Commits

Bart van Strien committed 242ff68

Add channels to love.thread

Comments (0)

Files changed (10)

src/common/runtime.cpp

 
 		// Thread
 		{"Thread", THREAD_THREAD_ID},
+		{"Channel", THREAD_CHANNEL_ID},
 
 		// The modules themselves. Only add abstracted modules here.
 		{"filesystem", MODULE_FILESYSTEM_ID},

src/common/types.h

 
 		// Thread
 		THREAD_THREAD_ID,
+		THREAD_CHANNEL_ID,
 
 		// The modules themselves. Only add abstracted modules here.
 		MODULE_FILESYSTEM_ID,
 
 	// Thread.
 	const bits THREAD_THREAD_T = (bits(1) << THREAD_THREAD_ID) | OBJECT_T;
+	const bits THREAD_CHANNEL_T = (bits(1) << THREAD_CHANNEL_ID) | OBJECT_T;
 
 	// Modules.
 	const bits MODULE_FILESYSTEM_T = (bits(1) << MODULE_FILESYSTEM_ID) | MODULE_T;

src/modules/thread/Channel.cpp

+/**
+* Copyright (c) 2006-2012 LOVE Development Team
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+*
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+*
+* 1. The origin of this software must not be misrepresented; you must not
+*    claim that you wrote the original software. If you use this software
+*    in a product, an acknowledgment in the product documentation would be
+*    appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+*    misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+**/
+
+#include "Channel.h"
+
+namespace love
+{
+namespace thread
+{
+	Channel::Channel()
+	{
+		mutex = new Mutex;
+		cond = new Conditional;
+	}
+
+	Channel::~Channel()
+	{
+		delete mutex;
+		delete cond;
+	}
+
+	void Channel::push(Variant *var)
+	{
+		Lock l(mutex);
+		var->retain();
+		queue.push(var);
+		cond->signal();
+	}
+
+	Variant *Channel::pop()
+	{
+		Lock l(mutex);
+		if (queue.empty())
+			return 0;
+
+		Variant *var = queue.front();
+		queue.pop();
+		return var;
+	} // NOTE: Returns a retained Variant
+
+	Variant *Channel::demand()
+	{
+		Variant *var;
+		while (!(var = pop()))
+		{
+			mutex->lock();
+			cond->wait(mutex);
+			mutex->unlock();
+		}
+		return var;
+	}
+
+	void Channel::clear()
+	{
+		Lock l(mutex);
+		while (!queue.empty())
+			queue.pop();
+	}
+} // thread
+} // love

src/modules/thread/Channel.h

+/**
+* Copyright (c) 2006-2012 LOVE Development Team
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+*
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+*
+* 1. The origin of this software must not be misrepresented; you must not
+*    claim that you wrote the original software. If you use this software
+*    in a product, an acknowledgment in the product documentation would be
+*    appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+*    misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+**/
+
+#ifndef LOVE_THREAD_CHANNEL_H
+#define LOVE_THREAD_CHANNEL_H
+
+// STL
+#include <queue>
+
+// LOVE
+#include <common/Variant.h>
+#include <thread/threads.h>
+
+namespace love
+{
+namespace thread
+{
+	class Channel : public love::Object
+	{
+	private:
+		Mutex *mutex;
+		Conditional *cond;
+		std::queue<Variant*> queue;
+
+	public:
+		Channel();
+		~Channel();
+
+		void push(Variant *var);
+		Variant *pop();
+		Variant *demand();
+		void clear();
+	}; // Channel
+} // thread
+} // love
+
+#endif // LOVE_THREAD_CHANNEL_H

src/modules/thread/Thread.cpp

 		return "love.thread.sdl";
 	}
 
+	Channel *ThreadModule::newChannel()
+	{
+		return new Channel();
+	}
+
 } // thread
 } // love

src/modules/thread/Thread.h

 #include <common/Module.h>
 #include <common/Variant.h>
 #include <thread/threads.h>
+#include <thread/Channel.h>
 
 namespace love
 {
 		unsigned getThreadCount() const;
 		void unregister(const std::string & name);
 		const char *getName() const;
+		Channel *newChannel();
 	}; // ThreadModule
 } // thread
 } // love

src/modules/thread/wrap_Channel.cpp

+/**
+* Copyright (c) 2006-2010 LOVE Development Team
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+*
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+*
+* 1. The origin of this software must not be misrepresented; you must not
+*    claim that you wrote the original software. If you use this software
+*    in a product, an acknowledgment in the product documentation would be
+*    appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+*    misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+**/
+
+#include "wrap_Channel.h"
+
+namespace love
+{
+namespace thread
+{
+	Channel *luax_checkchannel(lua_State *L, int idx)
+	{
+		return luax_checktype<Channel>(L, idx, "Channel", THREAD_CHANNEL_T);
+	}
+
+	int w_Channel_push(lua_State *L)
+	{
+		Channel *c = luax_checkchannel(L, 1);
+		Variant *var = Variant::fromLua(L, 2);
+		c->push(var);
+		var->release();
+		return 0;
+	}
+
+	int w_Channel_pop(lua_State *L)
+	{
+		Channel *c = luax_checkchannel(L, 1);
+		Variant *var = c->pop();
+		if (var)
+		{
+			var->toLua(L);
+			var->release();
+		}
+		else
+			lua_pushnil(L);
+		return 1;
+	}
+
+	int w_Channel_demand(lua_State *L)
+	{
+		Channel *c = luax_checkchannel(L, 1);
+		Variant *var = c->demand();
+		var->toLua(L);
+		var->release();
+		return 1;
+	}
+
+	int w_Channel_clear(lua_State *L)
+	{
+		Channel *c = luax_checkchannel(L, 1);
+		c->clear();
+		return 0;
+	}
+
+	static const luaL_Reg type_functions[] = {
+		{ "push", w_Channel_push },
+		{ "pop", w_Channel_pop },
+		{ "demand", w_Channel_demand },
+		{ "clear", w_Channel_clear },
+		{ 0, 0 }
+	};
+
+	extern "C" int luaopen_channel(lua_State *L)
+	{
+		return luax_register_type(L, "Channel", type_functions);
+	}
+}
+}

src/modules/thread/wrap_Channel.h

+/**
+* Copyright (c) 2006-2012 LOVE Development Team
+*
+* This software is provided 'as-is', without any express or implied
+* warranty.  In no event will the authors be held liable for any damages
+* arising from the use of this software.
+*
+* Permission is granted to anyone to use this software for any purpose,
+* including commercial applications, and to alter it and redistribute it
+* freely, subject to the following restrictions:
+*
+* 1. The origin of this software must not be misrepresented; you must not
+*    claim that you wrote the original software. If you use this software
+*    in a product, an acknowledgment in the product documentation would be
+*    appreciated but is not required.
+* 2. Altered source versions must be plainly marked as such, and must not be
+*    misrepresented as being the original software.
+* 3. This notice may not be removed or altered from any source distribution.
+**/
+
+#ifndef LOVE_THREAD_WRAP_CHANNEL_H
+#define LOVE_THREAD_WRAP_CHANNEL_H
+
+// LOVE
+#include "Channel.h"
+
+namespace love
+{
+namespace thread
+{
+	Channel *luax_checkchannel(lua_State *L, int idx);
+	int w_Channel_push(lua_State *L);
+	int w_Channel_pop(lua_State *L);
+	int w_Channel_demand(lua_State *L);
+	int w_Channel_clear(lua_State *L);
+
+	extern "C" int luaopen_channel(lua_State *L);
+} // thread
+} // love
+
+#endif // LOVE_THREAD_WRAP_CHANNEL_H

src/modules/thread/wrap_Thread.cpp

 **/
 
 #include "wrap_Thread.h"
+#include "wrap_Channel.h"
 
 namespace love
 {
 		return 1;
 	}
 
+	int w_newChannel(lua_State *L)
+	{
+		Channel *c = instance->newChannel();
+		luax_newtype(L, "Channel", THREAD_CHANNEL_T, (void*)c);
+		return 1;
+	}
 
 	// List of functions to wrap.
 	static const luaL_Reg module_functions[] = {
 		{ "newThread", w_newThread },
 		{ "getThread", w_getThread },
 		{ "getThreads", w_getThreads },
+		{ "newChannel", w_newChannel },
 		{ 0, 0 }
 	};
 
 	static const lua_CFunction types[] = {
 		luaopen_thread,
+		luaopen_channel,
 		0
 	};
 

src/modules/thread/wrap_Thread.h

 	int w_newThread(lua_State *L);
 	int w_getThreads(lua_State *L);
 	int w_getThread(lua_State *L);
+	int w_newChannel(lua_State *L);
 
 	extern "C" LOVE_EXPORT int luaopen_love_thread(lua_State * L);