我的脚本引擎使用起来非常简单,因为我不需要比现在更多的功能。基本上它仅仅用于编译生成的一个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);
}
}
{
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);
}
}
{
while(true)
{
if (isCodeCompiled)
{
g_mgnd.FillRectangle(Brushes.Black, mgndBounds);
script.Execute("main");
UpdatePicBox();
}
Thread.Sleep(20);
}
}
当然,这仅仅是展示如何使用脚本的一个简单示例。我仅仅是想创建一个可视化的示例来展示如何以一种非常简单的方式使用脚本。它展示在应用程序中如何定义函数并在脚本中使用它。理论上,对于使用脚本引擎实现你想要的功能没有限制。我的下一步将集成该引擎到我的呈现器中,添加这些功能使其在不用重新编译的情况下添加新的类型。