云柯

文章 评论 浏览 27

云柯 2025-02-01 09:14:58

我设法解决了这个问题。显然,我必须定义一个新功能并更新该功能内部的第一周属性。 :)

I managed to solve the issue. Apparently I had to define a new function and update the firstWeekDay property inside that function. :)

无法更新日历FirstWeekday Swift 3.0

云柯 2025-02-01 03:06:57

如果我正确理解你。
风格垫子场的父元素(S)与:

display: flex;
flex-direction: column;

应该这样做

If I understand you correctly.
Style the parent element of the mat-form-field(s) with:

display: flex;
flex-direction: column;

That should hopefully do it

如何将输入添加到列中?我有一个涉及我要做的事情的参考

云柯 2025-02-01 02:15:29

这有点迟来,但是总的来说,如果您似乎存在兼容性问题,我建议将Github Copilot和Vscode更新为最新版本。

在这种特殊情况下,我怀疑您使用的是带有旧版本的VSCODE的较新版本。我们确实尝试设置版本限制以避免这种限制,但它们可能无法正常工作。

This is a bit belated, but in general I'd suggest updating both GitHub Copilot and VSCode to the latest versions if you appear to have compatibility problems.

In this particular case I suspect that you were using a newer version of Copilot with an old version of VSCode. We did try to set version restrictions to avoid this but they may not have worked properly.

Github Copilot似乎有问题

云柯 2025-02-01 00:31:37

定义复制构造函数:

internal class RegularLogin
{
    public RegularLogin()
    {
    }
    public RegularLogin(RegularLogin login)
    {
        this.username = login.username;
        this.password = login.password;
    }
    public string username { get; set; }
    public string password { get; set; }
}

使您的富集蛋白继承常规斑点,并使用复制构造函数。在这里,基础(登录)运行用户并传递分配。

internal class FullLogin : RegularLogin
{
    public FullLogin()
    {
    }
    public FullLogin(RegularLogin login)
        : base(login)
    {
    }
    public FullLogin(FullLogin login)
        : base(login)
    {
        this.device = login.device;
        this.privacy = login.privacy;
    }
    public string device { get; set; }
    public string privacy { get; set; }
}

然后,您可以做到这一点:

FullLogin fullLogin = new FullLogin()
{
    username = "abc",
    password = "123",
    device = "MyDevice",
    privacy = "public"
};
RegularLogin regularLogin = new RegularLogin(fullLogin);
FullLogin fullLogin2 = new FullLogin(regularLogin);

Update

我在Fulllogin中添加了另一个副本的配置器,使您可以使用常规斑点属性创建一个富集蛋白。

更新2

另一种方法是使用复制方法。这样,您就可以随时在登录之间复制,不仅可以在制作中进行复制。另外,您只需要一个复制方法,带有基类(常规谷蛋白),在派生类中,您可以检查常规log蛋白是否也是富洛申蛋白,并复制其他属性

internal class RegularLogin
{
    public RegularLogin()
    {
    }
    public RegularLogin(RegularLogin login)
    {
        login.CopyTo(this);
    }
    public string username { get; set; }
    public string password { get; set; }
    public virtual void CopyTo(RegularLogin login)
    {
        login.username = this.username;
        login.password = this.password;
    }
}

internal class FullLogin : RegularLogin
{
    public FullLogin()
    {
    }
    public FullLogin(RegularLogin login)
        : base(login)
    {                
    }
    public string device { get; set; }
    public string privacy { get; set; }
    public override void CopyTo(RegularLogin login)
    {
        base.CopyTo(login);

        FullLogin fullLogin = login as FullLogin;
        if (fullLogin != null)
        {
            this.device = fullLogin.device;
            this.privacy = fullLogin.privacy;
        }
    }
}

测试:

FullLogin fullLogin = new FullLogin()
{
    username = "abc",
    password = "123",
    device = "MyDevice",
    privacy = "public"
};
RegularLogin regularLogin = new RegularLogin(fullLogin);
FullLogin fullLogin2 = new FullLogin(regularLogin);
FullLogin fullLogin3 = new FullLogin(fullLogin);

Define a copy constructor:

internal class RegularLogin
{
    public RegularLogin()
    {
    }
    public RegularLogin(RegularLogin login)
    {
        this.username = login.username;
        this.password = login.password;
    }
    public string username { get; set; }
    public string password { get; set; }
}

Make your FullLogin inherith RegularLogin and also with a copy constructor. Here, base(login) run the user and pass assignements.

internal class FullLogin : RegularLogin
{
    public FullLogin()
    {
    }
    public FullLogin(RegularLogin login)
        : base(login)
    {
    }
    public FullLogin(FullLogin login)
        : base(login)
    {
        this.device = login.device;
        this.privacy = login.privacy;
    }
    public string device { get; set; }
    public string privacy { get; set; }
}

Then you can do this:

FullLogin fullLogin = new FullLogin()
{
    username = "abc",
    password = "123",
    device = "MyDevice",
    privacy = "public"
};
RegularLogin regularLogin = new RegularLogin(fullLogin);
FullLogin fullLogin2 = new FullLogin(regularLogin);

UPDATE

I added another copy contructor to FullLogin that allow you create a FullLogin with the RegularLogin properties.

UPDATE 2

Another way to do is using a CopyTo method. In this way, you can copy between your logins in any moment, not only in the contruction. Also, you need only one CopyTo method, with the base class (RegularLogin) and, in derived classes, you can check if that RegularLogin is also a FullLogin and copy the other properties

internal class RegularLogin
{
    public RegularLogin()
    {
    }
    public RegularLogin(RegularLogin login)
    {
        login.CopyTo(this);
    }
    public string username { get; set; }
    public string password { get; set; }
    public virtual void CopyTo(RegularLogin login)
    {
        login.username = this.username;
        login.password = this.password;
    }
}

internal class FullLogin : RegularLogin
{
    public FullLogin()
    {
    }
    public FullLogin(RegularLogin login)
        : base(login)
    {                
    }
    public string device { get; set; }
    public string privacy { get; set; }
    public override void CopyTo(RegularLogin login)
    {
        base.CopyTo(login);

        FullLogin fullLogin = login as FullLogin;
        if (fullLogin != null)
        {
            this.device = fullLogin.device;
            this.privacy = fullLogin.privacy;
        }
    }
}

Test:

FullLogin fullLogin = new FullLogin()
{
    username = "abc",
    password = "123",
    device = "MyDevice",
    privacy = "public"
};
RegularLogin regularLogin = new RegularLogin(fullLogin);
FullLogin fullLogin2 = new FullLogin(regularLogin);
FullLogin fullLogin3 = new FullLogin(fullLogin);

复制C#中对象之间的共同属性

云柯 2025-01-31 22:22:48

如果 order order_history 与外键连接,则可以执行以下操作:

<changeSet id="foo" author="bar">
    <preConditions onFail="MARK_RAN">
        <and>
            <columnExists tableName="order" columnName="status"/>
            <columnExists tableName="order_history" columnName="status"/>
        </and>
    </preConditions>
    <comment>Update order_history.status with values from order.status, where order.id = order_history.order_id</comment>
    <update tableName="order_history">
        <column name="status" valueComputed="SELECT o.status FROM order o WHERE o.id = order_id"/>
    </update>
</changeSet>

如果这些表未连接,则可以使用 defaultValueComputed 添加新列时:

    <addColumn tableName="order_history">
        <column name="status" type="varchar(255)" defaultValueComputed="some SQL query here"/>
    </addColumn>

If order and order_history are connected with the foreign key, then you can just do the following:

<changeSet id="foo" author="bar">
    <preConditions onFail="MARK_RAN">
        <and>
            <columnExists tableName="order" columnName="status"/>
            <columnExists tableName="order_history" columnName="status"/>
        </and>
    </preConditions>
    <comment>Update order_history.status with values from order.status, where order.id = order_history.order_id</comment>
    <update tableName="order_history">
        <column name="status" valueComputed="SELECT o.status FROM order o WHERE o.id = order_id"/>
    </update>
</changeSet>

If these tables are not connected, then you may use defaultValueComputed when you're adding a new column:

    <addColumn tableName="order_history">
        <column name="status" type="varchar(255)" defaultValueComputed="some SQL query here"/>
    </addColumn>

Liquibase Changeet:如何根据另一个表构建子句

云柯 2025-01-31 16:24:24

每分钟 每分钟每个用户读取和写入请求 有限制。

它在每个项目的每天读写<代码>上是无限的。

文档上检查它

您可以在
“ https://developers.google.com/sheets/api/limits”的 每天每个项目 每分钟
每个项目每分钟每分钟 300
每分钟每个用户每个项目 60
的写作请求 每天每天的每天每分钟每分钟
每分钟每分钟每分钟 每天60个
个项目每分钟 每分钟每分钟每分钟300

也可以检查您的个人配额,您可以将云控制台用作请求增量增加

There is a limit on read and write requests per minute and per minute per user per project.

It is unlimited on read and write per day per project.

You can check it on the documentation on usage limits for the Sheets API:

Quotas
Read requests Per day per project Unlimited
Per minute per project 300
Per minute per user per project 60
Write requests Per day per project Unlimited
Per minute per project 300
Per minute per user per project 60

Also, to check your personal quotas you can use the Cloud Console as mentioned on Request a quota increase:

Google表批处理更新有效载荷限制

云柯 2025-01-31 14:49:27

有同样的问题。在这里找到答案:需要添加

compileclasspath += sourcesets [“ main”]。runtimeclasspath

Had the same problem. Found an answer here: Adding an additional test suite to Gradle seems you need to add

compileClasspath += sourceSets["main"].runtimeClasspath

使用Gradle JVM测试套件,IntegrationTest Suite无法访问Kotlin内部API

云柯 2025-01-31 11:49:26

您可以使用我们的ujson叉子来处理numpy int64。 caiyunapp/ultrajson:Ultra Fast JSON解码器和编码器,用python bintings和Numpy Bindings和Numpy Bindings编写C

pip install nujson

>>> import numpy as np
>>> import nujson as ujson
>>> a = {"a": np.int64(100)}
>>> ujson.dumps(a)
'{"a":100}'
>>> a["b"] = np.float64(10.9)
>>> ujson.dumps(a)
'{"a":100,"b":10.9}'
>>> a["c"] = np.str_("12")
>>> ujson.dumps(a)
'{"a":100,"b":10.9,"c":"12"}'
>>> a["d"] = np.array(list(range(10)))
>>> ujson.dumps(a)
'{"a":100,"b":10.9,"c":"12","d":[0,1,2,3,4,5,6,7,8,9]}'
>>> a["e"] = np.repeat(3.9, 4)
>>> ujson.dumps(a)
'{"a":100,"b":10.9,"c":"12","d":[0,1,2,3,4,5,6,7,8,9],"e":[3.9,3.9,3.9,3.9]}'

You can use our fork of ujson to deal with NumPy int64. caiyunapp/ultrajson: Ultra fast JSON decoder and encoder written in C with Python bindings and NumPy bindings

pip install nujson

Then

>>> import numpy as np
>>> import nujson as ujson
>>> a = {"a": np.int64(100)}
>>> ujson.dumps(a)
'{"a":100}'
>>> a["b"] = np.float64(10.9)
>>> ujson.dumps(a)
'{"a":100,"b":10.9}'
>>> a["c"] = np.str_("12")
>>> ujson.dumps(a)
'{"a":100,"b":10.9,"c":"12"}'
>>> a["d"] = np.array(list(range(10)))
>>> ujson.dumps(a)
'{"a":100,"b":10.9,"c":"12","d":[0,1,2,3,4,5,6,7,8,9]}'
>>> a["e"] = np.repeat(3.9, 4)
>>> ujson.dumps(a)
'{"a":100,"b":10.9,"c":"12","d":[0,1,2,3,4,5,6,7,8,9],"e":[3.9,3.9,3.9,3.9]}'

将numpy类型转换为Python

云柯 2025-01-31 10:01:24

我很确定 yfinance 仅提取当前股票的库存数据,但是您可以给它一个时间范围,例如:

# Define the ticker list
import pandas as pd
tickers_list = ['AAPL', 'WMT', 'IBM', 'MU', 'BA', 'AXP']

# Fetch the data
import yfinance as yf
data = yf.download(tickers_list,'2015-1-1')['Adj Close']

# Print first 5 rows of the data
print(data.head())

im pretty sure yfinance only pulls stock data of current stocks, but you can give it a time frame, for example:

# Define the ticker list
import pandas as pd
tickers_list = ['AAPL', 'WMT', 'IBM', 'MU', 'BA', 'AXP']

# Fetch the data
import yfinance as yf
data = yf.download(tickers_list,'2015-1-1')['Adj Close']

# Print first 5 rows of the data
print(data.head())

获取带有销售的股票数据的历史库存数据

云柯 2025-01-31 02:53:24

交易如何处理并发

  1. 使用客户端SDK时,事务将跟踪其中使用的所有文档。如果这些文档中的任何一个是由外部操作编辑的,则交易将从划痕中重试,以确保使用最新数据。

  2. 另一方面,服务器/管理员SDK将继续并在使用的文档上放置一个悲观的锁。试图更改交易中使用的文档的外部操作将失败,或者在抬起数据库锁之前才能完成。

除了交易中的并发控制外,如果您的问题是关于 在服务器上, Promise.all() get()在客户端上操作的数组完成相似的结果,然后在代码中,两个都将返回单个Promise 可以解决 documentnapshot 的数组,每个文档都被获取。

在这两种情况下,您的结果文档常数只需在承诺解决后即可包含文档数组。我在两个SDK中对此进行了测试。

// Iterating over documents regardless of which SDK is used in the transaction
myDocs.forEach( myDoc => {
    console.log(myDoc.data());
});

//Output in both SDKs
{ lastName: 'Doe', firstName: 'Jane' }
{ lastName: 'Smith', firstName: 'John' }
{ firstName: 'Foo', lastName: 'Bar' }

There is an important difference in how transactions handle concurrency between the client and admin SDKs:

  1. When using the client SDK, a transaction will keep track of all the documents that are used within it. If any of these documents is edited by an external operation, the transaction will retry from scratch ensuring the latest data is used.

  2. On the other hand, the server/admin SDK will go ahead and place a pessimistic lock on the documents that are used. External operations that try to change the documents used within the transaction will fail, or will not complete until the database lock is lifted.

Besides concurrency control in transactions, if your question is about whether getAll() on the server and a Promise.all() array of get() operations on the client accomplish similar results, then in the code both will return a single promise that resolves to an array of DocumentSnapshot with each document being fetched.

In both cases, your resulting docs constant will simply contain the array of documents after the Promise resolves. I tested this in both SDKs.

// Iterating over documents regardless of which SDK is used in the transaction
myDocs.forEach( myDoc => {
    console.log(myDoc.data());
});

//Output in both SDKs
{ lastName: 'Doe', firstName: 'Jane' }
{ lastName: 'Smith', firstName: 'John' }
{ firstName: 'Foo', lastName: 'Bar' }

Transaction.getall vs Promise.All在前端

云柯 2025-01-30 20:37:17

给定的输入文件:

"nman": "afklafjlka"
"prvr": "521.0.25",
"prvrfi": "1.18.3",

| 在REGEX输出中的布尔<代码>或的作用

import re

words = ['"nman"', '"prvr"'] # USE THE '""' OR YOU MAY DELETE MORE THAN EXPECTED
words = '|'.join(words) # == "nman"|"prvr"
with open('test.txt', 'r+') as f:
  # Marker used by truncate.
    f.seek(0)
  # Adds lines to the list if a regex match is NOT found. 
  # Matching the OR statement we created earlier.
    lines = [x for x in f.readlines() if not re.match(words, x)]
  # Writes all the lines we found to the file.
    f.writelines(lines)
  # Cuts off everything we didn't add.
    f.truncate()

"prvrfi": "1.18.3",

Given Input File:

"nman": "afklafjlka"
"prvr": "521.0.25",
"prvrfi": "1.18.3",

| acts like a boolean OR in regex

import re

words = ['"nman"', '"prvr"'] # USE THE '""' OR YOU MAY DELETE MORE THAN EXPECTED
words = '|'.join(words) # == "nman"|"prvr"
with open('test.txt', 'r+') as f:
  # Marker used by truncate.
    f.seek(0)
  # Adds lines to the list if a regex match is NOT found. 
  # Matching the OR statement we created earlier.
    lines = [x for x in f.readlines() if not re.match(words, x)]
  # Writes all the lines we found to the file.
    f.writelines(lines)
  # Cuts off everything we didn't add.
    f.truncate()

Output:

"prvrfi": "1.18.3",

用Python删除TXT文件中的一行

云柯 2025-01-30 18:45:39

使用匹配第一个DFRM数据的第二次DFRM name 创建索引,以应用于第二个数据框架的ID列。显然,这应该在您具有足够备份的R对象上完成。

txt1 <-"| Source   | Target         |
+ | DORTMUND | ANTWERP        |
+ | MUMBAI   | SPIJKENISSE    |
+ | XIOALAN  | BEILUN         |
+ |ETTRINGEN |BREMERHAVEN     |
+ |HILTER    |BREMERHAVEN     |"

 txt2 <- "| ID       | Name           |
+ | 2678     | DORTMUND       |
+ | 6049     | MUMBAI         |
+ | 9873     | XIOALAN        |
+ | 3014     | ETTRINGEN      |
+ | 4055     | HILTER         |
+ | 338      | ANTWERP        |
+ | 8323     | SPIJKENISSE    |
+ | 824      | BEILUN         |
+ | 1272     | BREMERHAVEN    |"
  inp1 <-read.delim(text=txt1, sep="|")[,2:3]
  inp2 <-read.delim(text=txt2, sep="|")[,2:3]

> inp1[] <- lapply(inp1,trimws) 
> inp2[] <- lapply(inp2,trimws)

> inp1[] <- lapply(inp1, function(col){inp2$ID[match(col,inp2$Name)]})
> inp1
  Source Target
1   2678    338
2   6049   8323
3   9873    824
4   3014   1272
5   4055   1272

Use match of first dfrm data agains second dfrm Name to create an index to apply to the ID column of the second dataframe. Obviously this should be done on R object for which you have adequate backups.

txt1 <-"| Source   | Target         |
+ | DORTMUND | ANTWERP        |
+ | MUMBAI   | SPIJKENISSE    |
+ | XIOALAN  | BEILUN         |
+ |ETTRINGEN |BREMERHAVEN     |
+ |HILTER    |BREMERHAVEN     |"

 txt2 <- "| ID       | Name           |
+ | 2678     | DORTMUND       |
+ | 6049     | MUMBAI         |
+ | 9873     | XIOALAN        |
+ | 3014     | ETTRINGEN      |
+ | 4055     | HILTER         |
+ | 338      | ANTWERP        |
+ | 8323     | SPIJKENISSE    |
+ | 824      | BEILUN         |
+ | 1272     | BREMERHAVEN    |"
  inp1 <-read.delim(text=txt1, sep="|")[,2:3]
  inp2 <-read.delim(text=txt2, sep="|")[,2:3]

> inp1[] <- lapply(inp1,trimws) 
> inp2[] <- lapply(inp2,trimws)

> inp1[] <- lapply(inp1, function(col){inp2$ID[match(col,inp2$Name)]})
> inp1
  Source Target
1   2678    338
2   6049   8323
3   9873    824
4   3014   1272
5   4055   1272

用R中的匹配ID替换单元格

云柯 2025-01-29 16:11:50

MOBX是一个通过应用功能反应性编程的国家管理库,它与OOP中的观察者模式非常相似。

与具有复杂状态的组件的常规REACT状态管理相比,它更便宜。

  • 使用MOBX,您无需多次使用Usestate。您可以将状态存储在看起来像常规JS对象的对象中(但实际上是代理对象,由getters和setter组成)。您可以单个时间更改MOBX状态对象,而不是多次调用SetState。
  • MOBX状态对象不是不可变的,这对于嵌套状态更方便,因为您不需要创建一个浅副本以确保不可超过的性能,
  • 您可以将某些逻辑与组件分解并因此简化(计算,相似的计算)对Usememo)。
  • MOBX比Redux更简单,并且更有生产力。

这是一个常规的反应示例:

const Widgets = (props) => {
  const [widgets, setWidgets] = useState([])
  const [status, setStatus] = useState('loading') // loading, error, loaded

  const onLoaded = (widgets) => {
    setWidgets(widgets)
    setStatus('loaded')
  }

  
  const onClose = (widget) => {
    const index = widgets.findIndex(currWidget => widget === currWidget)
    const nextWidgets = [...widgets]
    nextWidgets[index] = { ...nextWidgets[index] }
    nextWidgets[index].status = 'animatingOut'
    setWidgets(nextWidgets)
  }

  
  const hasActiveWidgets = useMemo(() => widgets.some(widget => widget.isActive), [widgets])
  if(hasActiveToasts){
    // something
  }

  ...
}

这是MOBX的同一示例:

class State {
  constructor(){
    makeAutoObservable(this) // use second parameter, to override, which properties to track and how
  }
  widgets: []
  status: 'loading'
  hasActiveWidgets: () => this.widgets.some(widget => widget.isActive)
}

const Widgets = observer((props) => {
  const state = useMemo(() => new State(), [])
  const onLoaded = action((widgets) => {
    state.widgets = widgets
    state.status = 'loaded'
  })
  const onClose = action((widget) => widget.status = 'animatingOut')
  
  if(state.hasActiveWidgets()){ // this causes rerender, whenever this function result changes (if state was changed inside action or runInAction)
    // something
  }

  ...
})

另外,您可以将MOBX状态放入React上下文中并与多个组件共享。这样,它可以类似于Redux Store。

Mobx is a library for state management by applying functional reactive programming, it is very similar to observer pattern in OOP.

It is more convenienient, than regular react state management for components with a complex state.

  • With mobx you dont need to use useState many times. you can store state in an object, that looks just like a regular js object (but is actually a proxy object, that consists of getters and setters). Instead of calling setState several times, you can change mobx state object single time.
  • Mobx state object is not immutable, this is more convenient for nested state, as you don't need to create a shallow copy all the way to ensure immutability
  • You can decouple some logic from the component and thus simplify it (computeds, that are similar to useMemo).
  • Mobx is much more simpler, than redux, and more productive.

Here is a regular react example:

const Widgets = (props) => {
  const [widgets, setWidgets] = useState([])
  const [status, setStatus] = useState('loading') // loading, error, loaded

  const onLoaded = (widgets) => {
    setWidgets(widgets)
    setStatus('loaded')
  }

  
  const onClose = (widget) => {
    const index = widgets.findIndex(currWidget => widget === currWidget)
    const nextWidgets = [...widgets]
    nextWidgets[index] = { ...nextWidgets[index] }
    nextWidgets[index].status = 'animatingOut'
    setWidgets(nextWidgets)
  }

  
  const hasActiveWidgets = useMemo(() => widgets.some(widget => widget.isActive), [widgets])
  if(hasActiveToasts){
    // something
  }

  ...
}

Here is the same example with mobx:

class State {
  constructor(){
    makeAutoObservable(this) // use second parameter, to override, which properties to track and how
  }
  widgets: []
  status: 'loading'
  hasActiveWidgets: () => this.widgets.some(widget => widget.isActive)
}

const Widgets = observer((props) => {
  const state = useMemo(() => new State(), [])
  const onLoaded = action((widgets) => {
    state.widgets = widgets
    state.status = 'loaded'
  })
  const onClose = action((widget) => widget.status = 'animatingOut')
  
  if(state.hasActiveWidgets()){ // this causes rerender, whenever this function result changes (if state was changed inside action or runInAction)
    // something
  }

  ...
})

Also, you can put mobx state into react context and share it with multiple components. This way it could work similar to redux store.

为什么MOBX有用?

云柯 2025-01-29 13:44:41

如果有人有兴趣,我将在此处发布我当前的解决方案。该实现有点混乱,但使用自定义脚本或编译器变换肯定可以自动化。

目标:为以下类创建线性代理,以便 main 函数的行为如预期:

class Foo {
    position: Vec2
    health: u8
}
export function main(): Info {
    
    const ptr = heap.alloc(FooProxy.size)
    const foo = changetype<FooProxy>(ptr)

    foo.health = 3
    foo.position.x = 9
    foo.position.y = 10
}

解决方案:计算每个字段的偏移和对齐。


class TypeMetadataBase{
    get align():u32{return 0}
    get offset():u32{return 0}
}
class TypeMetadata<T> extends TypeMetadataBase{
    get align():u32{return alignof<T>()}
    get offset():u32{return offsetof<T>()}

    constructor(){
        super()
        if(this.offset == 0)
        throw new Error('offset shouldnt be zero, for primitive types use PrimitiveMetadata')
    }
};
class PrimitiveMetadata<T> extends TypeMetadataBase{
    get align():u32{return sizeof<T>()}
    get offset():u32{return sizeof<T>()}
};

class LinearSchema{

    metadatas:StaticArray<TypeMetadataBase>
    size:u32
    offsets:StaticArray<u32>
    constructor(metadatas:StaticArray<TypeMetadataBase>){
        let align:u32 = 0
        const offsets = new StaticArray<u32>(metadatas.length)
        for (let i = 0; i < metadatas.length; i++){
            if(metadatas[i].align !== 0)
                while(align % metadatas[i].align !== 0)
                    align++
            offsets[i] = align
            align += metadatas[i].offset
        }
        this.offsets = offsets
        this.metadatas = metadatas
        this.size = align
    }
}


class Vec2 {
    x: u8
    y: u8
}

class FooSchema extends LinearSchema{
    constructor(){
        super([
            new PrimitiveMetadata<u8>(),
            new TypeMetadata<Vec2>(),
        ])
    }

}
const schema = new FooSchema()

class FooProxy{
    static get size():u32{return schema.size}
    set health(value:u8){store<u8>(changetype<usize>(this) + schema.offsets[0],value)}
    get health():u8{return load<u8>(changetype<usize>(this) + schema.offsets[0])}
    get position():Vec2{return changetype<Vec2>(changetype<usize>(this) + schema.offsets[1])}
}




In case anybody is interested I'll post my current solution here. The implementation is a little messy but is certainly automatable using custom scripts or compiler transforms.

Goal: Create a linear proxy for the following class so that the main function behaves as expected:

class Foo {
    position: Vec2
    health: u8
}
export function main(): Info {
    
    const ptr = heap.alloc(FooProxy.size)
    const foo = changetype<FooProxy>(ptr)

    foo.health = 3
    foo.position.x = 9
    foo.position.y = 10
}

Solution: calculate offsets and alignments for each field.


class TypeMetadataBase{
    get align():u32{return 0}
    get offset():u32{return 0}
}
class TypeMetadata<T> extends TypeMetadataBase{
    get align():u32{return alignof<T>()}
    get offset():u32{return offsetof<T>()}

    constructor(){
        super()
        if(this.offset == 0)
        throw new Error('offset shouldnt be zero, for primitive types use PrimitiveMetadata')
    }
};
class PrimitiveMetadata<T> extends TypeMetadataBase{
    get align():u32{return sizeof<T>()}
    get offset():u32{return sizeof<T>()}
};

class LinearSchema{

    metadatas:StaticArray<TypeMetadataBase>
    size:u32
    offsets:StaticArray<u32>
    constructor(metadatas:StaticArray<TypeMetadataBase>){
        let align:u32 = 0
        const offsets = new StaticArray<u32>(metadatas.length)
        for (let i = 0; i < metadatas.length; i++){
            if(metadatas[i].align !== 0)
                while(align % metadatas[i].align !== 0)
                    align++
            offsets[i] = align
            align += metadatas[i].offset
        }
        this.offsets = offsets
        this.metadatas = metadatas
        this.size = align
    }
}


class Vec2 {
    x: u8
    y: u8
}

class FooSchema extends LinearSchema{
    constructor(){
        super([
            new PrimitiveMetadata<u8>(),
            new TypeMetadata<Vec2>(),
        ])
    }

}
const schema = new FooSchema()

class FooProxy{
    static get size():u32{return schema.size}
    set health(value:u8){store<u8>(changetype<usize>(this) + schema.offsets[0],value)}
    get health():u8{return load<u8>(changetype<usize>(this) + schema.offsets[0])}
    get position():Vec2{return changetype<Vec2>(changetype<usize>(this) + schema.offsets[1])}
}




汇编 - 线性嵌套类布局

云柯 2025-01-28 19:16:18

您错了,使用“ color2d”很容易。这是非常奇怪的软件包,未发布到 npm 作为其他所有Javascript库。

由于问题缺乏信息,我不知道您如何运行代码。我想您正在这样做,而无需通过 webpack esbuild 或在每个JavaScript应用程序中使用的任何其他前端捆绑包。如果是这样,我建议您通过 create-react-app-app - 是的学习的好起点。

“ color2d”是非常古老的库,无法通过 import 添加,因此不建议完全使用它。但是,如果您非常需要使用它,最好将库代码放入 colormap.js 文件的开始中(是的,这很奇怪,但这是包含它而不修改的最佳方法库源代码)。

错误 src \ colormap.js行中的错误48:29:'color2d'未定义no-undef 实际上不是错误,更像是从 eslint

You are wrong that using of "color2d" is easy. It's quite weird package that is not published to npm as every other javascript library.

Due to lack of information in the question I don't know how you running your code. I suppose you are doing that without bundling via webpack, esbuild or any other frontend bundlers that is used in every javascript application. If that is true, I recommend you to start building your app via create-react-app – it's good starting point for learning.

"color2d" is very old library, that cannot be added via import, so it is not recommended to use it as is at all. But if you very need to use it, it's better to put library code into your the start of your ColorMap.js file (yes, it is weird, but that is the best way to include it without modifying library source code).

Error ERROR in src\ColorMap.js Line 48:29: 'Color2D' is not defined no-undef is not actually an error, that is more like a warning from eslint.

在React中使用2D COLORMAPS JAVASCRIPT插件

更多

推荐作者

櫻之舞

文章 0 评论 0

弥枳

文章 0 评论 0

m2429

文章 0 评论 0

野却迷人

文章 0 评论 0

我怀念的。

文章 0 评论 0

更多

友情链接

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文