From e4914606307827ff682b33ed9ee82aa1112e0825 Mon Sep 17 00:00:00 2001 From: Joshua Granick Date: Mon, 9 Jun 2014 14:44:02 -0700 Subject: [PATCH] Working toward render timing --- lime/app/Application.hx | 33 +++++------ lime/app/IRenderEventListener.hx | 10 ++++ lime/app/IUpdateEventListener.hx | 10 ++++ lime/app/RenderEvent.hx | 31 ++++++++++ lime/app/RenderEventManager.hx | 56 +++++++++++++++++++ lime/app/Renderer.hx | 12 ++++ lime/app/UpdateEvent.hx | 33 +++++++++++ lime/app/UpdateEventManager.hx | 56 +++++++++++++++++++ project/Build.xml | 2 + project/include/app/Application.h | 7 +++ project/include/app/RenderEvent.h | 37 ++++++++++++ project/include/app/Renderer.h | 2 + project/include/app/UpdateEvent.h | 38 +++++++++++++ project/src/ExternalInterface.cpp | 46 ++++++++++++++- project/src/app/RenderEvent.cpp | 43 ++++++++++++++ project/src/app/UpdateEvent.cpp | 47 ++++++++++++++++ project/src/backend/sdl/SDLApplication.cpp | 52 ++++++++++++++--- project/src/backend/sdl/SDLApplication.h | 5 ++ project/src/backend/sdl/SDLRenderer.cpp | 7 +++ project/src/backend/sdl/SDLRenderer.h | 2 + .../src/graphics/opengl/OpenGLExtensions.h | 2 +- 21 files changed, 498 insertions(+), 33 deletions(-) create mode 100644 lime/app/IRenderEventListener.hx create mode 100644 lime/app/IUpdateEventListener.hx create mode 100644 lime/app/RenderEvent.hx create mode 100644 lime/app/RenderEventManager.hx create mode 100644 lime/app/UpdateEvent.hx create mode 100644 lime/app/UpdateEventManager.hx create mode 100644 project/include/app/RenderEvent.h create mode 100644 project/include/app/UpdateEvent.h create mode 100644 project/src/app/RenderEvent.cpp create mode 100644 project/src/app/UpdateEvent.cpp diff --git a/lime/app/Application.hx b/lime/app/Application.hx index 075ee7aeb..11a615773 100644 --- a/lime/app/Application.hx +++ b/lime/app/Application.hx @@ -16,15 +16,17 @@ import lime.ui.WindowEvent; import lime.system.System; -class Application implements IKeyEventListener implements IMouseEventListener implements ITouchEventListener implements IWindowEventListener { +class Application implements IKeyEventListener implements IMouseEventListener implements IRenderEventListener implements ITouchEventListener implements IUpdateEventListener implements IWindowEventListener { public var handle:Dynamic; + private var lastUpdate:Int; + public function new () { - + lastUpdate = 0; } @@ -32,17 +34,21 @@ class Application implements IKeyEventListener implements IMouseEventListener im public function create (config:Config) { #if (cpp || neko) - handle = lime_application_create (); + handle = lime_application_create (null); #end new KeyEventManager (); new MouseEventManager (); + new RenderEventManager (); new TouchEventManager (); + new UpdateEventManager (); new WindowEventManager (); KeyEventManager.addEventListener (this); MouseEventManager.addEventListener (this); + RenderEventManager.addEventListener (this); TouchEventManager.addEventListener (this); + UpdateEventManager.addEventListener (this); WindowEventManager.addEventListener (this); var window = new Window (this); @@ -65,32 +71,19 @@ class Application implements IKeyEventListener implements IMouseEventListener im public function onMouseDown (event:MouseEvent):Void {} public function onMouseMove (event:MouseEvent):Void {} public function onMouseUp (event:MouseEvent):Void {} + public function onRender (event:RenderEvent):Void {} public function onTouchEnd (event:TouchEvent):Void {} public function onTouchMove (event:TouchEvent):Void {} public function onTouchStart (event:TouchEvent):Void {} + public function onUpdate (event:UpdateEvent):Void {} public function onWindowActivate (event:WindowEvent):Void {} public function onWindowDeactivate (event:WindowEvent):Void {} - - public function render ():Void { - - - - } - - - public function update ():Void { - - - - } - - - #if (cpp || neko) - private static var lime_application_create = System.load ("lime", "lime_application_create", 0); + 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_get_ticks = System.load ("lime", "lime_application_get_ticks", 0); #end diff --git a/lime/app/IRenderEventListener.hx b/lime/app/IRenderEventListener.hx new file mode 100644 index 000000000..490e24388 --- /dev/null +++ b/lime/app/IRenderEventListener.hx @@ -0,0 +1,10 @@ +package lime.app; + + +interface IRenderEventListener { + + + function onRender (event:RenderEvent):Void; + + +} \ No newline at end of file diff --git a/lime/app/IUpdateEventListener.hx b/lime/app/IUpdateEventListener.hx new file mode 100644 index 000000000..a877af6c2 --- /dev/null +++ b/lime/app/IUpdateEventListener.hx @@ -0,0 +1,10 @@ +package lime.app; + + +interface IUpdateEventListener { + + + function onUpdate (event:UpdateEvent):Void; + + +} \ No newline at end of file diff --git a/lime/app/RenderEvent.hx b/lime/app/RenderEvent.hx new file mode 100644 index 000000000..690bd0bfd --- /dev/null +++ b/lime/app/RenderEvent.hx @@ -0,0 +1,31 @@ +package lime.app; + + +class RenderEvent { + + + public var type:RenderEventType; + + + public function new (type:RenderEventType = null) { + + this.type = type; + + } + + + public function clone ():RenderEvent { + + return new RenderEvent (type); + + } + + +} + + +@:enum abstract RenderEventType(Int) { + + var RENDER = 0; + +} \ No newline at end of file diff --git a/lime/app/RenderEventManager.hx b/lime/app/RenderEventManager.hx new file mode 100644 index 000000000..6193a105f --- /dev/null +++ b/lime/app/RenderEventManager.hx @@ -0,0 +1,56 @@ +package lime.app; + + +import lime.system.System; + + +class RenderEventManager { + + + private static var instance:RenderEventManager; + + private var listeners:Array; + + + public function new () { + + listeners = new Array (); + instance = this; + + #if (cpp || neko) + lime_render_event_manager_register (handleEvent, new RenderEvent ()); + #end + + } + + + public static function addEventListener (listener:IRenderEventListener):Void { + + if (instance != null) { + + instance.listeners.push (listener); + + } + + } + + + private function handleEvent (event:RenderEvent):Void { + + var event = event.clone (); + + for (listener in listeners) { + + listener.onRender (event); + + } + + } + + + #if (cpp || neko) + private static var lime_render_event_manager_register = System.load ("lime", "lime_render_event_manager_register", 2); + #end + + +} \ No newline at end of file diff --git a/lime/app/Renderer.hx b/lime/app/Renderer.hx index a8b8194c4..4e8b2c3f5 100644 --- a/lime/app/Renderer.hx +++ b/lime/app/Renderer.hx @@ -9,6 +9,8 @@ class Renderer { public var handle:Dynamic; + private static var instance:Renderer; + public function new (window:Window) { @@ -16,11 +18,21 @@ class Renderer { handle = lime_renderer_create (window.handle); #end + instance = this; + + } + + + public static function flip ():Void { + + lime_renderer_flip (instance.handle); + } #if (cpp || neko) private static var lime_renderer_create = System.load ("lime", "lime_renderer_create", 1); + private static var lime_renderer_flip = System.load ("lime", "lime_renderer_flip", 1); #end diff --git a/lime/app/UpdateEvent.hx b/lime/app/UpdateEvent.hx new file mode 100644 index 000000000..797a21c32 --- /dev/null +++ b/lime/app/UpdateEvent.hx @@ -0,0 +1,33 @@ +package lime.app; + + +class UpdateEvent { + + + public var deltaTime:Int; + public var type:UpdateEventType; + + + public function new (type:UpdateEventType = null, deltaTime:Int = 0) { + + this.type = type; + this.deltaTime = deltaTime; + + } + + + public function clone ():UpdateEvent { + + return new UpdateEvent (type, deltaTime); + + } + + +} + + +@:enum abstract UpdateEventType(Int) { + + var UPDATE = 0; + +} \ No newline at end of file diff --git a/lime/app/UpdateEventManager.hx b/lime/app/UpdateEventManager.hx new file mode 100644 index 000000000..4bba06dec --- /dev/null +++ b/lime/app/UpdateEventManager.hx @@ -0,0 +1,56 @@ +package lime.app; + + +import lime.system.System; + + +class UpdateEventManager { + + + private static var instance:UpdateEventManager; + + private var listeners:Array; + + + public function new () { + + listeners = new Array (); + instance = this; + + #if (cpp || neko) + lime_update_event_manager_register (handleEvent, new UpdateEvent ()); + #end + + } + + + public static function addEventListener (listener:IUpdateEventListener):Void { + + if (instance != null) { + + instance.listeners.push (listener); + + } + + } + + + private function handleEvent (event:UpdateEvent):Void { + + var event = event.clone (); + + for (listener in listeners) { + + listener.onUpdate (event); + + } + + } + + + #if (cpp || neko) + private static var lime_update_event_manager_register = System.load ("lime", "lime_update_event_manager_register", 2); + #end + + +} \ No newline at end of file diff --git a/project/Build.xml b/project/Build.xml index 7b72eb652..c1bb71481 100644 --- a/project/Build.xml +++ b/project/Build.xml @@ -48,6 +48,8 @@ + + diff --git a/project/include/app/Application.h b/project/include/app/Application.h index 736b52ded..3f5d5ee1a 100644 --- a/project/include/app/Application.h +++ b/project/include/app/Application.h @@ -2,6 +2,9 @@ #define LIME_APP_APPLICATION_H +#include + + namespace lime { @@ -10,6 +13,10 @@ namespace lime { public: + static double GetTicks (); + + static AutoGCRoot* callback; + virtual int Exec () = 0; diff --git a/project/include/app/RenderEvent.h b/project/include/app/RenderEvent.h new file mode 100644 index 000000000..534c41416 --- /dev/null +++ b/project/include/app/RenderEvent.h @@ -0,0 +1,37 @@ +#ifndef LIME_APP_RENDER_EVENT_H +#define LIME_APP_RENDER_EVENT_H + + +#include + + +namespace lime { + + + enum RenderEventType { + + RENDER + + }; + + + class RenderEvent { + + public: + + static AutoGCRoot* callback; + static AutoGCRoot* eventObject; + + RenderEvent (); + + static void Dispatch (RenderEvent* event); + + RenderEventType type; + + }; + + +} + + +#endif \ No newline at end of file diff --git a/project/include/app/Renderer.h b/project/include/app/Renderer.h index 38566df28..873fa8d07 100644 --- a/project/include/app/Renderer.h +++ b/project/include/app/Renderer.h @@ -13,6 +13,8 @@ namespace lime { public: + virtual void Flip () = 0; + Window* currentWindow; diff --git a/project/include/app/UpdateEvent.h b/project/include/app/UpdateEvent.h new file mode 100644 index 000000000..6cf055342 --- /dev/null +++ b/project/include/app/UpdateEvent.h @@ -0,0 +1,38 @@ +#ifndef LIME_APP_UPDATE_EVENT_H +#define LIME_APP_UPDATE_EVENT_H + + +#include + + +namespace lime { + + + enum UpdateEventType { + + UPDATE + + }; + + + class UpdateEvent { + + public: + + static AutoGCRoot* callback; + static AutoGCRoot* eventObject; + + UpdateEvent (); + + static void Dispatch (UpdateEvent* event); + + int deltaTime; + UpdateEventType type; + + }; + + +} + + +#endif \ No newline at end of file diff --git a/project/src/ExternalInterface.cpp b/project/src/ExternalInterface.cpp index 992d480b7..cd9060139 100644 --- a/project/src/ExternalInterface.cpp +++ b/project/src/ExternalInterface.cpp @@ -9,8 +9,10 @@ #include #include -#include #include +#include +#include +#include #include #include #include @@ -20,9 +22,10 @@ namespace lime { - value lime_application_create () { + value lime_application_create (value callback) { Application* app = CreateApplication (); + Application::callback = new AutoGCRoot (callback); return alloc_int ((intptr_t)app); } @@ -36,6 +39,13 @@ namespace lime { } + value lime_application_get_ticks (value application) { + + return alloc_float (Application::GetTicks ()); + + } + + value lime_key_event_manager_register (value callback, value eventObject) { KeyEvent::callback = new AutoGCRoot (callback); @@ -80,6 +90,15 @@ namespace lime { } + value lime_render_event_manager_register (value callback, value eventObject) { + + RenderEvent::callback = new AutoGCRoot (callback); + RenderEvent::eventObject = new AutoGCRoot (eventObject); + return alloc_null (); + + } + + value lime_renderer_create (value window) { Renderer* renderer = CreateRenderer ((Window*)(intptr_t)val_int (window)); @@ -88,6 +107,14 @@ namespace lime { } + value lime_renderer_flip (value renderer) { + + ((Renderer*)(intptr_t)renderer)->Flip (); + return alloc_null (); + + } + + value lime_touch_event_manager_register (value callback, value eventObject) { TouchEvent::callback = new AutoGCRoot (callback); @@ -97,6 +124,15 @@ namespace lime { } + value lime_update_event_manager_register (value callback, value eventObject) { + + UpdateEvent::callback = new AutoGCRoot (callback); + UpdateEvent::eventObject = new AutoGCRoot (eventObject); + return alloc_null (); + + } + + value lime_window_create (value application) { Window* window = CreateWindow ((Application*)(intptr_t)val_int (application)); @@ -114,14 +150,18 @@ namespace lime { } - DEFINE_PRIM (lime_application_create, 0); + DEFINE_PRIM (lime_application_create, 1); DEFINE_PRIM (lime_application_exec, 1); + DEFINE_PRIM (lime_application_get_ticks, 0); DEFINE_PRIM (lime_key_event_manager_register, 2); DEFINE_PRIM (lime_lzma_encode, 1); DEFINE_PRIM (lime_lzma_decode, 1); DEFINE_PRIM (lime_mouse_event_manager_register, 2); DEFINE_PRIM (lime_renderer_create, 1); + DEFINE_PRIM (lime_renderer_flip, 1); + DEFINE_PRIM (lime_render_event_manager_register, 2); DEFINE_PRIM (lime_touch_event_manager_register, 2); + DEFINE_PRIM (lime_update_event_manager_register, 2); DEFINE_PRIM (lime_window_create, 1); DEFINE_PRIM (lime_window_event_manager_register, 2); diff --git a/project/src/app/RenderEvent.cpp b/project/src/app/RenderEvent.cpp new file mode 100644 index 000000000..ea90e8435 --- /dev/null +++ b/project/src/app/RenderEvent.cpp @@ -0,0 +1,43 @@ +#include +#include + + +namespace lime { + + + AutoGCRoot* RenderEvent::callback = 0; + AutoGCRoot* RenderEvent::eventObject = 0; + + //static int id_type; + //static bool init = false; + + + RenderEvent::RenderEvent () { + + type = RENDER; + + } + + + void RenderEvent::Dispatch (RenderEvent* event) { + + if (RenderEvent::callback) { + + //if (!init) { + + //id_type = val_id ("type"); + + //} + + value object = (RenderEvent::eventObject ? RenderEvent::eventObject->get () : alloc_empty_object ()); + + //alloc_field (object, id_type, alloc_int (event->type)); + + val_call1 (RenderEvent::callback->get (), object); + + } + + } + + +} \ No newline at end of file diff --git a/project/src/app/UpdateEvent.cpp b/project/src/app/UpdateEvent.cpp new file mode 100644 index 000000000..da7ee3c63 --- /dev/null +++ b/project/src/app/UpdateEvent.cpp @@ -0,0 +1,47 @@ +#include +#include + + +namespace lime { + + + AutoGCRoot* UpdateEvent::callback = 0; + AutoGCRoot* UpdateEvent::eventObject = 0; + + static int id_deltaTime; + //static int id_type; + static bool init = false; + + + UpdateEvent::UpdateEvent () { + + deltaTime = 0; + type = UPDATE; + + } + + + void UpdateEvent::Dispatch (UpdateEvent* event) { + + if (UpdateEvent::callback) { + + if (!init) { + + id_deltaTime = val_id ("deltaTime"); + //id_type = val_id ("type"); + + } + + value object = (UpdateEvent::eventObject ? UpdateEvent::eventObject->get () : alloc_empty_object ()); + + alloc_field (object, id_deltaTime, alloc_int (event->deltaTime)); + //alloc_field (object, id_type, alloc_int (event->type)); + + val_call1 (UpdateEvent::callback->get (), object); + + } + + } + + +} \ No newline at end of file diff --git a/project/src/backend/sdl/SDLApplication.cpp b/project/src/backend/sdl/SDLApplication.cpp index 18974bec2..556dffe4a 100644 --- a/project/src/backend/sdl/SDLApplication.cpp +++ b/project/src/backend/sdl/SDLApplication.cpp @@ -4,6 +4,16 @@ namespace lime { + AutoGCRoot* Application::callback = 0; + + + double Application::GetTicks () { + + return SDL_GetTicks (); + + } + + SDLApplication::SDLApplication () { SDL_Init (SDL_INIT_VIDEO); @@ -22,23 +32,43 @@ namespace lime { SDL_Event event; active = true; + bool firstTime = true; + lastUpdate = SDL_GetTicks (); + Uint32 currentUpdate = 0; + int deltaTime = 0; while (active) { - while (active && SDL_WaitEvent (&event)) { - - HandleEvent (&event); - event.type = -1; - if (!active) break; - - } + event.type = -1; - while (active && SDL_PollEvent (&event)) { + while (active && (firstTime || SDL_WaitEvent (&event))) { + + firstTime = false; HandleEvent (&event); event.type = -1; if (!active) break; + while (active && SDL_PollEvent (&event)) { + + HandleEvent (&event); + event.type = -1; + if (!active) break; + + } + + currentUpdate = SDL_GetTicks (); + deltaTime = currentUpdate - lastUpdate; + + if (deltaTime > 16) { + + updateEvent.deltaTime = deltaTime; + UpdateEvent::Dispatch (&updateEvent); + + RenderEvent::Dispatch (&renderEvent); + + } + } } @@ -92,7 +122,11 @@ namespace lime { ProcessWindowEvent (event); break; - case SDL_WINDOWEVENT_EXPOSED: /*poll*/ break; + case SDL_WINDOWEVENT_EXPOSED: + + RenderEvent::Dispatch (&renderEvent); + break; + case SDL_WINDOWEVENT_SIZE_CHANGED: /*resize*/ break; case SDL_WINDOWEVENT_FOCUS_GAINED: /*focus in*/ break; case SDL_WINDOWEVENT_FOCUS_LOST: /*focus out*/ break; diff --git a/project/src/backend/sdl/SDLApplication.h b/project/src/backend/sdl/SDLApplication.h index 8e140fc89..4033c972b 100644 --- a/project/src/backend/sdl/SDLApplication.h +++ b/project/src/backend/sdl/SDLApplication.h @@ -4,6 +4,8 @@ #include #include +#include +#include #include #include #include @@ -32,8 +34,11 @@ namespace lime { bool active; KeyEvent keyEvent; + Uint32 lastUpdate; MouseEvent mouseEvent; + RenderEvent renderEvent; TouchEvent touchEvent; + UpdateEvent updateEvent; WindowEvent windowEvent; }; diff --git a/project/src/backend/sdl/SDLRenderer.cpp b/project/src/backend/sdl/SDLRenderer.cpp index 8b886be25..80a30cf30 100644 --- a/project/src/backend/sdl/SDLRenderer.cpp +++ b/project/src/backend/sdl/SDLRenderer.cpp @@ -23,6 +23,13 @@ namespace lime { } + void SDLRenderer::Flip () { + + SDL_RenderPresent (sdlRenderer); + + } + + Renderer* CreateRenderer (Window* window) { return new SDLRenderer (window); diff --git a/project/src/backend/sdl/SDLRenderer.h b/project/src/backend/sdl/SDLRenderer.h index 679ae46e4..67178be8a 100644 --- a/project/src/backend/sdl/SDLRenderer.h +++ b/project/src/backend/sdl/SDLRenderer.h @@ -16,6 +16,8 @@ namespace lime { SDLRenderer (Window* window); ~SDLRenderer (); + virtual void Flip (); + SDL_Renderer* sdlRenderer; }; diff --git a/project/src/graphics/opengl/OpenGLExtensions.h b/project/src/graphics/opengl/OpenGLExtensions.h index 48562cd67..80250eec2 100644 --- a/project/src/graphics/opengl/OpenGLExtensions.h +++ b/project/src/graphics/opengl/OpenGLExtensions.h @@ -15,7 +15,7 @@ #ifdef DECLARE_EXTENSION -namespace lime { extern void *OpenGLBindings::handle; } +namespace lime { void *OpenGLBindings::handle; } #define OGL_EXT(func,ret,args) \ namespace lime { ret (CALLING_CONVENTION *func)args; }