changeset 694:ca1fcb96907d

Added pre- and post-rendering hooks for executing custom rendering code. * The functions FIFE::Engine.register(Pre|Post)RenderingHook are used to register custom rendering hooks to execute before and after thepredefined rendering functions in the main loop. * The rendering hook registration functions are also exposed to the Python bindings and accept any native C or Python functions.
author M. George Hansen <technopolitica@gmail.com>
date Fri, 10 Jun 2011 23:35:30 -1000
parents 9dce3dbd4fa9
children 47d58c7a95d7
files engine/core/controller/engine.cpp engine/core/controller/engine.h engine/core/controller/engine.i engine/core/eventchannel/eventmanager.cpp
diffstat 4 files changed, 85 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/engine/core/controller/engine.cpp	Tue Apr 19 16:13:37 2011 +0000
+++ b/engine/core/controller/engine.cpp	Fri Jun 10 23:35:30 2011 -1000
@@ -107,6 +107,8 @@
 		m_gui_graphics(0),
 		m_logmanager(0),
 		m_cursor(0),
+		m_prerender_callback(0),
+		m_postrender_callback(0),
 		m_settings(),
 		m_devcaps(),
 		m_changelisteners() {
@@ -363,11 +365,13 @@
 		m_eventmanager->processEvents();
 		m_renderbackend->startFrame();
 		m_timemanager->update();
-
 		if (m_model->getNumMaps() == 0) {
 			m_renderbackend->clearBackBuffer();
 		}
 
+		if (m_prerender_callback != 0) {
+			(*m_prerender_callback)();
+		}
 		m_model->update();
 #ifdef HAVE_OPENGL
 		if (m_settings.getLightingModel() == 1) {
@@ -376,6 +380,9 @@
 #endif
 		m_guimanager->turn();
 		m_cursor->draw();
+		if (m_postrender_callback != 0) {
+			(*m_postrender_callback)();
+		}
 #ifdef HAVE_OPENGL
 		if (m_settings.getLightingModel() == 1) {
 			m_renderbackend->enableLighting();
@@ -384,6 +391,14 @@
 		m_renderbackend->endFrame();
 	}
 
+	void Engine::registerPreRenderCallback(Callback callback) {
+		m_prerender_callback = callback;
+	}
+
+	void Engine::registerPostRenderCallback(Callback callback) {
+		m_postrender_callback = callback;
+	}
+
 	void Engine::finalizePumping() {
 		// nothing here at the moment..
 	}
--- a/engine/core/controller/engine.h	Tue Apr 19 16:13:37 2011 +0000
+++ b/engine/core/controller/engine.h	Fri Jun 10 23:35:30 2011 -1000
@@ -42,6 +42,8 @@
 #include "enginesettings.h"
 #include "video/devicecaps.h"
 
+typedef void (*Callback)();
+
 namespace gcn {
 	class Graphics;
 }
@@ -132,6 +134,16 @@
 		 */
 		void pump();
 
+		/** Register a callback function to call before rendering the main
+		 * scene.
+		 */
+		void registerPreRenderCallback(Callback callback);
+
+		/** Register a callback function to call after rendering the main
+		 * scene.
+		 */
+		void registerPostRenderCallback(Callback callback);
+
 		/** Provides access point to the SoundManager
 		 */
 		SoundManager* getSoundManager() const { return m_soundmanager; }
@@ -213,6 +225,9 @@
 		Cursor* m_cursor;
 		bool m_destroyed;
 
+		Callback m_prerender_callback;
+		Callback m_postrender_callback;
+
 		EngineSettings m_settings;
 		DeviceCaps m_devcaps;
 
--- a/engine/core/controller/engine.i	Tue Apr 19 16:13:37 2011 +0000
+++ b/engine/core/controller/engine.i	Fri Jun 10 23:35:30 2011 -1000
@@ -23,6 +23,32 @@
 #include "controller/engine.h"
 %}
 
+%header %{
+typedef void (*Callback)();
+
+PyObject *prerender_callback = 0;
+PyObject *postrender_callback = 0;
+
+void preRenderCallback() {
+	if (prerender_callback > 0) {
+		PyEval_CallFunction(prerender_callback, "()");
+	}
+}
+void postRenderCallback() {
+	if (postrender_callback > 0) {
+		PyEval_CallFunction(postrender_callback, "()");
+	}
+}
+%}
+
+%typemap(in) PyObject *callback {
+	if (!PyCallable_Check($input)) {
+		PyErr_SetString(PyExc_TypeError, "Need a callable object!");
+		return 0;
+	}
+	$1 = $input;
+}
+
 namespace FIFE {
 
 	class SoundManager;
@@ -96,6 +122,11 @@
 	};
 
 	class Engine {
+	%rename(c_registerPreRenderCallback) registerPreRenderCallback(Callback);
+	%rename(c_registerPostRenderCallback) registerPostRenderCallback(Callback);
+	%rename(registerPreRenderCallback) py_registerPreRenderCallback(PyObject*);
+	%rename(registerPostRenderCallback) py_registerPostRenderCallback(
+		PyObject*);
 	public:
 		Engine();
 		virtual ~Engine();
@@ -103,6 +134,26 @@
 		void finalizePumping();
 		void pump();
 
+		%extend {
+		void py_registerPreRenderCallback(PyObject *callback)
+		{
+			Py_XDECREF(prerender_callback);
+			Py_XINCREF(callback);
+			prerender_callback = callback;
+			$self->registerPreRenderCallback(&preRenderCallback);
+		}
+		
+		void py_registerPostRenderCallback(PyObject *callback)
+		{
+			Py_XDECREF(postrender_callback);
+			Py_XINCREF(callback);
+			postrender_callback = callback;
+			$self->registerPostRenderCallback(&postRenderCallback);
+		}
+		}
+		void registerPreRenderCallback(Callback callback);
+		void registerPostRenderCallback(Callback callback);
+
 		EngineSettings& getSettings();
 		const DeviceCaps& getDeviceCaps() const;
 		
--- a/engine/core/eventchannel/eventmanager.cpp	Tue Apr 19 16:13:37 2011 +0000
+++ b/engine/core/eventchannel/eventmanager.cpp	Fri Jun 10 23:35:30 2011 -1000
@@ -434,8 +434,9 @@
 	}
 
 	void EventManager::processMouseEvent(SDL_Event event) {
-		if(dispatchSdlEvent(event))
-			return;
+		// FIXME Technomage 2011-02-02: Guichan just consumes all mouse events.
+//		if(dispatchSdlEvent(event))
+//			return;
 
 		MouseEvent mouseevt;
 		mouseevt.setSource(this);