Created
March 12, 2015 18:11
-
-
Save julesx/f5624c6885b5e9f62514 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using Gizmox.WebGUI.Forms; | |
using Microsoft.ClearScript; | |
using Microsoft.ClearScript.V8; | |
namespace ScriptingDemo4 | |
{ | |
public partial class itScriptingFrm : Form | |
{ | |
#region Protected Vars | |
protected ScriptEngine ScriptEngine; | |
protected string EventCount { get { return _scriptEvents.Count.ToString(); } } | |
protected string MethodCount { get { return _scriptMethods.Count.ToString(); } } | |
#endregion | |
#region Private Vars | |
private readonly string _scriptPath; | |
private readonly Dictionary<string, List<string>> _scriptEvents = new Dictionary<string, List<string>>(); | |
private readonly List<string> _scriptMethods = new List<string>(); | |
private readonly List<Control> _controls = new List<Control>(); | |
private Dictionary<Control, List<ClearScriptEvent>> _assignedEvents = new Dictionary<Control, List<ClearScriptEvent>>(); | |
private bool _hasLoaded; | |
#endregion | |
#region C'Tor | |
public itScriptingFrm() | |
{ | |
InitializeComponent(); | |
_scriptPath = @"C:\tmp\scripts\" + GetType().Name + ".js"; | |
Load += itScriptingFrm_Load; | |
} | |
#endregion | |
#region Events | |
void itScriptingFrm_Load(object sender, EventArgs e) | |
{ | |
try | |
{ | |
ScriptEngine = new V8ScriptEngine(); | |
LoadScriptingEngine(); | |
_hasLoaded = true; | |
if (_scriptMethods.Contains("MainForm_Load")) | |
ScriptEngine.Script["MainForm_Load"](); | |
} | |
catch (Exception ex) | |
{ | |
MessageBox.Show(ex.Message); | |
} | |
} | |
#endregion | |
#region Protected Methods | |
protected void LoadScriptingEngine() | |
{ | |
GetMethods();//parses script file for all methods | |
GetEvents();//parses methods for all events | |
//execute script so we can call its methods through the script engine | |
ScriptEngine.Execute(System.IO.File.ReadAllText(_scriptPath)); | |
ScriptEngine.Execute(System.IO.File.ReadAllText(@"c:\tmp\scripts\GlobalScript.js")); | |
//find all controls on the form, and attach the appropriate events | |
AttachEvents(); | |
if (_hasLoaded) return; | |
AddHostTypes();//add any and all types a script would want to use | |
AddHostObjects();//add any and all objects a script would want to use | |
} | |
#endregion | |
#region Private Methods | |
private void AddHostObjects() | |
{ | |
ScriptEngine.AddHostObject("MainForm", this); | |
ScriptEngine.AddHostObject("Gbl", new Globals(ScriptEngine)); | |
foreach (var control in _controls) | |
ScriptEngine.AddHostObject(control.Name, control); | |
} | |
private void AddHostTypes() | |
{ | |
ScriptEngine.AddHostType("Button", typeof(Button)); | |
} | |
private void GetMethods() | |
{ | |
_scriptMethods.Clear(); | |
var script = System.IO.File.ReadAllLines(_scriptPath); | |
foreach (var line in script.Where(x => x.StartsWith("function"))) | |
{ | |
var method = line.Replace("function ", ""); | |
method = method.Substring(0, method.IndexOf("(")); | |
_scriptMethods.Add(method); | |
} | |
} | |
private void GetEvents() | |
{ | |
_scriptEvents.Clear(); | |
foreach (var method in _scriptMethods.Where(x => x.Contains("_"))) | |
{ | |
var split = method.Split('_'); | |
var control = Controls.Find(split[0], true).FirstOrDefault(); | |
if (control != null) | |
ScriptEngine.AddHostObject(split[0], control); | |
var key = split[0]; | |
var value = split[1]; | |
if (!_scriptEvents.ContainsKey(key)) | |
_scriptEvents.Add(key, new List<string>()); | |
_scriptEvents[key].Add(value); | |
} | |
} | |
private void RemoveEvents(Control control) | |
{ | |
foreach (var clearScriptEvent in _assignedEvents[control]) | |
{ | |
var controlEvent = control.GetType().GetEvent(clearScriptEvent.Event); | |
controlEvent.RemoveEventHandler(control, clearScriptEvent.EventHandler); | |
} | |
_assignedEvents[control].Clear(); | |
} | |
private void AttachEvent(Control control, string @event) | |
{ | |
var controlEvent = control.GetType().GetEvent(@event); | |
if (controlEvent == null) | |
throw new Exception(@event + " not supported"); | |
Action<object, EventArgs> myDelegate = (sender, e) => | |
{ | |
ScriptEngine.Script[control.Name + "_" + @event](sender, e); | |
}; | |
EventHandler eventHandler = myDelegate.Invoke; | |
_assignedEvents[control].Add(new ClearScriptEvent(@event, eventHandler)); | |
controlEvent.AddEventHandler(control, eventHandler); | |
} | |
private void AttachEvents(Control.ControlCollection controlCollection = null) | |
{ | |
_controls.Clear(); | |
var controls = controlCollection ?? Controls; | |
foreach (Control control in controls) | |
{ | |
var controlName = control.Name; | |
_controls.Add(control); | |
if (_assignedEvents.ContainsKey(control)) | |
RemoveEvents(control); | |
else | |
_assignedEvents.Add(control, new List<ClearScriptEvent>()); | |
if (control.GetType() == typeof (ControlCollection)) | |
{ | |
AttachEvents(); | |
} | |
else if (_scriptEvents.ContainsKey(controlName)) | |
{ | |
foreach (var @event in _scriptEvents[controlName]) | |
AttachEvent(control, @event); | |
} | |
} | |
} | |
#endregion | |
private class ClearScriptEvent | |
{ | |
public EventHandler EventHandler; | |
public string Event; | |
public ClearScriptEvent(string @event, EventHandler eventHandler) | |
{ | |
Event = @event; | |
EventHandler = eventHandler; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment