diff --git a/pkg/ant.hwi/service/bgfx.lua b/pkg/ant.hwi/service/bgfx.lua index 0fd1851b37..ada93b5ddf 100644 --- a/pkg/ant.hwi/service/bgfx.lua +++ b/pkg/ant.hwi/service/bgfx.lua @@ -347,8 +347,8 @@ function S.maxfps(v) maxfps = v end if platform.os == "ios" then - local ServiceWindow = ltask.queryservice "ant.window|ios" - ltask.call(ServiceWindow, "maxfps", maxfps) + local ServiceWindow = ltask.queryservice "ant.window|window" + ltask.call(ServiceWindow, "set_maxfps", maxfps) end return maxfps end diff --git a/pkg/ant.window/service/ios.lua b/pkg/ant.window/service/ios.lua index 8447d537d9..b6770cf908 100644 --- a/pkg/ant.window/service/ios.lua +++ b/pkg/ant.window/service/ios.lua @@ -4,18 +4,11 @@ local window = require "window.ios" local scheduling = exclusive.scheduling() local SCHEDULE_SUCCESS = 3 -local CALL = false + local function update() - ltask.wakeup "update" repeat scheduling() until ltask.schedule_message() ~= SCHEDULE_SUCCESS - while CALL do - exclusive.sleep(1) - repeat - scheduling() - until ltask.schedule_message() ~= SCHEDULE_SUCCESS - end end window.init({}, update) ltask.fork(function() @@ -24,8 +17,4 @@ ltask.fork(function() end) local S = {} - -function S.maxfps(fps) -end - return S diff --git a/pkg/ant.window/service/window.lua b/pkg/ant.window/service/window.lua index c47d495536..7930773c33 100644 --- a/pkg/ant.window/service/window.lua +++ b/pkg/ant.window/service/window.lua @@ -1,28 +1,191 @@ -local platform = require "bee.platform" -local world_instance = require "world_instance" +local ltask = require "ltask" +local bgfx = require "bgfx" +local window = require "window" +local assetmgr = import_package "ant.asset" +local audio = import_package "ant.audio" +local new_world = import_package "ant.world".new_world +local rhwi = import_package "ant.hwi" -world_instance.init(...) +rhwi.init_bgfx() + +local ServiceRmlUi +ltask.fork(function () + ServiceRmlUi = ltask.uniqueservice("ant.rmlui|rmlui", ltask.self()) +end) + +local world +local WillReboot +local initargs = ... + +local WindowQueue = {} +local WindowQuit +local WindowToken = {} +local WindowEvent = {} + +local function reboot(args) + local config = world.args + config.REBOOT = true + config.ecs = args + world:pipeline_exit() + world = new_world(config) + world:pipeline_init() +end + +local function render(init, args, initialized) + local config = { + ecs = args, + window = init.window, + nwh = init.nwh, + context = init.context, + width = init.w, + height = init.h, + } + rhwi.init { + window = config.window, + nwh = config.nwh, + context = config.context, + w = config.width, + h = config.height, + } + rhwi.set_profie(false) + bgfx.encoder_create "world" + bgfx.encoder_init() + assetmgr.init() + bgfx.encoder_begin() + world = new_world(config) + world:dispatch_message { + type = "set_viewport", + viewport = { + x = 0, + y = 0, + w = config.width, + h = config.height, + }, + } + world:dispatch_message { type = "update" } + world:pipeline_init() + bgfx.encoder_end() + + ltask.wakeup(initialized) + initialized = nil + + while true do + window.peek_message() + if #WindowQueue > 0 then + ltask.wakeup(WindowToken) + end + world:dispatch_message { type = "update" } + if WindowQuit then + break + end + bgfx.encoder_begin() + if WillReboot then + reboot(WillReboot) + WillReboot = nil + end + world:pipeline_update() + bgfx.encoder_end() + audio.frame() + world._frametime = bgfx.encoder_frame() + end + if ServiceRmlUi then + ltask.send(ServiceRmlUi, "shutdown") + ServiceRmlUi = nil + end + world:pipeline_exit() + world = nil + bgfx.encoder_destroy() + rhwi.shutdown() + ltask.wakeup(WindowQuit) +end + +function WindowEvent.init(m) + local initialized = {} + ltask.fork(render, m, initargs, initialized) + ltask.wait(initialized) +end + +function WindowEvent.recreate(m) + bgfx.set_platform_data { + nwh = m.nwh + } + world:dispatch_message { + type = "size", + w = m.w, + h = m.h, + } +end + +local PAUSE +function WindowEvent.suspend(m) + if m.what == "will_suspend" then + bgfx.pause() + PAUSE = true + ltask.fork(function () + local thread = require "bee.thread" + while PAUSE do + window.peek_message() + if #WindowQueue > 0 then + ltask.wakeup(WindowToken) + ltask.sleep(0) + else + thread.sleep(0.01) + end + end + end) + elseif m.what == "did_resume" then + bgfx.continue() + PAUSE = nil + end +end + +function WindowEvent.exit() + WindowQuit = {} + ltask.wait(WindowQuit) + print "exit" + ltask.multi_wakeup "quit" +end + +ltask.fork(function () + while not WindowQuit do + while true do + local msg = table.remove(WindowQueue, 1) + if not msg then + break + end + local f = WindowEvent[msg.type] + if f then + f(msg) + elseif not world:dispatch_imgui(msg) then + world:dispatch_message(msg) + end + end + ltask.wait(WindowToken) + end +end) + +local function table_append(t, a) + table.move(a, 1, #a, #t+1, t) +end local S = {} function S.reboot(args) - world_instance.reboot(args) + WillReboot = args end function S.wait() - world_instance.wait() + ltask.multi_wait "quit" end function S.msg(messages) - world_instance.message(messages) -end - -if platform.os == "ios" then - return S + local wakeup = #WindowQueue == 0 + table_append(WindowQueue, messages) + if wakeup then + ltask.wakeup(WindowToken) + end end -local window = require "window" - function S.set_cursor(cursor) window.set_cursor(cursor) end @@ -31,10 +194,10 @@ function S.set_title(title) window.set_title(title) end -function S.maxfps(fps) - if window.maxfps then - window.maxfps(fps) - end +function S.set_maxfps(fps) + window.set_maxfps(fps) end +window.init(WindowQueue, initargs.window_size) + return S diff --git a/pkg/ant.window/src/luabind.cpp b/pkg/ant.window/src/luabind.cpp index ff9ea139a9..fc42fb9929 100644 --- a/pkg/ant.window/src/luabind.cpp +++ b/pkg/ant.window/src/luabind.cpp @@ -7,24 +7,12 @@ static bee::zstring_view lua_checkstrview(lua_State* L, int idx) { return { str, sz }; } -#if !defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) -static int MessageFetch(lua_State* L) { - lua_seti(L, 1, luaL_len(L, 1)+1); - lua_settop(L, 1); - return 0; -} -#endif - static int init(lua_State *L) { lua_State* messageL = lua_newthread(L); lua_setfield(L, LUA_REGISTRYINDEX, "ANT_WINDOW_CONTEXT"); lua_pushvalue(L, 1); lua_xmove(L, messageL, 1); -#if !defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) - window_message_set_fetch_func(MessageFetch); -#endif - const char* size = lua_tostring(L, 2); bool ok = window_init(messageL, size); if (!ok) { @@ -55,9 +43,9 @@ static int set_title(lua_State* L) { return 0; } -static int maxfps(lua_State *L) { +static int set_maxfps(lua_State *L) { float fps = (float)luaL_checknumber(L, 1); - window_maxfps(fps); + window_set_maxfps(fps); return 0; } @@ -70,7 +58,7 @@ luaopen_window(lua_State *L) { { "peek_message", peek_message }, { "set_cursor", set_cursor }, { "set_title", set_title }, - { "maxfps", maxfps }, + { "set_maxfps", set_maxfps }, { NULL, NULL }, }; luaL_newlib(L, l); diff --git a/pkg/ant.window/src/platform/ios/ios_window.mm b/pkg/ant.window/src/platform/ios/ios_window.mm index 6868da0a0f..83f0b21190 100644 --- a/pkg/ant.window/src/platform/ios/ios_window.mm +++ b/pkg/ant.window/src/platform/ios/ios_window.mm @@ -228,10 +228,9 @@ void select(std::function handler) { static MessageQueue g_msqueue; -static int MessageFetch(lua_State* L) { +static void MessageFetch(lua_State* L) { g_msqueue.push(seri_pack(L, 0, NULL)); lua_settop(L, 0); - return 0; } void loopwindow_init(struct ant_window_callback* cb) { @@ -285,7 +284,7 @@ void window_set_cursor(int cursor) { void window_set_title(bee::zstring_view title) { } -void window_maxfps(float fps) { +void window_set_maxfps(float fps) { //TODO //if (global_window) { // [global_window maxfps: fps]; diff --git a/pkg/ant.window/src/platform/ios/luabind.cpp b/pkg/ant.window/src/platform/ios/luabind.cpp index c606e4a70c..b3b113543d 100644 --- a/pkg/ant.window/src/platform/ios/luabind.cpp +++ b/pkg/ant.window/src/platform/ios/luabind.cpp @@ -48,20 +48,12 @@ lmainloop(lua_State *L) { return 0; } -static int -lmaxfps(lua_State *L) { - float fps = (float)luaL_checknumber(L, 1); - window_maxfps(fps); - return 0; -} - extern "C" int luaopen_window_ios(lua_State *L) { luaL_checkversion(L); luaL_Reg l[] = { { "init", linit }, { "mainloop", lmainloop }, - { "maxfps", lmaxfps }, { NULL, NULL }, }; luaL_newlib(L, l); diff --git a/pkg/ant.window/src/platform/osx/osx_window.mm b/pkg/ant.window/src/platform/osx/osx_window.mm index 631f37dd22..0a07ca7a66 100644 --- a/pkg/ant.window/src/platform/osx/osx_window.mm +++ b/pkg/ant.window/src/platform/osx/osx_window.mm @@ -399,5 +399,5 @@ void window_set_title(bee::zstring_view title) { //TODO } -void window_maxfps(float fps) { +void window_set_maxfps(float fps) { } diff --git a/pkg/ant.window/src/platform/windows/win32_window.cpp b/pkg/ant.window/src/platform/windows/win32_window.cpp index 348cc6ee3e..4b5eaa6597 100644 --- a/pkg/ant.window/src/platform/windows/win32_window.cpp +++ b/pkg/ant.window/src/platform/windows/win32_window.cpp @@ -612,5 +612,5 @@ void window_set_title(bee::zstring_view title) { ::SetWindowTextW(G.hWnd, bee::win::u2w(title).c_str()); } -void window_maxfps(float fps) { +void window_set_maxfps(float fps) { } diff --git a/pkg/ant.window/src/window.cpp b/pkg/ant.window/src/window.cpp index 1d2f60686f..dd97726493 100644 --- a/pkg/ant.window/src/window.cpp +++ b/pkg/ant.window/src/window.cpp @@ -194,8 +194,13 @@ static void push_message_args(lua_State*L, K&& k, V&& v, Args&&... args) { } } -static lua_CFunction MessageFetch = NULL; -void window_message_set_fetch_func(lua_CFunction func) { +static void DefaultMessageFetch(lua_State* L) { + lua_seti(L, 1, luaL_len(L, 1)+1); + lua_settop(L, 1); +} + +static void (*MessageFetch)(lua_State*) = DefaultMessageFetch; +void window_message_set_fetch_func(void (*func)(lua_State*)) { MessageFetch = func; } diff --git a/pkg/ant.window/src/window.h b/pkg/ant.window/src/window.h index 8682c6f206..239a71991c 100644 --- a/pkg/ant.window/src/window.h +++ b/pkg/ant.window/src/window.h @@ -16,9 +16,9 @@ void window_close(); bool window_peek_message(); void window_set_cursor(int cursor); void window_set_title(bee::zstring_view title); -void window_maxfps(float fps); +void window_set_maxfps(float fps); -void window_message_set_fetch_func(int (*func)(lua_State*)); +void window_message_set_fetch_func(void (*func)(lua_State*)); void window_message_init(lua_State* L, void* window, void* nwh, void* context, int w, int h); void window_message_recreate(lua_State* L, void* window, void* nwh, void* context, int w, int h); void window_message_exit(lua_State* L); diff --git a/pkg/ant.window/world_instance.lua b/pkg/ant.window/world_instance.lua deleted file mode 100644 index 50b4e7d501..0000000000 --- a/pkg/ant.window/world_instance.lua +++ /dev/null @@ -1,196 +0,0 @@ -local ltask = require "ltask" -local bgfx = require "bgfx" -local platform = require "bee.platform" -local assetmgr = import_package "ant.asset" -local audio = import_package "ant.audio" -local new_world = import_package "ant.world".new_world -local rhwi = import_package "ant.hwi" - -local window = require "window" - -rhwi.init_bgfx() - -local ServiceRmlUi -ltask.fork(function () - ServiceRmlUi = ltask.uniqueservice("ant.rmlui|rmlui", ltask.self()) -end) - -local world -local WillReboot -local initargs - -local WindowQueue = {} -local WindowQuit -local WindowToken = {} -local WindowEvent = {} - -local function reboot(args) - local config = world.args - config.REBOOT = true - config.ecs = args - world:pipeline_exit() - world = new_world(config) - world:pipeline_init() -end - -local function render(init, args, initialized) - local config = { - ecs = args, - window = init.window, - nwh = init.nwh, - context = init.context, - width = init.w, - height = init.h, - } - rhwi.init { - window = config.window, - nwh = config.nwh, - context = config.context, - w = config.width, - h = config.height, - } - rhwi.set_profie(false) - bgfx.encoder_create "world" - bgfx.encoder_init() - assetmgr.init() - bgfx.encoder_begin() - world = new_world(config) - world:dispatch_message { - type = "set_viewport", - viewport = { - x = 0, - y = 0, - w = config.width, - h = config.height, - }, - } - world:dispatch_message { type = "update" } - world:pipeline_init() - bgfx.encoder_end() - - ltask.wakeup(initialized) - initialized = nil - - while true do - window.peek_message() - if #WindowQueue > 0 then - ltask.wakeup(WindowToken) - end - world:dispatch_message { type = "update" } - if WindowQuit then - break - end - bgfx.encoder_begin() - if WillReboot then - reboot(WillReboot) - WillReboot = nil - end - world:pipeline_update() - bgfx.encoder_end() - audio.frame() - world._frametime = bgfx.encoder_frame() - end - if ServiceRmlUi then - ltask.send(ServiceRmlUi, "shutdown") - ServiceRmlUi = nil - end - world:pipeline_exit() - world = nil - bgfx.encoder_destroy() - rhwi.shutdown() - ltask.wakeup(WindowQuit) -end - -function WindowEvent.init(m) - local initialized = {} - ltask.fork(render, m, initargs, initialized) - ltask.wait(initialized) -end - -function WindowEvent.recreate(m) - bgfx.set_platform_data { - nwh = m.nwh - } - world:dispatch_message { - type = "size", - w = m.w, - h = m.h, - } -end - -local PAUSE -function WindowEvent.suspend(m) - if m.what == "will_suspend" then - bgfx.pause() - PAUSE = true - ltask.fork(function () - local thread = require "bee.thread" - while PAUSE do - window.peek_message() - if #WindowQueue > 0 then - ltask.wakeup(WindowToken) - ltask.sleep(0) - else - thread.sleep(0.01) - end - end - end) - elseif m.what == "did_resume" then - bgfx.continue() - PAUSE = nil - end -end - -function WindowEvent.exit() - WindowQuit = {} - ltask.wait(WindowQuit) - print "exit" - ltask.multi_wakeup "quit" -end - -ltask.fork(function () - while not WindowQuit do - while true do - local msg = table.remove(WindowQueue, 1) - if not msg then - break - end - local f = WindowEvent[msg.type] - if f then - f(msg) - elseif not world:dispatch_imgui(msg) then - world:dispatch_message(msg) - end - end - ltask.wait(WindowToken) - end -end) - -local m = {} - -function m.init(args) - initargs = args - window.init(WindowQueue, initargs.window_size) -end - -function m.reboot(args) - WillReboot = args -end - -local function table_append(t, a) - table.move(a, 1, #a, #t+1, t) -end - -function m.message(messages) - local wakeup = #WindowQueue == 0 - table_append(WindowQueue, messages) - if wakeup then - ltask.wakeup(WindowToken) - end -end - -function m.wait() - ltask.multi_wait "quit" -end - -return m