Click here to Skip to main content
15,885,782 members
Articles / Programming Languages / C#

NanoScript - A Lightweight Scripting Engine for .NET

Rate me:
Please Sign up or sign in to vote.
4.83/5 (44 votes)
29 Sep 2009CPOL2 min read 74.8K   1.4K   148  
A very small and compact scripting solution for .NET
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.CodeDom.Compiler;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Reflection;

using NanoScript;

namespace ScriptTest2
{
    public partial class ScriptExample : Form
    {
        Bitmap mgnd = new Bitmap(400, 400, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
        
        RectangleF mgndBounds = new RectangleF();
        ScriptEngine script = new ScriptEngine();
        Thread mainThread = null;
        GraphicsUnit gu = new GraphicsUnit();
        
        Graphics g_mgnd = null;
        bool isCodeCompiled = false;
        bool needsInit = false;
        Hashtable sprites = new Hashtable();

        public ScriptExample()
        {            
            InitializeComponent();

            SampleCode1();

            Assembly a = Assembly.GetExecutingAssembly();
                     
            g_mgnd = Graphics.FromImage(mgnd);
            using (Brush b = new SolidBrush(Color.FromArgb(0, Color.Black)))
            {
                mgndBounds = mgnd.GetBounds(ref gu);
                g_mgnd.FillRectangle(Brushes.Black, mgndBounds);               
            }
           
            this.pictureBox1.Image = mgnd;
            this.pictureBox1.SizeMode = PictureBoxSizeMode.CenterImage;
            mainThread = new Thread(new ThreadStart(MainFunc));
            mainThread.Start();
        }

        protected override void OnClosing(CancelEventArgs e)
        {
            base.OnClosing(e);
            mainThread.Abort();
        }

        public void CreateSprite(String name, Color r)
        {
            if (sprites.ContainsKey(name) == false)
            {
                GraphicsUnit Gu = new GraphicsUnit();
                Bitmap S = new Bitmap(16,16, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
                using (Graphics g_sprite1 = Graphics.FromImage(S))
                {
                    using (Brush b = new SolidBrush(Color.FromArgb(0, Color.Black)))
                    {
                        using (Brush fill = new SolidBrush(r))
                        {
                            RectangleF Bnds = S.GetBounds(ref Gu);
                            g_sprite1.FillRectangle(b, Bnds);
                            g_sprite1.FillEllipse(fill, S.GetBounds(ref gu));
                            sprites[name] = S;
                        }
                    }
                }
            }
        }

        public void DrawSprite(String name, double posx, double posy)
        {
            if (sprites.ContainsKey(name)  )
            {
                g_mgnd.DrawImage((Bitmap)sprites[name], new Point((int)posx, (int)posy));                                      
            }
        }

        public void DrawSpriteS(String name, double posx, double posy, double w, double h)
        {
            if (sprites.ContainsKey(name) && w>=1 && h >=1)
            {               
                g_mgnd.DrawImage((Bitmap)sprites[name], (float)posx, (float)posy, (float)w, (float)h);           
            }
           
        }

        private void MainFunc()
        {             
            while(true)
            {
                if (isCodeCompiled)
                {                     
                    g_mgnd.FillRectangle(Brushes.Black, mgndBounds);
                    if (needsInit)
                    {
                        sprites.Clear();
                        script.Execute("init");
                        needsInit = false;
                    }
                    
                    script.Execute("main");

                    UpdatePicBox();
                }                 
               
                Thread.Sleep(20);
            }
        }

        private void UpdatePicBox()
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new MethodInvoker(UpdatePicBox));
            }
            else
            {
                lock (mgnd)
                {
                    this.pictureBox1.Image = mgnd;
                    
                }
            }
        }

        private void SampleCode1()
        {
             
            this.textBox1.Text =
            @" 
                
                double phi=0;
                double radius = 128;
                int amount = 64;

                public void init()
                {
                    for (int i=1;i<amount;i++)
                    {                        
                        CreateSprite(""sprite""+i, Color.FromArgb(i*4,i*2,0));
                    }
                }

                public void main()
                {
                    
                    for (int i=0;i<amount;i++)
                    {
                        double delta = 2.0*Math.PI /(double)amount;
                        double off = i*delta;
                        double x = 200+Math.Sin(phi+off)*radius;
                        double y = 200+Math.Sin(2*phi+off)*radius;
                        DrawSpriteS(""sprite""+i,x,y,i/3,i/3);
                   }

                    phi+=0.02;

                }
              
            ";
        }
        
        private void SampleCode2()
        {
             
            this.textBox1.Text =
            @"
            double phi = 0;
            
            public void init()
            {
                CreateSprite(""sprite1"", Color.Red);
            }

            public void main()
            {
                int amount = 264;

                for (int i = 0; i < amount; i++)
                {

                    double delta = 2 * Math.PI / (double)amount;
                    double off = i * delta;
                    double radius = Math.Sin(phi + 4 * off) * 128;
                    double x = 200 + Math.Sin(phi + off) * radius;
                    double y = 200 + Math.Sin(0.5 * phi + off) * radius;
                    DrawSpriteS(""sprite1"", x, y,4,4);
                }

                phi += 0.02;

            }";
        }

        private void SampleCode3()
        {             
            this.textBox1.Text =
            @"
                double phi = 0;    

                public void init()
                {
                    CreateSprite(""sprite1"", Color.Red);
                }
        
                public void main()
                {
                    int amount = 128;

                    for (int i = 0; i < amount; i++)
                    {
                        double delta = 2 * Math.PI / (double)amount;
                        double off = i * delta;
                        float w = (float)(8 + Math.Sin(phi + 2 * off) * 8);
                        double radius = Math.Sin(phi + 2 * off) * 128;
                        double x = 200 + Math.Sin(phi + off) * radius;
                        double y = 200 + Math.Sin(0.5 * phi + off) * radius;
                        DrawSpriteS(""sprite1"", x, y, w, w);
                    }

                    phi += 0.02;
                 }";
        }


        private void SampleCode4()
        {

            this.textBox1.Text =
            @"
                double phi = 0;
                double radius = 128;

                public void init()
                {
                    CreateSprite(""sprite1"", Color.Red);
                }

                public void main()
                {
                    int amount = 264;
                    for (int i = 0; i < amount; i++)
                    {
                        double delta = 2.0 * Math.PI / (double)amount;
                        double off = i * delta;
                        double x = 200 + Math.Sin(phi + off) * radius;
                        double y = 200 + Math.Sin(2 * phi + off + i * 0.01) * radius;
                        DrawSpriteS(""sprite1"", x, y, 4, 4);
                    }

                    phi += 0.02;
                }";
        }

        private void SampleCode5()
        {

            this.textBox1.Text =
            @"
                 double phi = 0;
                double radius = 128;

                public void init()
                {
                    CreateSprite(""sprite1"", Color.Red);
                }

                public void main()
                {
                    int amount = 264;
                    for (int i = 0; i < amount; i++)
                    {
                        double delta = 2.0 * Math.PI / (double)amount;
                        double off = i * delta;
                        float w = (float)(4 + Math.Sin(phi + 2 * off) * 2);
                        double x = 200 + Math.Sin(phi + off) * radius;
                        double y = 200 + Math.Sin(2 * phi + off + i * delta * 2) * radius;
                        DrawSpriteS(""sprite1"", x, y, w, w);
                    }

                    phi += 0.04;   
                }";
        }

        private void SampleCode6()
        {
            this.textBox1.Text =
            @"
                double phi = 0;
                double radius = 164;

                public void init()
                {
                    CreateSprite(""sprite1"", Color.Red);
                }

                public void main()
                {
                    int amount = 264;
                    for (int i = 0; i < amount; i++)
                    {
                        double delta = 2.0 * Math.PI / (double)amount;
                        double off = i * delta;
                        float w = (float)(8 + Math.Sin(phi + 2 * off) * 8);
                        double x = 200 + Math.Sin(phi + off) * radius;
                        double y = 200 + Math.Sin(2 * phi + off + i * delta * 65) * radius;
                        DrawSpriteS(""sprite1"", x, y, w, w);
                    }

                    phi += 0.04;
                }";
        }

        private void SampleCode7()
        {
           this.textBox1.Text =
           @"
                double phi = 0;
                double radius = 128;

                public void init()
                {
                    CreateSprite(""sprite1"", Color.Red);
                }

                public void main()
                {
                    int amount = 264;
                    for (int i = 0; i < amount; i++)
                    {
                        double delta = 2.0 * Math.PI / (double)amount;
                        double off = i * delta;
                        float w = (float)(4 + Math.Sin(phi + 2 * off + i*0.02) * 6);
                        double x = 200 + Math.Sin(phi + off) * radius;
                        double y = 200 + Math.Sin(2 * phi + off + i * delta * 2) * radius;
                        DrawSpriteS(""sprite1"", x, y, w, w);
                    }

                    phi += 0.04;   
                }";
        }
            

        private void example1ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SampleCode1();
        }

        private void example2ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SampleCode2();
        }

        private void example3ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SampleCode3();
        }

        private void example4ToolStripMenuItem_Click(object sender, EventArgs e)
        {

            SampleCode4();
        }

        private void example5ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SampleCode5();
        }

        private void example6ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SampleCode6();
        }
        private void example7ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SampleCode7();
        }

         
        private void compileAndRunToolStripMenuItem_Click(object sender, EventArgs e)
        {
            isCodeCompiled = false;
            needsInit = true;

            script = new ScriptEngine();
            script.References("System.Drawing.dll");
            script.References("System.Windows.Forms.dll");

            script.Using("System");
            script.Using("System.Drawing");
            script.Using("System.Windows");
            script.Using("System.Windows.Forms");
          
            script.SetMemberFunction(  this, "DrawSprite");
            script.SetMemberFunction(  this, "DrawSpriteS");
            script.SetMemberFunction(  this, "CreateSprite");                      
            script.SetCode(this.textBox1.Text);

            try
            {
                script.Compile();
            }
            catch (NanoScript.ScriptEngine.ScriptingContextException ex)
            {
                StringBuilder b = new StringBuilder();
                List<ScriptEngine.ScriptingContextException.CompileError> 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;
             
        }

      
      

        
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Austria Austria
I have started programming at the age of 13 on the commodore 64.

Ever since then I have been programming on many systems in many languages.

During the last 12 years I have been working as professional programmer in different companies and different areas.

Now I am working as freelancer programmer / consultant

Comments and Discussions