using System; using System.Collections.Generic; using System.Linq; using Bridge; using Bridge.Html5; using Bridge.Text.RegularExpressions; namespace WebMrbc { public class Mruby { public object[] preRun = new object[0]; public object[] postRun = new object[0]; public Mruby() { /*canvas = Document.GetElementById("canvas"); // As a default initial behavior, pop up an alert when webgl context is lost. To make your // application robust, you may want to override this behavior before shipping! // See http://www.khronos.org/registry/webgl/specs/latest/1.0/#5.15.2 canvas.AddEventListener("webglcontextlost", new Action((Event e) => { Window.Alert("WebGL context lost. You will need to reload the page."); e.PreventDefault(); }), false);*/ setStatus = new Action(_setStatus); } public void print(object arg) { string text; Array args; if (arg.GetType() == typeof(string)) text = (string)arg; else if (arg.GetType().Is() && (args = (Array)arg).Length > 1) { var texts = new string[0]; foreach (var ele in args) { texts.Push(ele.ToString()); } text = texts.Join(" "); } else text = arg.ToString(); App.WriteLine(text); } public void printErr(object arg) { string text; Array args; if (arg.GetType() == typeof(string)) text = (string)arg; else if (arg.GetType().Is() && (args = (Array)arg).Length > 1) { var texts = new string[0]; foreach (var ele in args) { texts.Push(ele.ToString()); } text = texts.Join(" "); } else text = arg.ToString(); App.WriteLine(text); } internal void run(string[] args) { App.Write("$ " + args.Join(" ") + "\r\n"); var exe = (string)args.Shift(); this["arguments"] = args; var onerror = Window.OnError; Window.OnError = new ErrorEventHandler((string message, string url, int lineNumber, int columnNumber, object error) => { var spinnerElement = Document.GetElementById("spinner"); // TODO: do not warn on ok events like simulating an infinite loop or exitStatus setStatus("Exception thrown, see JavaScript console"); spinnerElement.Style.Display = Display.None; setStatus = new Action((text) => { if (!string.IsNullOrEmpty(text)) printErr(new[] { "[post-exception status] " + text }); }); onerror(message, url, lineNumber, columnNumber, error); return false; }); try { Script.Eval(exe + "(this)"); } finally { Window.OnError = onerror; } } public HTMLElement canvas; public Action setStatus; object _last; string _text; private void _setStatus(string text) { if (_last == null) _last = new { time = DateTime.Now.Ticks, text = "" }; if (text == _text) return; _text = text; var progressElement = (HTMLProgressElement)Document.GetElementById("progress"); var spinnerElement = (HTMLDivElement)Document.GetElementById("spinner"); var m = text.Match(new Regex(@"([^(]+)\((\d+(\.\d+)?)\/(\d+)\)")); var now = DateTime.Now.Ticks; if (m != null && now - DateTime.Now.Ticks < 30) return; // if this is a progress update, skip it if too soon if (m != null) { text = m[1]; progressElement.Value = Script.ParseInt(m[2]) * 100; progressElement.Max = Script.ParseInt(m[4]) * 100; progressElement.SetAttribute("hidden", "false"); spinnerElement.SetAttribute("hidden", "false"); } else { progressElement.Value = 0.0; progressElement.Max = 0.0; progressElement.SetAttribute("hidden", "true"); if (!string.IsNullOrEmpty(text)) spinnerElement.Style.Display = Display.None; } var statusElement = (HTMLDivElement)Document.GetElementById("status"); statusElement.InnerHTML = text; } public int totalDependencies = 0; public void monitorRunDependencies(int left) { totalDependencies = System.Math.Max(totalDependencies, left); setStatus((left != 0) ? "Preparing... (" + (totalDependencies - left) + "/" + totalDependencies + ")" : "All downloads complete."); } [External, Name(false)] internal string UTF8ArrayToString(Uint8Array buf, int index) { throw new NotImplementedException(); } [External] internal string intArrayToString(Uint8Array buf) { throw new NotImplementedException(); } [External] internal int stringToUTF8Array(string str, Uint8Array outU8Array, int outIdx, int maxBytesToWrite) { throw new NotImplementedException(); } [External] internal int lengthBytesUTF8(string str) { throw new NotImplementedException(); } [Name(false)] internal Uint8Array UTF8StringToArray(string str) { var len = lengthBytesUTF8(str); var result = new Uint8Array(len); stringToUTF8Array(str, result, 0, len); return result; } [Script("return this.FS;")] internal FileSystem GetFileSystem() { return (FileSystem)this["FS"]; } [External] internal void stdin(object data) { throw new NotImplementedException(); } } }