diff --git a/eventloop.d b/eventloop.d index beba0f2..b16560b 100644 --- a/eventloop.d +++ b/eventloop.d @@ -106,13 +106,13 @@ public void clearInterval(TimerHandle handle) { } /// Sends an exit event to the loop. The loop will break when it sees this event, ignoring any events after that point. -public void exit() { +public void exit() @nogc { ubyte[backingSize] bufferBacking = 0; // a null message means exit... writeToEventPipe(bufferBacking); } -void writeToEventPipe(ubyte[backingSize] bufferBacking) { +void writeToEventPipe(ubyte[backingSize] bufferBacking) @nogc { ubyte[] buffer = bufferBacking[]; while(buffer.length) { auto written = unix.write(pipes[1], buffer.ptr, buffer.length); @@ -124,9 +124,10 @@ void writeToEventPipe(ubyte[backingSize] bufferBacking) { // are virtually guaranteed to be smaller than the pipe buffer // ...unless there's like a thousand messages, which is a WTF anyway import std.string; - assert(0, format("EAGAIN on %d", buffer.length)); + assert(0); // , format("EAGAIN on %d", buffer.length)); } else - throw new Exception("write"); + assert(0, "write failure"); + // throw new Exception("write"); } else { assert(written <= buffer.length); buffer = buffer[written .. $]; diff --git a/jsvar.d b/jsvar.d index 06bb481..d715204 100644 --- a/jsvar.d +++ b/jsvar.d @@ -721,6 +721,10 @@ struct var { public T get(T)() if(!is(T == void)) { static if(is(T == var)) { return this; + } else static if(__traits(compiles, T(this))) { + return T(this); + } else static if(__traits(compiles, new T(this))) { + return new T(this); } else final switch(payloadType) { case Type.Boolean: @@ -959,6 +963,12 @@ struct var { return *tmp; } + if(name == "toJson") { + var* tmp = new var; + *tmp = to!string(this.toJson()); + return *tmp; + } + if(name == "length" && this.payloadType() == Type.String) { var* tmp = new var; *tmp = _payload._string.length; diff --git a/png.d b/png.d index af79a95..d3e1c9e 100644 --- a/png.d +++ b/png.d @@ -115,6 +115,7 @@ MemoryImage imageFromPng(PNG* png) { return ret; } previousLine = data; + import std.conv; loop: for(int pixel = 0; pixel < h.width; pixel++) switch(h.type) { @@ -167,14 +168,27 @@ MemoryImage imageFromPng(PNG* png) { break; case 2: // truecolor case 6: // true with alpha - idata[idataIdx++] = consumeOne(); - idata[idataIdx++] = consumeOne(); - idata[idataIdx++] = consumeOne(); - idata[idataIdx++] = (h.type == 6) ? consumeOne() : 255; + if(h.depth == 8) { + idata[idataIdx++] = consumeOne(); + idata[idataIdx++] = consumeOne(); + idata[idataIdx++] = consumeOne(); + idata[idataIdx++] = (h.type == 6) ? consumeOne() : 255; + } else if(h.depth == 16) { + idata[idataIdx++] = consumeOne(); + consumeOne(); + idata[idataIdx++] = consumeOne(); + consumeOne(); + idata[idataIdx++] = consumeOne(); + consumeOne(); + idata[idataIdx++] = (h.type == 6) ? consumeOne() : 255; + if(h.type == 6) + consumeOne(); + + } else assert(0, "unsupported truecolor bit depth " ~ to!string(h.depth)); break; default: assert(0); } - assert(data.length == 0, "not all consumed, wtf"); + assert(data.length == 0, "not all consumed, wtf " ~ to!string(h)); } assert(idataIdx == idata.length, "not all filled, wtf"); diff --git a/script.d b/script.d index 9f83fb6..1a0d9d7 100644 --- a/script.d +++ b/script.d @@ -433,6 +433,40 @@ class MacroPrototype : PrototypeObject { } } +alias helper(alias T) = T; +// alternative to virtual function for converting the expression objects to script objects +void addChildElementsOfExpressionToScriptExpressionObject(ClassInfo c, Expression _thisin, PrototypeObject sc, ref var obj) { + foreach(itemName; __traits(allMembers, mixin(__MODULE__))) + static if(__traits(compiles, __traits(getMember, mixin(__MODULE__), itemName))) { + alias Class = helper!(__traits(getMember, mixin(__MODULE__), itemName)); + static if(is(Class : Expression)) if(c == typeid(Class)) { + auto _this = cast(Class) _thisin; + foreach(memberName; __traits(allMembers, Class)) { + alias member = helper!(__traits(getMember, Class, memberName)); + + static if(is(typeof(member) : Expression)) { + auto lol = __traits(getMember, _this, memberName); + if(lol is null) + obj[memberName] = null; + else + obj[memberName] = lol.toScriptExpressionObject(sc); + } + static if(is(typeof(member) : Expression[])) { + obj[memberName] = var.emptyArray; + foreach(m; __traits(getMember, _this, memberName)) + if(m !is null) + obj[memberName] ~= m.toScriptExpressionObject(sc); + else + obj[memberName] ~= null; + } + static if(is(typeof(member) : string) || is(typeof(member) : long) || is(typeof(member) : real) || is(typeof(member) : bool)) { + obj[memberName] = __traits(getMember, _this, memberName); + } + } + } + } +} + struct InterpretResult { var value; PrototypeObject sc; @@ -451,8 +485,11 @@ class Expression { var obj = var.emptyObject; obj["type"] = typeid(this).name; - obj["toString"] = (var _this, var[] args) { - return var(this.toString()); + obj["toSourceCode"] = (var _this, var[] args) { + Expression e = this; + // FIXME: if they changed the properties in the + // script, we should update them here too. + return var(e.toString()); }; obj["opCall"] = (var _this, var[] args) { Expression e = this; @@ -461,6 +498,10 @@ class Expression { return e.interpret(sc).value; }; + // adding structure is going to be a little bit magical + // I could have done this with a virtual function, but I'm lazy. + addChildElementsOfExpressionToScriptExpressionObject(typeid(this), this, sc, obj); + return obj; } } diff --git a/simpledisplay.d b/simpledisplay.d index dc9a157..0ac7fcb 100644 --- a/simpledisplay.d +++ b/simpledisplay.d @@ -279,7 +279,7 @@ version(Windows) { // global hotkey helper function - void registerHotKey(SimpleWindow window, UINT modifiers, UINT vk, void delegate() handler) { + int registerHotKey(SimpleWindow window, UINT modifiers, UINT vk, void delegate() handler) { static int hotkeyId = 0; int id = ++hotkeyId; if(!RegisterHotKey(window.impl.hwnd, id, modifiers, vk)) @@ -314,6 +314,12 @@ version(Windows) { window.handleNativeEvent = nativeEventHandler; } + return id; + } + + void unregisterHotKey(SimpleWindow window, int id) { + if(!UnregisterHotKey(window.impl.hwnd, id)) + throw new Exception("UnregisterHotKey"); } } @@ -3671,6 +3677,8 @@ nothrow: // http://msdn.microsoft.com/en-us/library/ms646310%28v=vs.85%29.aspx extern(Windows) UINT SendInput(UINT, INPUT*, int); + extern(Windows) BOOL UnregisterHotKey(HWND, int); + struct INPUT { DWORD type; union { @@ -3738,6 +3746,7 @@ else version(X11) { */ pragma(lib, "X11"); +pragma(lib, "Xext"); extern(C):