From f7e9c34d5a9de06941a4aee6e5bd6a55d8a9f736 Mon Sep 17 00:00:00 2001 From: Jason Walter Date: Fri, 26 May 2017 15:02:29 -0400 Subject: [PATCH 1/5] batch script to compile for all targets. --- tools/makeall.bat | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 tools/makeall.bat diff --git a/tools/makeall.bat b/tools/makeall.bat new file mode 100644 index 0000000..99f3d17 --- /dev/null +++ b/tools/makeall.bat @@ -0,0 +1,3 @@ +ruby make.rb --config debug +ruby make.rb --config dev +ruby make.rb --config release From 92f058762af7d00477e673a70f61e58096c9dd00 Mon Sep 17 00:00:00 2001 From: Jason Walter Date: Tue, 30 May 2017 13:18:57 -0400 Subject: [PATCH 2/5] Add hooks to allow JS to send events to Lua. --- engine/html5_api_lua.cpp | 46 ++++++++++++++++++++++ engine/html5_lua_events.cpp | 50 ++++++++++++++++++++++++ engine/html5_lua_events.h | 54 ++++++++++++++++++++++++++ engine/html5_plugin.cpp | 3 ++ engine/html5_web_api.cpp | 10 +++++ plugin/html5_resources/web_app.lua | 17 +++++++- plugin/sample_project/app.html5/app.js | 1 + 7 files changed, 179 insertions(+), 2 deletions(-) create mode 100644 engine/html5_lua_events.cpp create mode 100644 engine/html5_lua_events.h diff --git a/engine/html5_api_lua.cpp b/engine/html5_api_lua.cpp index 404d485..c938212 100644 --- a/engine/html5_api_lua.cpp +++ b/engine/html5_api_lua.cpp @@ -1,6 +1,7 @@ #include "html5_api.h" #include "html5_web_view.h" #include "html5_api_bindings.h" +#include "html5_lua_events.h" #include #include @@ -85,6 +86,28 @@ template T get_object(lua_State *L, int i) return (T)p; } +__forceinline void push(lua_State *L, int n) +{ + stingray::api::lua->pushnumber(L, n); +} + +__forceinline void push(lua_State *L, const char *s) +{ + stingray::api::lua->pushstring(L, s); +} + +template +__forceinline void set_field(lua_State *L, const char *key, T value) +{ + push(L, value); + stingray::api::lua->setfield(L, -2, key); +} + +__forceinline void push_new_table(lua_State* L) +{ + stingray::api::lua->createtable(L, 0, 0); +} + /* @adoc lua @obj stingray.WebView : userdata @grp core @@ -168,6 +191,29 @@ void load_lua_api(LuaApi* env) return 0; }); + /* @adoc lua + @sig stingray.WebApp.consume_events() : {event_name, event_data} + @des Consume all events available for processing. + */ + env->add_module_function("WebApp", "consume_events", [](lua_State* L) + { + LuaEventPtr event = event_handler()->consume_one(); + push_new_table(L); + unsigned counter = 0; + while ( event ) { + // Specify the table index. + push( L, ++counter ); + // Create a new table at the pushed index. + push_new_table(L); + // Now set the appropriate fields. + set_field(L, "name", event->name.c_str()); + set_field(L, "data", event->data.c_str()); + stingray::api::lua->settable( L, -3 ); + event = event_handler()->consume_one(); + } + return 1; + }); + /* @adoc lua @sig stingray.WebApp.render() : nil @des Render and synchronize the web app with the engine render frame. diff --git a/engine/html5_lua_events.cpp b/engine/html5_lua_events.cpp new file mode 100644 index 0000000..2d185a1 --- /dev/null +++ b/engine/html5_lua_events.cpp @@ -0,0 +1,50 @@ +#include "stingray_api.h" + +#include "html5_lua_events.h" +#include +#include + +namespace PLUGIN_NAMESPACE { + + LuaEventPtr LuaEventHandler::add_event(const char *name, const char *data) + { + LuaEventPtr event = MAKE_NEW(allocator, LuaEvent, allocator); + event->name = name; + event->data = data; + + events.push_back( event ); + + return event; + } + + LuaEventPtr LuaEventHandler::consume_one() + { + if ( stack_idx < events.size() ) { + return events[stack_idx++]; + } + + stack_idx = 0; + events.clear(); + return nullptr; + } + + LuaEventHandler *event_handler() + { + return LuaEventHandler::instance; + } + + void setup_lua_event_table() + { + LuaEventHandler::instance = + MAKE_NEW(allocator, LuaEventHandler, allocator); + } + + void shutdown_lua_event_table() + { + MAKE_DELETE_TYPE(LuaEventHandler::instance->allocator, + LuaEventHandler, + LuaEventHandler::instance); + } + + LuaEventHandler* LuaEventHandler::instance = nullptr; +}; diff --git a/engine/html5_lua_events.h b/engine/html5_lua_events.h new file mode 100644 index 0000000..42faa6d --- /dev/null +++ b/engine/html5_lua_events.h @@ -0,0 +1,54 @@ +#pragma once + +#include "shared_ptr.h" + +#include + +#include +#include +#include + +namespace PLUGIN_NAMESPACE { + + using namespace stingray_plugin_foundation; + + struct LuaEvent { + ALLOCATOR_AWARE; + + explicit LuaEvent( Allocator &a ) + : allocator(a), + name(a), + data(a) + { + } + + Allocator &allocator; + DynamicString name; + DynamicString data; + }; + typedef shared_ptr LuaEventPtr; + + struct LuaEventHandler { + + ALLOCATOR_AWARE; + explicit LuaEventHandler(Allocator &a) + : allocator(a), + events(a), + stack_idx(0) + { + } + + LuaEventPtr add_event(const char *name, const char *data); + LuaEventPtr consume_one(); + + Allocator &allocator; + Vector events; + unsigned stack_idx; + static LuaEventHandler* instance; + }; + + LuaEventHandler * event_handler(); + void setup_lua_event_table(); + void shutdown_lua_event_table(); + +} // end namespace diff --git a/engine/html5_plugin.cpp b/engine/html5_plugin.cpp index b931cbe..d1da351 100644 --- a/engine/html5_plugin.cpp +++ b/engine/html5_plugin.cpp @@ -3,6 +3,7 @@ #include "html5_api.h" #include "html5_web_browser.h" #include "html5_web_page.h" +#include "html5_lua_events.h" #include #include @@ -83,6 +84,7 @@ void setup_runtime_plugin(GetApiFunction get_engine_api) load_lua_api(stingray::api::lua); setup_web_page_database(); + setup_lua_event_table(); // Initialize modules browser::init(); @@ -165,6 +167,7 @@ void unload_plugin() browser::shutdown(); unload_lua_api(stingray::api::lua); shutdown_web_page_database(); + shutdown_lua_event_table(); WebApp::shutdown(); unload_common_plugin_resources(); diff --git a/engine/html5_web_api.cpp b/engine/html5_web_api.cpp index 56d8ba4..27707dd 100644 --- a/engine/html5_web_api.cpp +++ b/engine/html5_web_api.cpp @@ -1,6 +1,8 @@ +#include "shared_ptr.h" #include "html5_web_browser.h" #include "html5_web_view.h" #include "html5_api_bindings.h" +#include "html5_lua_events.h" #include @@ -20,6 +22,14 @@ void bind_api_web_app(CefRefPtr stingray_ns) sync_signal(); return CefV8Value::CreateUndefined(); }); + + bind_api(ns, "emit", [](const CefV8ValueList& args) + { + const char *messageName = get_arg( args, 0 ); + const char *messageData = get_arg( args, 1 ); + event_handler()->add_event( messageName, messageData ); + return CefV8Value::CreateUndefined(); + }); } void bind_api_web_view(CefRefPtr stingray_ns) diff --git a/plugin/html5_resources/web_app.lua b/plugin/html5_resources/web_app.lua index b9f26f0..f03d439 100644 --- a/plugin/html5_resources/web_app.lua +++ b/plugin/html5_resources/web_app.lua @@ -3,6 +3,8 @@ local web_app +local print_events = true + local app_settings = stingray.Application.settings() or {} local web_app_url = app_settings.web_app_url or "stingray://app/main.html" if not stingray.Script.exists(web_app_url) then @@ -23,8 +25,19 @@ function shutdown() stingray.WebApp.destroy(web_app) end -function update(dt) - stingray.WebApp.update(web_app, dt) +if print_events then + function update(dt) + stingray.WebApp.update(web_app, dt) + local events = stingray.WebApp.consume_events() + for i=1,#events,1 do + print( 'name: ' .. events[i].name ) + print( 'data: ' .. events[i].data ) + end + end +else + function update(dt) + stingray.WebApp.update(web_app, dt) + end end function render() diff --git a/plugin/sample_project/app.html5/app.js b/plugin/sample_project/app.html5/app.js index 6812ed3..6d45b74 100644 --- a/plugin/sample_project/app.html5/app.js +++ b/plugin/sample_project/app.html5/app.js @@ -138,6 +138,7 @@ define(require => { Vector2.create(0,0), 2, Vector2.create(res[0],res[1])) } + stingray.WebApp.emit("worldCreated", '{"value":true}'); } /** From 4811db91aa62bbcad0a0047f8588c9f4ac22d067 Mon Sep 17 00:00:00 2001 From: Jason Walter Date: Tue, 30 May 2017 13:22:46 -0400 Subject: [PATCH 3/5] Ignore .pshell files and any test *.bat files. --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index 1d977b5..7fa579f 100644 --- a/.gitignore +++ b/.gitignore @@ -77,7 +77,11 @@ make_args.txt # Visual Studio Code config .settings jsconfig.json +.pshell_info .vs/ # Webstorm project folder .idea/ + +run.bat +run_debug.bat From be02f3eb686b4f919e7caa72eac9fe2f2425c175 Mon Sep 17 00:00:00 2001 From: Jason Walter Date: Fri, 2 Jun 2017 10:46:30 -0400 Subject: [PATCH 4/5] Add support to send events back up to javascript. - Users can pass message up via LUA. - Supported on WebApp or WebViews. --- engine/html5_api_lua.cpp | 58 ++++++++++++++++++++++++++ plugin/html5_resources/web_app.lua | 11 ++++- plugin/sample_project/app.html5/app.js | 3 ++ 3 files changed, 70 insertions(+), 2 deletions(-) diff --git a/engine/html5_api_lua.cpp b/engine/html5_api_lua.cpp index c938212..a085ee8 100644 --- a/engine/html5_api_lua.cpp +++ b/engine/html5_api_lua.cpp @@ -169,6 +169,39 @@ void load_lua_api(LuaApi* env) return 1; }); + /* @adoc lua + @sig stingray.WebApp.emit() : {event_name, event_data} + @des Emit an event to the web app. + */ + env->add_module_function("WebApp", "emit", [](lua_State* L) + { + TempAllocator tempalloc( stingray::api::allocator_api ); + + if (!web_apps) + return 0; + + CefRefPtr web_app = get_web_app(L, 1); + if (!web_app->is_ready()) + return 0; + + const char* name = stingray::api::lua->tolstring(L, 2, nullptr); + const char* data = stingray::api::lua->tolstring(L, 3, nullptr); + + if ( web_app && name && data ) { + unsigned len = (unsigned)strlen(data) + + (unsigned)strlen(name) + 128; + const char *sync = "stingray.WebApp.sync();"; + const char *dispatch = + "window.dispatchEvent(new CustomEvent('%s',{detail:%s}));%s"; + char *event = (char *)tempalloc.allocate( len ); + if ( snprintf( event, len, dispatch, name, data, sync ) > 0 ) { + web_app->execute( event ); + } + return 1; + } + return 0; + }); + /* @adoc lua @sig stingray.WebApp.update(dt: number) : nil @des Update and synchronize the web app with the engine update loop. @@ -214,6 +247,31 @@ void load_lua_api(LuaApi* env) return 1; }); + /* @adoc lua + @sig stingray.WebView.emit() : {event_name, event_data} + @des Emit an event to the WebView. + */ + env->add_module_function("WebView", "emit", [](lua_State* L) + { + TempAllocator tempalloc( stingray::api::allocator_api ); + CefRefPtr web_view = get_web_view(L, 1); + const char* name = stingray::api::lua->tolstring(L, 2, nullptr); + const char* data = stingray::api::lua->tolstring(L, 3, nullptr); + + if ( web_view && name && data ) { + unsigned len = (unsigned)strlen(data) + + (unsigned)strlen(name) + 128; + const char *dispatch = + "window.dispatchEvent(new CustomEvent('%s',{detail:%s})"; + char *event = (char *)tempalloc.allocate( len ); + if ( snprintf( event, len, dispatch, name, data ) > 0 ) { + web_view->execute( event ); + } + return 1; + } + return 0; + }); + /* @adoc lua @sig stingray.WebApp.render() : nil @des Render and synchronize the web app with the engine render frame. diff --git a/plugin/html5_resources/web_app.lua b/plugin/html5_resources/web_app.lua index f03d439..b9304ff 100644 --- a/plugin/html5_resources/web_app.lua +++ b/plugin/html5_resources/web_app.lua @@ -3,7 +3,7 @@ local web_app -local print_events = true +local test_events = false local app_settings = stingray.Application.settings() or {} local web_app_url = app_settings.web_app_url or "stingray://app/main.html" @@ -25,7 +25,7 @@ function shutdown() stingray.WebApp.destroy(web_app) end -if print_events then +if test_events then function update(dt) stingray.WebApp.update(web_app, dt) local events = stingray.WebApp.consume_events() @@ -33,6 +33,13 @@ if print_events then print( 'name: ' .. events[i].name ) print( 'data: ' .. events[i].data ) end + index = stingray.Keyboard.button_id("x") + local x_pressed = index and stingray.Keyboard.pressed( index ) + if x_pressed then + -- Send an event to the web app + -- + stingray.WebApp.emit(web_app, "eventFire", '"sayhello"' ) + end end else function update(dt) diff --git a/plugin/sample_project/app.html5/app.js b/plugin/sample_project/app.html5/app.js index 6d45b74..debaad6 100644 --- a/plugin/sample_project/app.html5/app.js +++ b/plugin/sample_project/app.html5/app.js @@ -159,6 +159,9 @@ define(require => { Camera.set_local_rotation(app.camera.instance, app.camera.unit, orientation); console.info('Camera created'); + window.addEventListener("eventFire", function( e ) { + console.info( e.detail ); + }); } /** From f1dbf2586a5df1b1f3810f35f74438fd1f58c289 Mon Sep 17 00:00:00 2001 From: Jason Walter Date: Fri, 2 Jun 2017 22:51:05 -0400 Subject: [PATCH 5/5] Forgot paren in string format. --- engine/html5_api_lua.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/html5_api_lua.cpp b/engine/html5_api_lua.cpp index a085ee8..dc30146 100644 --- a/engine/html5_api_lua.cpp +++ b/engine/html5_api_lua.cpp @@ -262,7 +262,7 @@ void load_lua_api(LuaApi* env) unsigned len = (unsigned)strlen(data) + (unsigned)strlen(name) + 128; const char *dispatch = - "window.dispatchEvent(new CustomEvent('%s',{detail:%s})"; + "window.dispatchEvent(new CustomEvent('%s',{detail:%s}));"; char *event = (char *)tempalloc.allocate( len ); if ( snprintf( event, len, dispatch, name, data ) > 0 ) { web_view->execute( event );