Browse Source

Added demand (love.thread)

[email protected] 15 years ago
parent
commit
cc4d737924

+ 16 - 0
src/modules/thread/sdl/Thread.cpp

@@ -154,6 +154,7 @@ namespace sdl
 		memcpy(this->data, data->getData(), len);
 		comm = new ThreadData(name.c_str(), this->data);
 		mutex = SDL_CreateMutex();
+		cond = SDL_CreateCond();
 	}
 
 	Thread::~Thread()
@@ -164,6 +165,7 @@ namespace sdl
 			SDL_KillThread(handle);
 		reg->unregister(name);
 		SDL_DestroyMutex(mutex);
+		SDL_DestroyCond(cond);
 		reg->release();
 	}
 
@@ -214,6 +216,19 @@ namespace sdl
 		return v;
 	}
 
+	ThreadVariant *Thread::demand(std::string name)
+	{
+		lock();
+		ThreadVariant *v = comm->getValue(name);
+		while (!v)
+		{
+			SDL_CondWait(cond, mutex);
+			v = comm->getValue(name);
+		}
+		unlock();
+		return v;
+	}
+
 	void Thread::clear(std::string name)
 	{
 		lock();
@@ -226,6 +241,7 @@ namespace sdl
 		lock();
 		comm->setValue(name, v);
 		unlock();
+		SDL_CondBroadcast(cond);
 	}
 
 	ThreadModule::~ThreadModule()

+ 2 - 0
src/modules/thread/sdl/Thread.h

@@ -99,6 +99,7 @@ namespace sdl
 		std::string name;
 		char *data;
 		SDL_mutex *mutex;
+		SDL_cond *cond;
 
 	public:
 		Thread(ThreadModuleRegistrar *reg, std::string name, love::Data *data);
@@ -108,6 +109,7 @@ namespace sdl
 		void wait();
 		std::string getName();
 		ThreadVariant *receive(std::string name);
+		ThreadVariant *demand(std::string name);
 		void clear(std::string name);
 		void send(std::string name, ThreadVariant *v);
 		void lock();

+ 35 - 0
src/modules/thread/sdl/wrap_Thread.cpp

@@ -93,6 +93,40 @@ namespace sdl
 		return 1;
 	}
 
+	int w_Thread_demand(lua_State *L)
+	{
+		Thread *t = luax_checkthread(L, 1);
+		std::string name = luaL_checkstring(L, 2);
+		ThreadVariant *v = t->demand(name);
+		if (!v)
+		{
+			lua_pushnil(L);
+			return 1;
+		}
+		v->retain();
+		t->clear(name);
+		switch(v->type)
+		{
+			case BOOLEAN:
+				lua_pushboolean(L, v->data.boolean);
+				break;
+			case NUMBER:
+				lua_pushnumber(L, v->data.number);
+				break;
+			case STRING:
+				lua_pushstring(L, v->data.string);
+				break;
+			case USERDATA: //FIXME: full userdata
+				lua_pushlightuserdata(L, v->data.userdata);
+				break;
+			default:
+				lua_pushnil(L);
+				break;
+		}
+		v->release();
+		return 1;
+	}
+
 	int w_Thread_peek(lua_State *L)
 	{
 		Thread *t = luax_checkthread(L, 1);
@@ -162,6 +196,7 @@ namespace sdl
 		{ "wait", w_Thread_wait },
 		{ "getName", w_Thread_getName },
 		{ "receive", w_Thread_receive },
+		{ "demand", w_Thread_demand },
 		{ "peek", w_Thread_peek },
 		{ "send", w_Thread_send },
 		{ 0, 0 }

+ 1 - 0
src/modules/thread/sdl/wrap_Thread.h

@@ -37,6 +37,7 @@ namespace sdl
 	int w_Thread_wait(lua_State *L);
 	int w_Thread_getName(lua_State *L);
 	int w_Thread_receive(lua_State *L);
+	int w_Thread_demand(lua_State *L);
 	int w_Thread_peek(lua_State *L);
 	int w_Thread_send(lua_State *L);