d5/tengo

[question] How can I register native type into script?

ckcfcc opened this issue · 2 comments

I want to register my own object MyPos in go code, a struct like this.

golang code:

type MyPos struct {
	X, Y int
}

And provide a newMO() function to return this object. I hope that the members of this object can be accessed in the script, but I do not want to register this object in the script, for example:

script code:

	mp := import(mypos)

	pos1 := mp.newMO()

	pos1.X = 1000
	pos1.Y = 20
	...

Please tell me how to do this. Thx!

type MyPos struct {
	X, Y int
}

func newMyPos(args ...tengo.Object) (ret tengo.Object, err error) {
	myPos := &MyPos{}
	return ... // ??? how can I return myPos
}

var PosModule = &tengo.BuiltinModule{
	Attrs: map[string]tengo.Object{
		"newMO": &tengo.UserFunction{
			Name:  "newMO",
			Value: newMyPos,
		},
	},
}

The previous problem has been solved.

But a new problem has arisen. The values of members in the native object cannot be changed in the script. What method can be used to solve this problem?

native module code:

type MyPos struct {
	X, Y int
}

func (mp *MyPos) GetTengoObject() tengo.Object {
	return &tengo.Map{
		Value: map[string]tengo.Object{
			"x": &tengo.Int{Value: int64(mp.X)},
			"y": &tengo.Int{Value: int64(mp.Y)},
			"print": &tengo.UserFunction{
				Name: "print",
				Value: func(args ...tengo.Object) (ret tengo.Object, err error) {
					mp.Print()
					return tengo.UndefinedValue, nil
				},
			},
		},
	}
}

func (mp *MyPos) Print() {
	log.Printf("[native] X:%d Y:%d", mp.X, mp.Y)
}

func newMyPos(args ...tengo.Object) (ret tengo.Object, err error) {
	myPos := &MyPos{X: 1, Y: 2}
	return myPos.GetTengoObject(), nil
}

var PosModule = &tengo.BuiltinModule{
	Attrs: map[string]tengo.Object{
		"newMP": &tengo.UserFunction{
			Name:  "new",
			Value: newMyPos,
		},
	},
}

script code:

md := import("myModule")

p1 := md.newMP()
p1.x += 123
p1.y = 234
log("x:%d y:%d", p1.x, p1.y) // output script object field value
p1.y -= 11
p1.print() // output native object field value

output:
2024/02/23 11:48:49 [scp] x:124 y:234
2024/02/23 11:48:49 [native] X:1 Y:2 // why hasn't it changed?

p1.x += 123 only modified the attribute on tengo.Object, not the original MyPos instance, you can add a function like setx(x int) on MyPos.