mirror of https://github.com/adamdruppe/arsd.git
bugs from dogfooding
This commit is contained in:
parent
bb4619715d
commit
75e13156e9
|
@ -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.
|
/// 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...
|
ubyte[backingSize] bufferBacking = 0; // a null message means exit...
|
||||||
|
|
||||||
writeToEventPipe(bufferBacking);
|
writeToEventPipe(bufferBacking);
|
||||||
}
|
}
|
||||||
|
|
||||||
void writeToEventPipe(ubyte[backingSize] bufferBacking) {
|
void writeToEventPipe(ubyte[backingSize] bufferBacking) @nogc {
|
||||||
ubyte[] buffer = bufferBacking[];
|
ubyte[] buffer = bufferBacking[];
|
||||||
while(buffer.length) {
|
while(buffer.length) {
|
||||||
auto written = unix.write(pipes[1], buffer.ptr, 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
|
// are virtually guaranteed to be smaller than the pipe buffer
|
||||||
// ...unless there's like a thousand messages, which is a WTF anyway
|
// ...unless there's like a thousand messages, which is a WTF anyway
|
||||||
import std.string;
|
import std.string;
|
||||||
assert(0, format("EAGAIN on %d", buffer.length));
|
assert(0); // , format("EAGAIN on %d", buffer.length));
|
||||||
} else
|
} else
|
||||||
throw new Exception("write");
|
assert(0, "write failure");
|
||||||
|
// throw new Exception("write");
|
||||||
} else {
|
} else {
|
||||||
assert(written <= buffer.length);
|
assert(written <= buffer.length);
|
||||||
buffer = buffer[written .. $];
|
buffer = buffer[written .. $];
|
||||||
|
|
10
jsvar.d
10
jsvar.d
|
@ -721,6 +721,10 @@ struct var {
|
||||||
public T get(T)() if(!is(T == void)) {
|
public T get(T)() if(!is(T == void)) {
|
||||||
static if(is(T == var)) {
|
static if(is(T == var)) {
|
||||||
return this;
|
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
|
} else
|
||||||
final switch(payloadType) {
|
final switch(payloadType) {
|
||||||
case Type.Boolean:
|
case Type.Boolean:
|
||||||
|
@ -959,6 +963,12 @@ struct var {
|
||||||
return *tmp;
|
return *tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(name == "toJson") {
|
||||||
|
var* tmp = new var;
|
||||||
|
*tmp = to!string(this.toJson());
|
||||||
|
return *tmp;
|
||||||
|
}
|
||||||
|
|
||||||
if(name == "length" && this.payloadType() == Type.String) {
|
if(name == "length" && this.payloadType() == Type.String) {
|
||||||
var* tmp = new var;
|
var* tmp = new var;
|
||||||
*tmp = _payload._string.length;
|
*tmp = _payload._string.length;
|
||||||
|
|
16
png.d
16
png.d
|
@ -115,6 +115,7 @@ MemoryImage imageFromPng(PNG* png) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
previousLine = data;
|
previousLine = data;
|
||||||
|
import std.conv;
|
||||||
|
|
||||||
loop: for(int pixel = 0; pixel < h.width; pixel++)
|
loop: for(int pixel = 0; pixel < h.width; pixel++)
|
||||||
switch(h.type) {
|
switch(h.type) {
|
||||||
|
@ -167,14 +168,27 @@ MemoryImage imageFromPng(PNG* png) {
|
||||||
break;
|
break;
|
||||||
case 2: // truecolor
|
case 2: // truecolor
|
||||||
case 6: // true with alpha
|
case 6: // true with alpha
|
||||||
|
if(h.depth == 8) {
|
||||||
idata[idataIdx++] = consumeOne();
|
idata[idataIdx++] = consumeOne();
|
||||||
idata[idataIdx++] = consumeOne();
|
idata[idataIdx++] = consumeOne();
|
||||||
idata[idataIdx++] = consumeOne();
|
idata[idataIdx++] = consumeOne();
|
||||||
idata[idataIdx++] = (h.type == 6) ? consumeOne() : 255;
|
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;
|
break;
|
||||||
default: assert(0);
|
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");
|
assert(idataIdx == idata.length, "not all filled, wtf");
|
||||||
|
|
||||||
|
|
45
script.d
45
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 {
|
struct InterpretResult {
|
||||||
var value;
|
var value;
|
||||||
PrototypeObject sc;
|
PrototypeObject sc;
|
||||||
|
@ -451,8 +485,11 @@ class Expression {
|
||||||
var obj = var.emptyObject;
|
var obj = var.emptyObject;
|
||||||
|
|
||||||
obj["type"] = typeid(this).name;
|
obj["type"] = typeid(this).name;
|
||||||
obj["toString"] = (var _this, var[] args) {
|
obj["toSourceCode"] = (var _this, var[] args) {
|
||||||
return var(this.toString());
|
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) {
|
obj["opCall"] = (var _this, var[] args) {
|
||||||
Expression e = this;
|
Expression e = this;
|
||||||
|
@ -461,6 +498,10 @@ class Expression {
|
||||||
return e.interpret(sc).value;
|
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;
|
return obj;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -279,7 +279,7 @@ version(Windows) {
|
||||||
|
|
||||||
// global hotkey helper function
|
// 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;
|
static int hotkeyId = 0;
|
||||||
int id = ++hotkeyId;
|
int id = ++hotkeyId;
|
||||||
if(!RegisterHotKey(window.impl.hwnd, id, modifiers, vk))
|
if(!RegisterHotKey(window.impl.hwnd, id, modifiers, vk))
|
||||||
|
@ -314,6 +314,12 @@ version(Windows) {
|
||||||
window.handleNativeEvent = nativeEventHandler;
|
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
|
// http://msdn.microsoft.com/en-us/library/ms646310%28v=vs.85%29.aspx
|
||||||
extern(Windows) UINT SendInput(UINT, INPUT*, int);
|
extern(Windows) UINT SendInput(UINT, INPUT*, int);
|
||||||
|
|
||||||
|
extern(Windows) BOOL UnregisterHotKey(HWND, int);
|
||||||
|
|
||||||
struct INPUT {
|
struct INPUT {
|
||||||
DWORD type;
|
DWORD type;
|
||||||
union {
|
union {
|
||||||
|
@ -3738,6 +3746,7 @@ else version(X11) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
pragma(lib, "X11");
|
pragma(lib, "X11");
|
||||||
|
pragma(lib, "Xext");
|
||||||
|
|
||||||
extern(C):
|
extern(C):
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue