From eafeac9bf99f2ee0719aa55d3581b5064a02646e Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Wed, 14 Oct 2009 03:38:32 +0000 Subject: [PATCH] rolled back all changed to implement multitasking git-svn-id: svn://anubis/anaglym/trunk@84 99a6e188-d820-4881-8870-2d33a10e2619 --- Engine.cc | 86 +++++++++++++++++++++-- Engine.h | 14 +++- ag.cc | 12 ++++ ag.h | 2 + anaglym.cc | 158 +------------------------------------------ anaglym.h | 9 --- tests/ballstairs.lua | 2 + 7 files changed, 110 insertions(+), 173 deletions(-) diff --git a/Engine.cc b/Engine.cc index 32efd04..a57da07 100644 --- a/Engine.cc +++ b/Engine.cc @@ -1,7 +1,7 @@ #include "ag.h" +#include "Video.h" #include "Engine.h" -#include "anaglym.h" #include #include /* exit() */ #include @@ -16,8 +16,11 @@ using namespace std; Engine * g_engine; +SDL_Event Engine::userEvent; + Engine::Engine(const string & path) { + m_video = new Video(); m_next_object_index = 1; m_eye[0] = 0; m_eye[1] = -1; @@ -28,14 +31,26 @@ Engine::Engine(const string & path) m_up[0] = 0; m_up[1] = 0; m_up[2] = 1; + m_drawing = false; m_autoPhysics = true; size_t pos = path.find_last_of("\\/"); m_engine_path = (pos != string::npos) ? string(path, 0, pos) : "."; + + /* setup redraw SDL event structure */ + userEvent.type = SDL_USEREVENT; + userEvent.user.code = 0; +#if 0 + /* start in windowed mode for debugging */ + m_video->start(0, 0, false, false); +#else + m_video->start(); +#endif } Engine::~Engine() { + m_video->stop(); lua_close(m_luaState); for (std::map::iterator it = m_objects.begin(); it != m_objects.end(); @@ -43,6 +58,7 @@ Engine::~Engine() { delete it->second; } + delete m_video; } bool Engine::load(const char * program) @@ -159,7 +175,7 @@ Engine::Object * Engine::getObject(int id) return m_objects.find(id) != m_objects.end() ? m_objects[id] : NULL; } -void Engine::startFrame() +int Engine::startFrame(lua_State * L) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); @@ -167,6 +183,13 @@ void Engine::startFrame() gluLookAt(m_eye[0], m_eye[1], m_eye[2], m_center[0], m_center[1], m_center[2], m_up[0], m_up[1], m_up[2]); + return 0; +} + +int Engine::endFrame(lua_State * L) +{ + SDL_GL_SwapBuffers(); + return 0; } int Engine::setCamera(lua_State * L) @@ -176,7 +199,8 @@ int Engine::setCamera(lua_State * L) vector args; for (int i = 1; i <= argc; i++) { - if (lua_isnumber(L, i)) + int type = lua_type(L, i); + if (type == LUA_TNUMBER || type == LUA_TSTRING) args.push_back(lua_tonumber(L, i)); else args.push_back(0); @@ -204,13 +228,62 @@ int Engine::setCamera(lua_State * L) return 0; } +/* called by SDL when the update timer expires */ +Uint32 Engine::updateCallback(Uint32 interval, void * param) +{ + Engine * engine = (Engine *) param; + return engine->updateCallback(interval); +} + +/* member update function to be called by our registered + * SDL callback non-member function */ +Uint32 Engine::updateCallback(Uint32 interval) +{ + if (!m_drawing) + { + SDL_PushEvent(&userEvent); + } + return interval; +} + +void Engine::run() +{ + /* register a screen redrawing SDL event */ + SDL_AddTimer(25, &updateCallback, this); + + SDL_Event event; + while (SDL_WaitEvent(&event)) + { + switch (event.type) + { + case SDL_KEYDOWN: + if (event.key.keysym.sym == SDLK_ESCAPE) + { + goto RET; + } + break; + case SDL_QUIT: + goto RET; + break; + case SDL_USEREVENT: + if (event.user.code == 0) + { + update(); + } + break; + } + } +RET: + ; +} + void Engine::update() { - startFrame(); + m_drawing = true; if (m_autoPhysics) doPhysics(); lua_getfield(m_luaState, LUA_GLOBALSINDEX, "update"); - if (lua_isfunction(m_luaState, -1)) + if (lua_type(m_luaState, -1) == LUA_TFUNCTION) { /* call the update function - pops the function ref from the stack */ int s = lua_pcall(m_luaState, 0, LUA_MULTRET, 0); @@ -220,12 +293,13 @@ void Engine::update() { lua_pop(m_luaState, 1); } + m_drawing = false; } void Engine::doPhysics() { static Uint32 last_updated = 0; - Uint32 current_ticks = GetTicks(); + Uint32 current_ticks = SDL_GetTicks(); if (last_updated > 0) { Uint32 msec_steps = current_ticks - last_updated; diff --git a/Engine.h b/Engine.h index dbccec2..8449f86 100644 --- a/Engine.h +++ b/Engine.h @@ -5,6 +5,7 @@ #include #include #include +#include "Video.h" #include "OdeWorld/OdeWorld.h" #include "wfobj/WFObj.hh" @@ -49,7 +50,9 @@ class Engine ~Engine(); std::string locateResource(const std::string & shortname); + Video * getVideo() { return m_video; } bool load(const char * program); + void run(); void reportErrors(int status); OdeWorld & getWorld() { return m_world; } int addObject(WFObj * obj, bool is_static, float scale = 1.0f); @@ -60,22 +63,28 @@ class Engine void drawObjects(); void setAutoPhysics(bool autoPhysics) { m_autoPhysics = autoPhysics; } bool getAutoPhysics() { return m_autoPhysics; } - void update(); /* lua services */ + int startFrame(lua_State * L); + int endFrame(lua_State * L); int setCamera(lua_State * L); protected: + static Uint32 updateCallback(Uint32 interval, void * param); + static SDL_Event userEvent; + + Uint32 updateCallback(Uint32 interval); void registerLibraries(); bool fileExists(const std::string & path); + void update(); Object * createObject(bool is_static, GLuint display_list, float scale = 1.0f) { return new Object(is_static, m_world, display_list, scale); } - void startFrame(); lua_State * m_luaState; + Video * m_video; std::string m_program_path; std::string m_engine_path; OdeWorld m_world; @@ -84,6 +93,7 @@ class Engine GLdouble m_eye[3]; GLdouble m_center[3]; GLdouble m_up[3]; + bool m_drawing; bool m_autoPhysics; }; diff --git a/ag.cc b/ag.cc index bbf8751..ab5db3b 100644 --- a/ag.cc +++ b/ag.cc @@ -26,6 +26,8 @@ namespace ag { "loadModel", loadModel }, { "loadStaticModel", loadStaticModel }, { "sleep", sleep }, + { "startFrame", startFrame }, + { "endFrame", endFrame }, { "setCamera", setCamera }, { "elapsedTime", elapsedTime }, { "doPhysics", doPhysics }, @@ -197,6 +199,16 @@ namespace ag return 0; } + int startFrame(lua_State * L) + { + return g_engine->startFrame(L); + } + + int endFrame(lua_State * L) + { + return g_engine->endFrame(L); + } + int setCamera(lua_State * L) { return g_engine->setCamera(L); diff --git a/ag.h b/ag.h index a3cb45d..df4abe1 100644 --- a/ag.h +++ b/ag.h @@ -12,6 +12,8 @@ namespace ag int loadModel(lua_State * L); int loadStaticModel(lua_State * L); int sleep(lua_State * L); + int startFrame(lua_State * L); + int endFrame(lua_State * L); int setCamera(lua_State * L); int elapsedTime(lua_State * L); int doPhysics(lua_State * L); diff --git a/anaglym.cc b/anaglym.cc index be741ad..4dd7e80 100644 --- a/anaglym.cc +++ b/anaglym.cc @@ -6,33 +6,9 @@ #include /* exit() */ #include #include -#include -#include -#include using namespace std; -enum EventType { EVENT_UPDATE }; - -typedef struct -{ - EventType type; -} Event; - static void usage(); -static void mainloop(); -static void update(); -static void addEvent(const Event & event); -static Uint32 updateCallback(Uint32 interval, void * param); - -static bool lastUpdateCompleted; -static bool engine_running; -static SDL_Event userEvent; -static SDL_cond * event_condition; -static SDL_mutex * event_mutex; -static SDL_mutex * event_queue_mutex; -static SDL_mutex * engine_thread_ready_mutex; -static queue event_queue; -Uint32 g_ticks; static void usage() { @@ -40,56 +16,6 @@ static void usage() exit(42); } -static int engine_thread(void * param) -{ - const char * program = (const char *) param; - if (g_engine->load(program)) - { - SDL_mutexV(engine_thread_ready_mutex); - for (;;) - { - Event event; - bool moreEvents = false; - SDL_mutexP(event_queue_mutex); - if (event_queue.size() > 0) - moreEvents = true; - SDL_mutexV(event_queue_mutex); - if (!moreEvents) - { - /* wait for an event to be ready */ - SDL_mutexP(event_mutex); - SDL_CondWait(event_condition, event_mutex); - } - moreEvents = true; - while (moreEvents) - { - SDL_mutexP(event_queue_mutex); - if (event_queue.size() < 1) - moreEvents = false; - else - { - event = event_queue.front(); - event_queue.pop(); - } - SDL_mutexV(event_queue_mutex); - if (moreEvents) - { - /* process the event */ - switch (event.type) - { - case EVENT_UPDATE: - g_engine->update(); - lastUpdateCompleted = true; - break; - } - } - } - } - } - engine_running = false; - return 0; -} - int main(int argc, char * argv[]) { const char * program = NULL; @@ -120,90 +46,10 @@ int main(int argc, char * argv[]) usage(); } - lastUpdateCompleted = true; - engine_running = true; - /* setup SDL update event */ - userEvent.type = SDL_USEREVENT; - userEvent.user.code = 0; - event_condition = SDL_CreateCond(); - event_mutex = SDL_CreateMutex(); - event_queue_mutex = SDL_CreateMutex(); - - Video video; -#if 0 - /* start in windowed mode for debugging */ - video.start(0, 0, false, false); -#else - video.start(); -#endif - g_engine = new Engine(argv[0]); - SDL_CreateThread(engine_thread, (void *) program); - - mainloop(); - - SDL_DestroyCond(event_condition); + if (g_engine->load(program)) + g_engine->run(); delete g_engine; - video.stop(); return 0; } - -/* called by SDL when the update timer expires */ -static Uint32 updateCallback(Uint32 interval, void * param) -{ - if (lastUpdateCompleted) - SDL_PushEvent(&userEvent); - return interval; -} - -static void mainloop() -{ - SDL_Event event; - - /* register a screen redrawing SDL event */ - SDL_AddTimer(25, &updateCallback, NULL); - - while (SDL_WaitEvent(&event)) - { - if (!engine_running) - goto RET; - switch (event.type) - { - case SDL_KEYDOWN: - if (event.key.keysym.sym == SDLK_ESCAPE) - { - goto RET; - } - break; - case SDL_QUIT: - goto RET; - break; - case SDL_USEREVENT: - if (event.user.code == 0) - { - SDL_GL_SwapBuffers(); - update(); - } - break; - } - } -RET: - ; -} - -static void update() -{ - Event update_event; - update_event.type = EVENT_UPDATE; - lastUpdateCompleted = false; - addEvent(update_event); -} - -static void addEvent(const Event & event) -{ - SDL_mutexP(event_queue_mutex); - event_queue.push(event); - SDL_mutexV(event_queue_mutex); - SDL_CondSignal(event_condition); -} diff --git a/anaglym.h b/anaglym.h index e7d2325..d5cc2cb 100644 --- a/anaglym.h +++ b/anaglym.h @@ -2,15 +2,6 @@ #ifndef ANAGLYM_H #define ANAGLYM_H -#include - #define FILENAME_SAFE_CHARS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-" -extern Uint32 g_ticks; - -static inline Uint32 GetTicks() -{ - return g_ticks; -} - #endif diff --git a/tests/ballstairs.lua b/tests/ballstairs.lua index 3919938..f7a181c 100755 --- a/tests/ballstairs.lua +++ b/tests/ballstairs.lua @@ -2,7 +2,9 @@ function update() ballx, bally, ballz = ball:getPosition() ag.setCamera(7, -6, 15, ballx, bally, ballz, 0, 0, 1) + ag.startFrame() ag.drawObjects() + ag.endFrame() end --ag.setCamera(8, -8, 15, -8, 8, 4, 0, 0, 1)