在过去的几天中,我一直在思考将.NET的部分应用程序脚本化这种可能性。
虽然我查看了现有的解决方案,但是最终,在基于内置.NET编译器的基础上,我以一种非常简单的方式实现了这种功能。
Nanoscript 就是我工作的成果。
它允许我实现下面的功能:
• 编写能够从应用程序调用的脚本函数。
• 在脚本内部定义新类使其能在脚本内部能够实例化并使用。
• 定义能够在脚本内部和外部使用的全局变量。
• 为脚本上下文导出静态程序员函数并从脚本中调用它们。
我已经为该方案添加了两个简单的示例应用程序。第一个示例是基于命令行的小型应用程序。这些仅是做一些基本的测试。使你可以对整个方案有个更好的了解。第二个示例是一个基于窗口的应用程序,用来画一个曲线:
我的脚本引擎使用起来非常简单,因为我不需要比现在更多的功能。基本上它仅仅用于编译生成的一个CS文件并生一个包含该类的程序集,该程序集封装了所有的脚本函数。NanoScript 不会使用自己的应用程序域。生成的代码在当前的应用程序域中将会执行。NanoScript不能执行外壳CS文件。它仅仅是一个简单的类库。我的目的是将其实现为一个简单的脚本游戏成为可能。如果使用谷歌搜索,你将会找到带有更多更能的优秀解决方案。
使用代码
使用Nanoscript非常简单。仅仅需要添加一个NanoScript.dll程序集合的引用并在代码中加入命名空间NanoScript即可。该示例程序使用下面的方法来编译代码,该代码被存储在一个文本框里面:
以下是引用片段: private void compileAndRunToolStripMenuItem_Click(object sender, EventArgs e) { isCodeCompiled = false; // create a new scripting context script = new ScriptEngine(); // reference the required assemblies script.References(“System.Drawing.dll”); script.References(“System.Windows.Forms.dll”); // make namespaces visible script.Using(“System”); script.Using(“System.Drawing”); script.Using(“System.Windows”); script.Using(“System.Windows.Forms”); // export the functions DrawSprite and DrawSprites to the scripting context script.SetMemberFunction( this, “DrawSprite”); script.SetMemberFunction( this, “DrawSpriteS”); // set the code stored in textBox1 script.SetCode(this.textBox1.Text); try { // try to compile script.Compile(); } catch (NanoScript.ScriptEngine.ScriptingContextException ex) { // present the compiling errors in a MessageBox StringBuilder b = new StringBuilder(); List cc = ex.errors; b.AppendLine(“There were errors:”); foreach (ScriptEngine.ScriptingContextException.CompileError err in cc) { b.AppendLine(“Error ” + err.errNumber + ” at line ” + err.line + ” col ” + err.column + ” : “” + err.text+””” ); b.AppendLine(“code: ” + err.codeSnippet); b.AppendLine(); } MessageBox.Show(b.ToString(),”Compiling Error(s)”); return; } isCodeCompiled = true; } The functions DrawSprite and DrawSpriteS look like this: public void DrawSprite(String name, double posx, double posy) { if (name == “sprite1”) { g_mgnd.DrawImage(sprite1, new Point((int)posx, (int)posy)); } } public void DrawSpriteS(String name, double posx, double posy, double w, double h) { if (name == “sprite1”) { g_mgnd.DrawImage(sprite1, (float)posx, (float)posy, (float)w, (float)h); } } |
现在,我们可以在我们的应用程序中编写脚本来实现绘画。我添加了7个示例函数来呈现不同的利萨如曲线。选择示例1到7填充适当代码到代码文本框中。
点击“编译并运行”编译脚本,并在应用程序的主循环中运行它。该应用程序在脚本上下文中调用“main”函数并每秒执行50次。
以下是引用片段: private void MainFunc() { while(true) { if (isCodeCompiled) { g_mgnd.FillRectangle(Brushes.Black, mgndBounds); script.Execute(“main”); UpdatePicBox(); } Thread.Sleep(20); } } |
当然,这仅仅是展示如何使用脚本的一个简单示例。我仅仅是想创建一个可视化的示例来展示如何以一种非常简单的方式使用脚本。它展示在应用程序中如何定义函数并在脚本中使用它。理论上,对于使用脚本引擎实现你想要的功能没有限制。我的下一步将集成该引擎到我的呈现器中,添加这些功能使其在不用重新编译的情况下添加新的类型。
我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。
我原创,你原创,我们的内容世界才会更加精彩!
【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】
微信公众号
TechTarget
官方微博
TechTarget中国
作者
相关推荐
-
.NET架构师:函数式语言做领域驱动设计
Scott一位.NET架构师,同时也是掌握函数式编程的作者,他很欣赏函数式编程,对于Scott来说,面向对象编程的那些概念也很恐怖,比如多态、泛型、继承、协变等。
-
软件开发就像炒股 关键看你怎么选股票!
本文作者Paulo Ortins在这里分享了对于选择哪种编程语言作为软件开发工作的起点的话题,并阐述了自己的观点。
-
增进离岸Java开发效率的十个提示
近日,Cygnet Infotech公司发布了一篇博文,谈到了如何增进离岸Java开发的效率。众多的ISV与软件厂商总是在不断寻找能以最低的代价实现其业务目标的解决方案。
-
Visual Studio 2013增强调试功能
Visual Studio 2013包含了若干诊断特性,能够帮助开发人员有效地调试他们的应用程序。