From 17cb9e51b412dee6de6ad0cf11892adc1f290f34 Mon Sep 17 00:00:00 2001 From: vroad Date: Sat, 1 Nov 2014 11:11:57 +0900 Subject: [PATCH] Work on node.js support --- lime/app/Application.hx | 34 ++++++++-- lime/system/System.hx | 20 +++--- lime/utils/ByteArray.hx | 78 ++++++++++++++++++++-- project/include/app/Application.h | 3 + project/src/ExternalInterface.cpp | 24 +++++++ project/src/backend/sdl/SDLApplication.cpp | 76 ++++++++++++--------- project/src/backend/sdl/SDLApplication.h | 3 + templates/haxe/ApplicationMain.hx | 2 +- 8 files changed, 188 insertions(+), 52 deletions(-) diff --git a/lime/app/Application.hx b/lime/app/Application.hx index cb82f04c5..cf0eddf06 100644 --- a/lime/app/Application.hx +++ b/lime/app/Application.hx @@ -136,11 +136,28 @@ class Application extends Module { */ public function exec ():Int { - #if (cpp || neko || nodejs) + #if nodejs - var result = lime_application_exec (__handle); + lime_application_init(__handle); + var eventLoop = function() { + var active = lime_application_update(__handle); + if (!active) { + var result = lime_application_quit(__handle); + __cleanup(); + Sys.exit(result); + } + untyped setImmediate(eventLoop); + } + untyped setImmediate(eventLoop); - AudioManager.shutdown (); + #elseif (cpp || neko) + + lime_application_init(__handle); + while(lime_application_update(__handle)) + {} + var result = lime_application_quit (__handle); + + __cleanup(); return result; @@ -185,6 +202,13 @@ class Application extends Module { } + #if (cpp || neko || nodejs) + @:noCompletion private function __cleanup():Void { + + AudioManager.shutdown(); + + } + #end /** * The init() method is called once before the first render() @@ -380,7 +404,9 @@ class Application extends Module { #if (cpp || neko || nodejs) private static var lime_application_create = System.load ("lime", "lime_application_create", 1); - private static var lime_application_exec = System.load ("lime", "lime_application_exec", 1); + private static var lime_application_init = System.load ("lime", "lime_application_init", 1); + private static var lime_application_update = System.load ("lime", "lime_application_update", 1); + private static var lime_application_quit = System.load ("lime", "lime_application_quit", 1); private static var lime_application_get_ticks = System.load ("lime", "lime_application_get_ticks", 0); private static var lime_update_event_manager_register = System.load ("lime", "lime_update_event_manager_register", 2); #end diff --git a/lime/system/System.hx b/lime/system/System.hx index 2084f6e70..107f48b43 100644 --- a/lime/system/System.hx +++ b/lime/system/System.hx @@ -7,7 +7,7 @@ import js.html.HtmlElement; import js.Browser; #end -#if sys +#if (sys && !html5) import sys.io.Process; #end @@ -83,7 +83,7 @@ class System { static private function findHaxeLib (library:String):String { - #if sys + #if (sys && !html5) try { @@ -149,7 +149,7 @@ class System { } #if !disable_cffi - #if sys + #if (sys && !html5) #if (iphone || emscripten || android || static_link) return cpp.Lib.load (library, method, args); @@ -162,7 +162,9 @@ class System { return cpp.Lib.load (__moduleNames.get (library), method, args); #elseif neko return neko.Lib.load (__moduleNames.get (library), method, args); - #else + #elseif nodejs + return js.Lib.load (__moduleNames.get (library), method, args); + #else return null; #end @@ -239,7 +241,7 @@ class System { private static function sysName ():String { - #if sys + #if (sys && !html5) #if cpp var sys_string = cpp.Lib.load ("std", "sys_string", 0); return sys_string (); @@ -255,7 +257,7 @@ class System { private static function tryLoad (name:String, library:String, func:String, args:Int):Dynamic { - #if sys + #if (sys && !html5) try { @@ -263,7 +265,9 @@ class System { var result = cpp.Lib.load (name, func, args); #elseif (neko) var result = neko.Lib.load (name, func, args); - #else + #elseif nodejs + var result = js.Lib.load (name, func, args); + #else var result = null; #end @@ -290,7 +294,7 @@ class System { private static function loaderTrace (message:String) { - #if sys + #if (sys && !html5) #if cpp var get_env = cpp.Lib.load ("std", "get_env", 1); diff --git a/lime/utils/ByteArray.hx b/lime/utils/ByteArray.hx index 2aef176b6..4b9ef197f 100644 --- a/lime/utils/ByteArray.hx +++ b/lime/utils/ByteArray.hx @@ -91,8 +91,13 @@ class ByteArray #if !html5 extends Bytes #end implements ArrayAccess #if !h allocated = size < 16 ? 16 : size; var bytes = untyped __dollar__smake (allocated); super (size, bytes); - #else + #else + #if nodejs + var data = new BytesData(size); + data.fill(0); + #else var data = new BytesData (); + #end #if cpp NativeArray.setSize (data, size); #else @@ -209,6 +214,17 @@ class ByteArray #if !html5 extends Bytes #end implements ArrayAccess #if !h b = new_b; } + #elseif nodejs + if (b == null) + b = new BytesData(len); + else + { + var new_b = new BytesData(len); + b.copy(new_b); + if (new_b.length > b.length) + new_b.fill(0, b.length, new_b.length); + b = new_b; + } #else if (b == null) b = new BytesData (); @@ -382,6 +398,10 @@ class ByteArray #if !html5 extends Bytes #end implements ArrayAccess #if !h var int = data.getInt32 (this.position, littleEndian); this.position += 4; return int; + #elseif nodejs + var int = littleEndian ? b.readInt32LE(this.position) : b.readInt32BE(this.position); + this.position += 4; + return int; #else var ch1 = readUnsignedByte (); var ch2 = readUnsignedByte (); @@ -406,6 +426,10 @@ class ByteArray #if !html5 extends Bytes #end implements ArrayAccess #if !h var short = data.getInt16 (this.position, littleEndian); this.position += 2; return short; + #elseif nodejs + var short = littleEndian ? b.readInt16LE(this.position) : b.readInt16BE(this.position); + this.position += 2; + return short; #else var ch1 = readUnsignedByte (); var ch2 = readUnsignedByte (); @@ -434,6 +458,10 @@ class ByteArray #if !html5 extends Bytes #end implements ArrayAccess #if !h var uInt = data.getUint32 (this.position, littleEndian); this.position += 4; return uInt; + #elseif nodejs + var uInt = littleEndian ? b.readUInt32LE(this.position) : b.readUInt32BE(this.position); + this.position += 4; + return uInt; #else var ch1 = readUnsignedByte (); var ch2 = readUnsignedByte (); @@ -451,6 +479,10 @@ class ByteArray #if !html5 extends Bytes #end implements ArrayAccess #if !h var uShort = data.getUint16 (this.position, littleEndian); this.position += 2; return uShort; + #elseif nodejs + var uShort = littleEndian ? b.readInt16LE(this.position) : b.readInt16BE(this.position); + this.position += 2; + return uShort; #else var ch1 = readUnsignedByte (); var ch2 = readUnsignedByte (); @@ -524,7 +556,9 @@ class ByteArray #if !html5 extends Bytes #end implements ArrayAccess #if !h var result = ""; untyped __global__.__hxcpp_string_of_bytes (b, result, p, len); return result; - #else + #elseif nodejs + return untyped b.toString(); + #else return "-"; #end @@ -663,7 +697,9 @@ class ByteArray #if !html5 extends Bytes #end implements ArrayAccess #if !h #if cpp untyped b.__unsafe_set (position++, byte); - #else + #elseif nodejs + b.writeUInt8 (byte, position++/*, true*/); + #else untyped __dollar__sset (b, position++, byte & 0xff); #end @@ -688,6 +724,8 @@ class ByteArray #if !html5 extends Bytes #end implements ArrayAccess #if !h ensureElem (position, true); #if cpp b[position++] = untyped value; + #elseif nodejs + b.writeUInt8(value, position++); #else untyped __dollar__sset (b, position++, value & 0xff); #end @@ -767,7 +805,13 @@ class ByteArray #if !html5 extends Bytes #end implements ArrayAccess #if !h this.position += 4; #else ensureElem (position + 3, true); - + #if nodejs + if (littleEndian) + b.writeInt32LE(value, position); + else + b.writeInt32BE(value, position); + this.position += 4; + #else if (littleEndian) { write_uncheck (value); @@ -784,6 +828,7 @@ class ByteArray #if !html5 extends Bytes #end implements ArrayAccess #if !h } #end + #end } @@ -796,7 +841,13 @@ class ByteArray #if !html5 extends Bytes #end implements ArrayAccess #if !h this.position += 2; #else ensureElem (position + 1, true); - + #if nodejs + if (littleEndian) + b.writeInt16LE(value, position); + else + b.writeInt16BE(value, position); + this.position += 2; + #else if (littleEndian) { write_uncheck (value); @@ -808,7 +859,7 @@ class ByteArray #if !html5 extends Bytes #end implements ArrayAccess #if !h write_uncheck (value); } - + #end #end } @@ -820,6 +871,13 @@ class ByteArray #if !html5 extends Bytes #end implements ArrayAccess #if !h ensureWrite (this.position + 4); data.setUint32 (this.position, value, littleEndian); this.position += 4; + #elseif nodejs + ensureElem (position + 3, true); + if (littleEndian) + b.writeUInt32LE(value, this.position); + else + b.writeUInt32BE(value, this.position); + this.position += 4; #else writeInt (value); #end @@ -833,6 +891,12 @@ class ByteArray #if !html5 extends Bytes #end implements ArrayAccess #if !h ensureWrite (this.position + 2); data.setUint16 (this.position, value, littleEndian); this.position += 2; + #elseif nodejs + if (littleEndian) + b.writeUInt16LE(value, position); + else + b.writeUInt16BE(value, position); + this.position += 2; #else writeShort (value); #end @@ -929,6 +993,8 @@ class ByteArray #if !html5 extends Bytes #end implements ArrayAccess #if !h // No bounds checking is done in the cpp case #if cpp return untyped b[pos]; + #elseif nodejs + return untyped b[pos]; #else return get (pos); #end diff --git a/project/include/app/Application.h b/project/include/app/Application.h index 3f5d5ee1a..70924a3cd 100644 --- a/project/include/app/Application.h +++ b/project/include/app/Application.h @@ -17,7 +17,10 @@ namespace lime { static AutoGCRoot* callback; + virtual void Init() = 0; virtual int Exec () = 0; + virtual bool Update() = 0; + virtual int Quit() = 0; }; diff --git a/project/src/ExternalInterface.cpp b/project/src/ExternalInterface.cpp index 1767328e0..25d8a02af 100644 --- a/project/src/ExternalInterface.cpp +++ b/project/src/ExternalInterface.cpp @@ -43,6 +43,14 @@ namespace lime { } + value lime_application_init (value application) { + + Application* app = (Application*)(intptr_t)val_float (application); + app->Init(); + return alloc_null (); + + } + value lime_application_exec (value application) { Application* app = (Application*)(intptr_t)val_float (application); @@ -50,6 +58,19 @@ namespace lime { } + value lime_application_update (value application) { + + Application* app = (Application*)(intptr_t)val_float (application); + return alloc_bool (app->Update ()); + + } + + value lime_application_quit (value application) { + + Application* app = (Application*)(intptr_t)val_float (application); + return alloc_bool (app->Quit ()); + + } value lime_application_get_ticks (value application) { @@ -385,7 +406,10 @@ namespace lime { DEFINE_PRIM (lime_application_create, 1); + DEFINE_PRIM (lime_application_init, 1); DEFINE_PRIM (lime_application_exec, 1); + DEFINE_PRIM (lime_application_update, 1); + DEFINE_PRIM (lime_application_quit, 1); DEFINE_PRIM (lime_application_get_ticks, 0); DEFINE_PRIM (lime_audio_load, 1); DEFINE_PRIM (lime_font_create_image, 1); diff --git a/project/src/backend/sdl/SDLApplication.cpp b/project/src/backend/sdl/SDLApplication.cpp index a7d7d66bd..8dc60a884 100644 --- a/project/src/backend/sdl/SDLApplication.cpp +++ b/project/src/backend/sdl/SDLApplication.cpp @@ -58,7 +58,7 @@ namespace lime { static SDL_TimerID timerID = 0; bool timerActive = false; - + bool firstTime = true; Uint32 OnTimer (Uint32 interval, void *) { @@ -80,65 +80,75 @@ namespace lime { } - - int SDLApplication::Exec () { - + void SDLApplication::Init() { + framePeriod = 1000.0 / 60.0; - SDL_Event event; active = true; lastUpdate = SDL_GetTicks (); nextUpdate = lastUpdate; + + } + + int SDLApplication::Exec () { - bool firstTime = true; + Init(); - while (active) { + while (active) + Update(); + + return Quit(); + } + + bool SDLApplication::Update() { + + SDL_Event event; + event.type = -1; + if (active && (firstTime || SDL_WaitEvent (&event))) { + + firstTime = false; + + HandleEvent (&event); event.type = -1; + if (!active) + return active; - while (active && (firstTime || SDL_WaitEvent (&event))) { - - firstTime = false; + if (SDL_PollEvent (&event)) { HandleEvent (&event); event.type = -1; - if (!active) break; - while (active && SDL_PollEvent (&event)) { - - HandleEvent (&event); - event.type = -1; - if (!active) break; - - } + } + + currentUpdate = SDL_GetTicks (); + + if (currentUpdate >= nextUpdate) { - currentUpdate = SDL_GetTicks (); + SDL_RemoveTimer (timerID); + OnTimer (0, 0); - if (currentUpdate >= nextUpdate) { - - SDL_RemoveTimer (timerID); - OnTimer (0, 0); - - } else if (!timerActive) { - - timerActive = true; - timerID = SDL_AddTimer (nextUpdate - currentUpdate, OnTimer, 0); - - } + } else if (!timerActive) { + + timerActive = true; + timerID = SDL_AddTimer (nextUpdate - currentUpdate, OnTimer, 0); } } - + return active; + } + + int SDLApplication::Quit() { + windowEvent.type = WINDOW_DEACTIVATE; WindowEvent::Dispatch (&windowEvent); SDL_Quit (); return 0; - + } - void SDLApplication::HandleEvent (SDL_Event* event) { switch (event->type) { diff --git a/project/src/backend/sdl/SDLApplication.h b/project/src/backend/sdl/SDLApplication.h index 1602025ca..acbe8619b 100644 --- a/project/src/backend/sdl/SDLApplication.h +++ b/project/src/backend/sdl/SDLApplication.h @@ -22,7 +22,10 @@ namespace lime { SDLApplication (); ~SDLApplication (); + virtual void Init(); virtual int Exec (); + virtual bool Update(); + virtual int Quit(); private: diff --git a/templates/haxe/ApplicationMain.hx b/templates/haxe/ApplicationMain.hx index ed657fd99..cfdcdeb22 100644 --- a/templates/haxe/ApplicationMain.hx +++ b/templates/haxe/ApplicationMain.hx @@ -76,7 +76,7 @@ class ApplicationMain { var result = app.exec (); - #if sys + #if (sys && !nodejs) Sys.exit (result); #end