#region Imported Libraries using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Controls; using Microsoft.Scripting.Hosting; using System.IO; using System.Windows.Input; using IronRuby; using Microsoft.Scripting; using System.Windows; using System.Threading; using System.Reflection; #endregion #region Namespace Declaration namespace Org.TechA.Wpf.UserControls { internal sealed class IronRubyConsolePresenter { #region Private Members private readonly IronRubyConsoleModel _model; private readonly IronRubyConsole _view; #endregion #region Constructor /// /// Default Constructor. /// /// /// The View. /// internal IronRubyConsolePresenter(UserControl view) { //set the model and the view _view = (IronRubyConsole)view; _model = SetupModel(); //set the default scope vars SetDefaultScopeVariables(_model.Scopes[0]); //setup the view InitializeView(); //subscribe to all the view events WireupEvents(); } #endregion #region Accessor Mutators /// /// The View. /// internal IronRubyConsole View { get { return _view; } } /// /// The Model. /// internal IronRubyConsoleModel Model { get { return _model; } } #endregion #region Event Subscriptions /// /// Wireup all the views events. /// internal void WireupEvents() { _view.txtUserCodeInput.KeyDown += new KeyEventHandler(txtUserCodeInput_KeyDown); _view.mitmPrintState.Click += new RoutedEventHandler(mitmPrintState_Click); _view.mitmAbout.Click += new RoutedEventHandler(mitmAbout_Click); _view.mitmAddScope.Click += new RoutedEventHandler(mitmAddScope_Click); _view.mitmClearScreen.Click += new RoutedEventHandler(mitmClearScreen_Click); _view.VariablesAdded += new Action>(_view_VariablesAdded); } void _view_VariablesAdded(Dictionary obj) { foreach (var key in obj.Keys) { _model.Scopes[0].SetVariable(key, obj[key]); } } /// /// Clears the IronRuby output screen. /// /// /// The menu item. /// /// /// The routed event arguments. /// void mitmClearScreen_Click(object sender, RoutedEventArgs e) { _view.txtIronRubyOutput.Clear(); } /// /// Menu item click event for added a scope. /// /// /// The menu item. /// /// /// The Routed event args. /// void mitmAddScope_Click(object sender, RoutedEventArgs e) { } /// /// About window menu item /// click event hanlder. /// /// /// The Menu Item. /// /// /// The routed event arguments. /// void mitmAbout_Click(object sender, RoutedEventArgs e) { AboutDialog dlg = new AboutDialog(); dlg.ShowDialog(); } /// /// /// /// /// void mitmPrintState_Click(object sender, RoutedEventArgs e) { var scope = _model.Scopes[0]; var source = scope.Engine .CreateScriptSourceFromString("puts 'PRINTING VARIABLES FROM DEFAULT SCOPE';" + "puts '************************************************'"); var result = source.Execute(scope); foreach(var varName in scope.GetVariableNames()) { //get the variable by name var variable = scope.GetVariable(varName); //get the script source from string which will //simply print the name of the variable source = scope.Engine .CreateScriptSourceFromString("puts 'Variable Name is [" + varName + "] and value is [" + variable + "]'"); result = source.Execute(scope); _model.Writer.WriteLine(FormatResult(result)); } source = scope.Engine .CreateScriptSourceFromString("puts; puts '************************************************'"); result = source.Execute(scope); } #endregion #region Private Worker Methods /// /// Setup of the View. /// private void InitializeView() { FocusHelper.Focus(_view.txtUserCodeInput); _view.txtUserCodeInput.SelectionStart = 1; } /// /// Setup the IronRuby Runtime, Engine /// and create a default scope. /// private IronRubyConsoleModel SetupModel() { var runtime = Ruby.CreateRuntime(); // give ruby access to all our assemblies foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) { runtime.LoadAssembly(assembly); } var writer = SetupIO(runtime); var engine = runtime.GetEngine("Ruby"); var default_scope = engine.CreateScope(); var model = new IronRubyConsoleModel(writer, engine); model.Scopes.Add(default_scope); return model; } /// /// Setup the IO classes that will have /// the IronRuby runtime have its IO /// redirected to. /// /// /// The IronRuby runtime. /// /// /// The Texwriter that the IronRuby /// runtime will write to. /// private TextWriter SetupIO(ScriptRuntime runtime) { var writer = new TextBoxWriter(_view.txtIronRubyOutput); var stream = new TextWriterStream(writer); runtime.IO.SetOutput(stream, writer); runtime.IO.SetErrorOutput(stream, writer); return writer; } /// /// Formats the result of the of /// execution of code by a ScriptSource. /// /// /// The result of running a given script. /// /// /// Returns the formatted result from /// running a given script. /// private string FormatResult(object obj) { var prefix = "=> "; var result = default(string); if (obj == null) result = "nil"; else result = obj.ToString(); return prefix + result; } /// /// Runs the code typed in the console window. /// /// /// The code string. /// private void RunCode(string theCode) { _model.Writer.WriteLine(">>> " + theCode); try { var scriptSource = _model.Engine. CreateScriptSourceFromString(theCode, SourceCodeKind.Statements); var result = scriptSource.Execute(_model.Scopes[0]); _model.Writer.WriteLine(FormatResult(result)); } catch (Exception e) { _model.Writer.WriteLine(e.Message); } } /// /// Sets any variables required /// for the default scope. /// /// /// The default scope. /// private void SetDefaultScopeVariables(ScriptScope scope) { scope.SetVariable("scopename", "Default"); scope.SetVariable("windowcount", Application.Current.Windows.Count); } #endregion #region Event Delegates /// /// The user entry code textbox /// key down event handler. /// /// /// The code text box. /// /// /// The keys event args. /// void txtUserCodeInput_KeyDown(object sender, KeyEventArgs e) { if (e.Key == Key.Enter) { RunCode(this._view.txtUserCodeInput.Text); e.Handled = true; this._view.txtUserCodeInput.Clear(); } } #endregion } } #endregion