Saturday, April 5, 2014

Jint tutorial 006 - Using Jint and Jint.Ex in a Win Form Application

Reminder : Jint is a Javascript v 5 interpreter for the .NET Framework/Mono/Xamarin allowing to execute scripts in C# applications on Windows, MacOS, iOS, Android and Linux (Anywhere there is a C# 4.x compiler).

Jint.Ex is event-driven interaction run time for Jint to build non blocking UI and creating asynchronous API with a focus on Windows and iOS.

The sample demonstrates how to execute JavaScript scripts using Jint and Jint.Ex in a Win Form application.
This full source code is part of the Jint.Ex project on GitHub.
  • All script execution do not use or block the UI thread
  • All script interact with the UI specifically with the Listbox control
  • The Asynchronous Execution script calls the Jint.Ex method setTimeout() which will trigger a one time asynchronous event (Callback)
  • The Timers scripts calls the Jint.Ex method setInterval() which will trigger asynchronous event at specific interval (Callback)
  • All script or callback execution is controled by the Jint.Ex event loop.


In a next blog I will show the same program on iOS.

JavaScript Scripts 

SynchronousExecution.js

    
for (var i = 0; i < 10; i++) {

    setUserMessage("string "+i);
}

AsynchronousExecution.js

    
function addUserMessage() {

    setUserMessage("string async");
}
setTimeout(addUserMessage, 10);

Timer.js

    
function addUserMessage() {

    setUserMessage("string async " + (new Date()));
}

setInterval(addUserMessage, 1000);

MultipleTimers.js

    
var secondCounter       = 0;
var halfSecondCounter   = 0;

function MessageEverySecond() {

    secondCounter++;
    setUserMessage("Every second " + secondCounter);
}
setInterval(MessageEverySecond, 1000);

function MessageHalfSecond() {

    halfSecondCounter++;
    setUserMessage("Every half second " + halfSecondCounter);
}
setInterval(MessageHalfSecond, 500);

C# 

   

public partial class Form1 : Form
{
    private AsyncronousEngine _asyncronousEngine;
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        _asyncronousEngine = new AsyncronousEngine();
        _asyncronousEngine.EmbedScriptAssemblies.Add(Assembly.GetExecutingAssembly());
        // Expose to the JavaScript the function setUserMessage which add a string 
        // in the Listbox
        _asyncronousEngine.Engine.SetValue("setUserMessage", new Action<string>(__setUserMessage__));
    }

    private void __setUserMessage__(string s)
    {
        try
        {
            // When the method is called by the JavaScript engine it will be called from
            // different thread
            if (this.InvokeRequired)
            {
                this.Invoke(new Action<string>(__setUserMessage__), s);
            }
            else
            {
                this.lbOut.Items.Add(s);
                this.lbOut.SelectedIndex = this.lbOut.Items.Count - 1;
            }
        }
        catch (System.Exception ex)
        {
            Debug.WriteLine(ex.ToString());
            Debugger.Break();
        }
    }

    private void butSynchronousExecution_Click(object sender, EventArgs e)
    {
        _asyncronousEngine.RequestFileExecution("SynchronousExecution.js");
    }

    private void butASynchronousExecution_Click(object sender, EventArgs e)
    {
        _asyncronousEngine.RequestFileExecution("AsynchronousExecution.js");
    }

    private void butTimer_Click(object sender, EventArgs e)
    {
        _asyncronousEngine.RequestFileExecution("Timer.js");
    }

    private void butMultipleTimer_Click(object sender, EventArgs e)
    {
        _asyncronousEngine.RequestFileExecution("MultipleTimers.js");
    }

    private void butClearListBox_Click(object sender, EventArgs e)
    {
        this.lbOut.Items.Clear();
    }

    private void butClearEventQueue_Click(object sender, EventArgs e)
    {
        butClearListBox_Click(sender, e);
        _asyncronousEngine.RequestClearQueue();
    }

    private void quitToolStripMenuItem_Click(object sender, EventArgs e)
    {
        this.Close();
    }

    private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
        // How to correctly request stopping the AsyncronousEngine event loop
        _asyncronousEngine.Stop(() =>
        {
            Thread.Sleep(100);
            Application.DoEvents();
        });
    }
}

No comments:

Post a Comment