rolled back all changed to implement multitasking

git-svn-id: svn://anubis/anaglym/trunk@84 99a6e188-d820-4881-8870-2d33a10e2619
This commit is contained in:
Josh Holtrop 2009-10-14 03:38:32 +00:00
parent bf32dab70c
commit eafeac9bf9
7 changed files with 110 additions and 173 deletions

View File

@ -1,7 +1,7 @@
#include "ag.h"
#include "Video.h"
#include "Engine.h"
#include "anaglym.h"
#include <lua.hpp>
#include <stdlib.h> /* exit() */
#include <sys/types.h>
@ -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<int, Object *>::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<double> 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;

View File

@ -5,6 +5,7 @@
#include <string>
#include <lua.hpp>
#include <map>
#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;
};

12
ag.cc
View File

@ -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);

2
ag.h
View File

@ -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);

View File

@ -6,33 +6,9 @@
#include <stdlib.h> /* exit() */
#include <iostream>
#include <string>
#include <queue>
#include <GL/gl.h>
#include <GL/glu.h>
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> 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);
}

View File

@ -2,15 +2,6 @@
#ifndef ANAGLYM_H
#define ANAGLYM_H
#include <SDL.h>
#define FILENAME_SAFE_CHARS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-"
extern Uint32 g_ticks;
static inline Uint32 GetTicks()
{
return g_ticks;
}
#endif

View File

@ -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)