From cb87783f2b23421824a90a333fc4764d9f491ec3 Mon Sep 17 00:00:00 2001 From: Joshua Granick Date: Thu, 14 May 2015 16:29:31 -0700 Subject: [PATCH] Add support for application.frameRate --- lime/_backend/flash/FlashApplication.hx | 17 ++++ lime/_backend/html5/HTML5Application.hx | 109 +++++++++++++++++---- lime/_backend/native/NativeApplication.hx | 19 ++++ lime/app/Application.hx | 15 +++ project/include/app/Application.h | 1 + project/src/ExternalInterface.cpp | 10 ++ project/src/backend/sdl/SDLApplication.cpp | 18 +++- project/src/backend/sdl/SDLApplication.h | 1 + 8 files changed, 171 insertions(+), 19 deletions(-) diff --git a/lime/_backend/flash/FlashApplication.hx b/lime/_backend/flash/FlashApplication.hx index 23c46bb1b..1264ad06f 100644 --- a/lime/_backend/flash/FlashApplication.hx +++ b/lime/_backend/flash/FlashApplication.hx @@ -33,6 +33,8 @@ class FlashApplication { this.parent = parent; + Lib.current.stage.frameRate = 60; + AudioManager.init (); } @@ -106,6 +108,7 @@ class FlashApplication { if (config != null) { + setFrameRate (config.fps); var window = new Window (config); var renderer = new Renderer (window); parent.addWindow (window); @@ -152,6 +155,13 @@ class FlashApplication { } + public function getFrameRate ():Float { + + return Lib.current.stage.frameRate; + + } + + private function handleKeyEvent (event:KeyboardEvent):Void { if (parent.window != null) { @@ -314,4 +324,11 @@ class FlashApplication { } + public function setFrameRate (value:Float):Float { + + return Lib.current.stage.frameRate = value; + + } + + } \ No newline at end of file diff --git a/lime/_backend/html5/HTML5Application.hx b/lime/_backend/html5/HTML5Application.hx index 7eda98583..2a7ef0547 100644 --- a/lime/_backend/html5/HTML5Application.hx +++ b/lime/_backend/html5/HTML5Application.hx @@ -20,7 +20,11 @@ import lime.ui.Window; class HTML5Application { - private var cacheTime:Float; + private var currentUpdate:Float; + private var deltaTime:Float; + private var framePeriod:Float; + private var lastUpdate:Float; + private var nextUpdate:Float; private var parent:Application; #if stats private var stats:Dynamic; @@ -31,6 +35,11 @@ class HTML5Application { this.parent = parent; + currentUpdate = 0; + lastUpdate = 0; + nextUpdate = 0; + framePeriod = -1; + AudioManager.init (); } @@ -141,7 +150,7 @@ class HTML5Application { window.requestAnimFrame = window.requestAnimationFrame; "); - cacheTime = Date.now ().getTime (); + lastUpdate = Date.now ().getTime (); handleUpdateEvent (); @@ -150,6 +159,25 @@ class HTML5Application { } + public function getFrameRate ():Float { + + if (framePeriod < 0) { + + return 60; + + } else if (framePeriod == 1000) { + + return 0; + + } else { + + return 1000 / framePeriod; + + } + + } + + private function handleKeyEvent (event:KeyboardEvent):Void { if (parent.window != null) { @@ -189,27 +217,51 @@ class HTML5Application { private function handleUpdateEvent (?__):Void { - #if stats - stats.begin (); - #end + currentUpdate = Date.now ().getTime (); - var currentTime = Date.now ().getTime (); - var deltaTime = currentTime - cacheTime; - cacheTime = currentTime; - - parent.onUpdate.dispatch (Std.int (deltaTime)); - - if (parent.renderer != null) { + if (currentUpdate >= nextUpdate) { - parent.renderer.onRender.dispatch (parent.renderer.context); - parent.renderer.flip (); + #if stats + stats.begin (); + #end + + deltaTime = currentUpdate - lastUpdate; + + parent.onUpdate.dispatch (Std.int (deltaTime)); + + if (parent.renderer != null) { + + parent.renderer.onRender.dispatch (parent.renderer.context); + parent.renderer.flip (); + + } + + #if stats + stats.end (); + #end + + if (framePeriod < 0) { + + nextUpdate = currentUpdate; + nextUpdate = currentUpdate; + + } else { + + nextUpdate = currentUpdate + framePeriod; + + //while (nextUpdate <= currentUpdate) { + // + //nextUpdate += framePeriod; + // + //} + + + } + + lastUpdate = currentUpdate; } - #if stats - stats.end (); - #end - Browser.window.requestAnimationFrame (cast handleUpdateEvent); } @@ -255,4 +307,25 @@ class HTML5Application { } + public function setFrameRate (value:Float):Float { + + if (value >= 60) { + + framePeriod = -1; + + } else if (value > 0) { + + framePeriod = 1000 / value; + + } else { + + framePeriod = 1000; + + } + + return value; + + } + + } \ No newline at end of file diff --git a/lime/_backend/native/NativeApplication.hx b/lime/_backend/native/NativeApplication.hx index f51e5c656..2fb32b32a 100644 --- a/lime/_backend/native/NativeApplication.hx +++ b/lime/_backend/native/NativeApplication.hx @@ -34,12 +34,14 @@ class NativeApplication { public var handle:Dynamic; + private var frameRate:Float; private var parent:Application; public function new (parent:Application):Void { this.parent = parent; + frameRate = 60; AudioManager.init (); @@ -54,6 +56,7 @@ class NativeApplication { if (config != null) { + setFrameRate (config.fps); var window = new Window (config); var renderer = new Renderer (window); parent.addWindow (window); @@ -112,6 +115,13 @@ class NativeApplication { } + public function getFrameRate ():Float { + + return frameRate; + + } + + private function handleGamepadEvent ():Void { if (parent.window != null) { @@ -359,6 +369,14 @@ class NativeApplication { } + public function setFrameRate (value:Float):Float { + + lime_application_set_frame_rate (handle, value); + return frameRate = value; + + } + + private function updateTimer ():Void { if (Timer.sRunningTimers.length > 0) { @@ -409,6 +427,7 @@ class NativeApplication { 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_set_frame_rate = System.load ("lime", "lime_application_set_frame_rate", 2); 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_gamepad_event_manager_register = System.load ("lime", "lime_gamepad_event_manager_register", 2); diff --git a/lime/app/Application.hx b/lime/app/Application.hx index 69e592424..9d1b71115 100644 --- a/lime/app/Application.hx +++ b/lime/app/Application.hx @@ -23,6 +23,7 @@ class Application extends Module { public static var current (default, null):Application; public var config (default, null):Config; + public var frameRate (get, set):Float; public var modules (default, null):Array; /** @@ -589,6 +590,20 @@ class Application extends Module { + @:noCompletion private inline function get_frameRate ():Float { + + return backend.getFrameRate (); + + } + + + @:noCompletion private inline function set_frameRate (value:Float):Float { + + return backend.setFrameRate (value); + + } + + @:noCompletion private inline function get_renderer ():Renderer { return renderers[0]; diff --git a/project/include/app/Application.h b/project/include/app/Application.h index 9439bf8f5..395ba9a47 100644 --- a/project/include/app/Application.h +++ b/project/include/app/Application.h @@ -18,6 +18,7 @@ namespace lime { virtual int Exec () = 0; virtual void Init () = 0; virtual int Quit () = 0; + virtual void SetFrameRate (double frameRate) = 0; virtual bool Update () = 0; diff --git a/project/src/ExternalInterface.cpp b/project/src/ExternalInterface.cpp index f253ad9be..78a102608 100644 --- a/project/src/ExternalInterface.cpp +++ b/project/src/ExternalInterface.cpp @@ -74,6 +74,15 @@ namespace lime { } + value lime_application_set_frame_rate (value application, value frameRate) { + + Application* app = (Application*)(intptr_t)val_float (application); + app->SetFrameRate (val_number (frameRate)); + return alloc_null (); + + } + + value lime_application_update (value application) { Application* app = (Application*)(intptr_t)val_float (application); @@ -992,6 +1001,7 @@ namespace lime { DEFINE_PRIM (lime_application_exec, 1); DEFINE_PRIM (lime_application_init, 1); DEFINE_PRIM (lime_application_quit, 1); + DEFINE_PRIM (lime_application_set_frame_rate, 2); DEFINE_PRIM (lime_application_update, 1); DEFINE_PRIM (lime_audio_load, 1); DEFINE_PRIM (lime_font_get_ascender, 1); diff --git a/project/src/backend/sdl/SDLApplication.cpp b/project/src/backend/sdl/SDLApplication.cpp index 38a765aae..f2f1c1742 100644 --- a/project/src/backend/sdl/SDLApplication.cpp +++ b/project/src/backend/sdl/SDLApplication.cpp @@ -27,6 +27,8 @@ namespace lime { currentApplication = this; + framePeriod = 1000.0 / 60.0; + #ifdef EMSCRIPTEN emscripten_cancel_main_loop (); emscripten_set_main_loop (UpdateFrame, 0, 0); @@ -203,7 +205,6 @@ namespace lime { void SDLApplication::Init () { - framePeriod = 1000.0 / 60.0; active = true; lastUpdate = SDL_GetTicks (); nextUpdate = lastUpdate; @@ -441,6 +442,21 @@ namespace lime { } + void SDLApplication::SetFrameRate (double frameRate) { + + if (frameRate > 0) { + + framePeriod = 1000.0 / frameRate; + + } else { + + framePeriod = 1000.0; + + } + + } + + static SDL_TimerID timerID = 0; bool timerActive = false; bool firstTime = true; diff --git a/project/src/backend/sdl/SDLApplication.h b/project/src/backend/sdl/SDLApplication.h index de48a7e0f..29e1640d2 100644 --- a/project/src/backend/sdl/SDLApplication.h +++ b/project/src/backend/sdl/SDLApplication.h @@ -28,6 +28,7 @@ namespace lime { virtual int Exec (); virtual void Init (); virtual int Quit (); + virtual void SetFrameRate (double frameRate); virtual bool Update (); void RegisterWindow (SDLWindow *window);