MoonSharp 文档一-CSDN博客
MoonSharp 文档二-CSDN博客
MoonSharp 文档四-CSDN博客
MoonSharp 文档五-CSDN博客
7.Proxy objects(代理对象)
如何封装你的实现,同时又为脚本提供一个有意义的对象模型
官方文档:MoonSharp
在现实世界的场景中,脚本往往会超出你的控制范围。这带来了几个问题,包括:
• 安全性:这部分内容与本页主题无关,但如果你的脚本来自非严格控制的环境,请阅读有关沙盒化的部分。
• 向后和向前兼容性:MoonSharp 尽力避免引入与过去或未来的兼容性问题,但你的 API 设计是你的责任!
实现上述两点的一个关键方法是封装你的实现细节,确保没有 API 不应该调用的字段被调用,并且你可以按照自己的意愿发展你的内部模型,几乎不用担心意外破坏脚本。
有两种封装方式,一种是以一些非常复杂的方式复制所有你的 API。另一种是通过“代理对象”(一种 “脚本用的 DTOs”)。
这个概念非常简单。对于每一个你想要封装并暴露给脚本的类型,你必须提供一个“代理类型”,这是一个类,它操作一个被封装(目标)类型的实例。
用一个例子来说明更直观:
// Declare a proxy class
class MyProxy
{MyType target;[MoonSharpHidden]public MyProxy(MyType p){this.target = p;}public int GetValue() { return target.GetValue(); }
}// Register the proxy, using a function which creates a proxy from the target type
UserData.RegisterProxyType<MyProxy, MyType>(r => new MyProxy(r));// Test with a script - only the proxy type is really exposed to scripts, yet everything it works
// just as if the target type was actually used..Script S = new Script();S.Globals["mytarget"] = new MyType(...);
S.Globals["func"] = (Action<MyType>)SomeFunction;S.DoString(@"x = mytarget.GetValue(); func(mytarget);
");
除了封装,还可以使用代理对象进行一些巧妙的操作。
其中一个方法非常简单但非常有用——正确地访问值类型;例如,你可以包装 Unity 的 Transform 类——这个类完全由值类型组成,但它是一个引用类型——用一个不同的接口来保持正确的引用!