随笔-341  评论-2670  文章-0  trackbacks-0
    今天做好了Vczh Free Script 2.0的一个新插件,这个插件可以直接插入class并接管成员调用、构造函数和析构函数等调用。

    一、在C++中插入一个类VczhClass和函数write、writeln、read和collect:
  1 class VczhClass : public FsClass
  2 {
  3 protected:
  4 public:
  5     VczhClass(FsPlugin* Plugin):FsClass(Plugin,L"interpreter_debug")
  6     {
  7     }
  8 
  9     FsePluginInvoke CallConstructor(int ClassID , FsObject* Parameters , int ParamCount , FsObject& ErrorMessage , FsObject& Result)
 10     {
 11         GetConsole()->Write(L"VczhClass is creating.\r\n");
 12         AddExternalMember(ClassID,L"MethodA",0);
 13         AddExternalMember(ClassID,L"MethodB",1);
 14         AddExternalMember(ClassID,L"MethodC",2);
 15         return fsSuccess;
 16     }
 17 
 18     FsePluginInvoke CallMember(int ClassID , int ExternalMemberID , FsObject* Parameters , int ParamCount , FsObject& ErrorMessage , FsObject& Result)
 19     {
 20         switch(GetMemberID(ExternalMemberID))
 21         {
 22         case 0:
 23             GetConsole()->Write(L"VczhClass::MethodA is invoking.\r\n");
 24             break;
 25         case 1:
 26             GetConsole()->Write(L"VczhClass::MethodB is invoking.\r\n");
 27             break;
 28         case 2:
 29             GetConsole()->Write(L"VczhClass::MethodC is invoking.\r\n");
 30             break;
 31         }
 32         return fsSuccess;
 33     }
 34 
 35     void CallDestructor(int ClassID)
 36     {
 37         GetConsole()->Write(L"VczhClass is destroying.\r\n");
 38     }
 39 };
 40 
 41 class VczhConsole : public FsPlugin
 42 {
 43 protected:
 44     FsObject            FWrite;
 45     FsObject            FWriteLine;
 46     FsObject            FRead;
 47     FsObject            FCollect;
 48     VczhClass*            FVczhClass;
 49 
 50     VUnicodeString Transform(const FsObject& Value)
 51     {
 52         return Value.GetReadableString().w_str();
 53     }
 54 public:
 55     VczhConsole(FsEngine* Engine , VUnicodeString CodePath):FsPlugin(Engine,L"interpreter")
 56     {
 57         FWrite        =Engine->CreateExternalResource();
 58         FWriteLine    =Engine->CreateExternalResource();
 59         FRead        =Engine->CreateExternalResource();
 60         FCollect    =Engine->CreateExternalResource();
 61 
 62         GetEnvironment().SetFixedVariable(L"write",FWrite);
 63         GetEnvironment().SetFixedVariable(L"writeln",FWriteLine);
 64         GetEnvironment().SetFixedVariable(L"read",FRead);
 65         GetEnvironment().SetFixedVariable(L"collect",FCollect);
 66         GetEnvironment().SetVariable(L"apppath",Engine->CreateString(CodePath.Buffer()));
 67         GetEnvironment().SetFixedVariable(L"vmpath",Engine->CreateString(GetConsole()->GetAppPath().Buffer()));
 68 
 69 #ifdef _DEBUG
 70         FVczhClass=new VczhClass(this);
 71         GetEnvironment().SetFixedVariable(L"VczhClass",FVczhClass->GetCtor());
 72 #else
 73         FVczhClass=0;
 74 #endif
 75     }
 76 
 77     ~VczhConsole()
 78     {
 79         if(FVczhClass)
 80         {
 81             delete FVczhClass;
 82         }
 83     }
 84 
 85     FsePluginInvoke Invoke(int ExternalID , FsObject* Parameters , int ParamCount , FsObject& ErrorMessage , FsObject& Result)
 86     {
 87         if(ExternalID==FWrite.GetExternalID())
 88         {
 89             for(VInt i=0;i<ParamCount;i++)
 90             {
 91                 GetConsole()->Write(Transform(Parameters[i]));
 92             }
 93             return fsSuccess;
 94         }
 95         else if(ExternalID==FWriteLine.GetExternalID())
 96         {
 97             for(VInt i=0;i<ParamCount;i++)
 98             {
 99                 GetConsole()->Write(Transform(Parameters[i]));
100             }
101             GetConsole()->Write(L"\r\n");
102             return fsSuccess;
103         }
104         else if(ExternalID==FRead.GetExternalID())
105         {
106             for(VInt i=0;i<ParamCount;i++)
107             {
108                 GetConsole()->Write(Transform(Parameters[i]));
109             }
110             VUnicodeString Read;
111             GetConsole()->Read(Read);
112             Result=GetOwnedEngine()->CreateString(Read.Buffer());
113             return fsSuccess;
114         }
115         else if(ExternalID==FCollect.GetExternalID())
116         {
117             int* Buffer=0;
118             int Count=GetOwnedEngine()->CollectGarbage(Buffer);
119             FsReleaseBuffer(Buffer);
120             return fsSuccess;
121         }
122         else
123         {
124             return fsGiveUp;
125         }
126     }
127 };

    二、书写测试用的脚本代码:
1 func()
2 {
3     a=VczhClass.new();
4     a.MethodA();
5     a.MethodB();
6     a.MethodC();
7 }();
8 collect();
    这里构造了一个VczhClass并调用了三个成员函数。结束之后,这种写法保证a再也不可被访问到,于是调用collect进行垃圾收集(垃圾收集是自动的,但是要触发条件很难,所以给了个函数进行强制收集)的时候就可以把a手机掉。

    三、运行结果:
1 VczhClass is creating.
2 VczhClass::MethodA is invoking.
3 VczhClass::MethodB is invoking.
4 VczhClass::MethodC is invoking.
5 VczhClass is destroying.

    四、如果a的成员被保存起来了怎么办呢?
 1 b=null;
 2 func()
 3 {
 4     a=VczhClass.new();
 5     a.MethodA();
 6     a.MethodB();
 7     a.MethodC();
 8     b=a.constructor;
 9 }();
10 collect();

    五、结果是因为b还能继续使用,所以a就不会销毁(垃圾收集器解决了这个问题):
1 VczhClass is creating.
2 VczhClass::MethodA is invoking.
3 VczhClass::MethodB is invoking.
4 VczhClass::MethodC is invoking.

    到了这里,一个直接往脚本中插入类的演示就结束了。接下来就是对这个插件进行测试,并且在相应的.NET接口上添加这样的支持。
posted on 2008-05-28 22:50 陈梓瀚(vczh) 阅读(1586) 评论(0)  编辑 收藏 引用 所属分类: Vczh Free Script

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理