Commits

Igor Baidiuk committed ff8bfc8

Made properly compiled DLL. Changed readme

Comments (0)

Files changed (8)

 - Boost (author compiles against 1.50)
 - Lua 5.1.5 compiled from source
 
-To build, execute "python waf configure build"
+Configure (one-time):
+	python waf configure --boost-root <path-to-boost-distribution> --lualib-root <path-to-Lua-SDK>
+Build (after configure):
+	python waf
 
 3. Usage
 
-Place channels.dll somewhere in packae search path
+Place channels.dll somewhere in package search path
 From lua:
 require "channels"
+
+4. API
+
+channels.new(["name"])
+	creates new channel, optionally named "name"
+	If channel is named, it's placed into global channels registry.
+		
+	return:
+		new channel object
+channels.get("name")
+	retrieves existing channel by name; name should be string
+	
+	return:
+		channel object reference, if found
+		nil, if no such channel present
 #ifndef __CHANNEL_HEADER__
 #define __CHANNEL_HEADER__
 
-#include <lua.h>
+#include <lua.hpp>
 
 #include <queue>
 #include <boost/thread/mutex.hpp>
-extern "C"
-{
-#include <lua.h>
-#include <lauxlib.h>
-}
+#include <lua.hpp>
 
 #include <string>
 #include <boost/smart_ptr/shared_ptr.hpp>
 #include <boost/unordered_map.hpp>
 #include <boost/thread/mutex.hpp>
 
-#include "channels.h"
+#include <iostream>
+
 #include "Channel.hpp"
 #include "utility.hpp"
 
-#include <iostream>
-
 typedef boost::shared_ptr<Channel> ChannelPtr;
 typedef boost::weak_ptr<Channel>   ChannelRef;
 
 		chanPtr = chan->second.lock();
 
 	if (!chanPtr)
-		return lua_pushfstring(L, "Channel '%s' does not exist", name), false;
+		return false;
 
 	// initialize shared pointer to channel with inplace new
 	void* chanptr_buffer = lua_newuserdata(L, sizeof(ChannelPtr));
 		luaL_error(L, "Channel name must be a non-empty string");
 
 	if (!getChannel(L, chanName))
-		lua_error(L);
+		lua_pushnil(L);
 
 	return 1;
 }
 	return chan->receive(L);
 }
 
-int luaopen_channels(lua_State* L)
+// dllexport is sensible only on Windows
+#ifdef _WIN32
+#	define DLLEXPORT __declspec(dllexport)
+#else
+#	define DLLEXPORT
+#endif
+
+extern "C" DLLEXPORT int luaopen_channels(lua_State* L)
 {
 	luaL_register(L, "channels", lua_channels_libtable);
 	return 0;

src/channels.h

-#ifndef __LUA_CHANNELS_HEADER__
-#define __LUA_CHANNELS_HEADER__
-
-/** 
-lua.channels is a module that provides safe means of transporting complex Lua values
-between independent states.
-
-The main concept is a channel - a multiple producer-single consumer queue, that is also
-a Lua userdata to be used from script.
-
-A channel can be constructed via lua.channels.new call (from script), with optional string argument.
-Every channel has single receiver endpoint and multiple sender endpoints.
-A receiver endpoint can be created only via constructing new channel and can't be transferred anywhere.
-When you try to transfer it, you'll just receive sender endpoint.
-All sender endpoints are weak, i.e. they can't exist without receiver.
-If a channel is constructed named, it's placed into global weak registry (global to dynamic lib instance
-and weak in a means that it actually doesn't own channels). A named sender can be later acquired from that registry.
-
-Limitations:
-1. There's no "peek" and will not be. If you receive message, it's removed from queue.
-I don't consider it as an issue due to single receiver design.
-
-2. Only non-executable Lua data can be sent over channels; functions and coroutines aren't allowed
-to be sent. This is because saving and restoring full function context is a rather complex task
-
-3. Table metatables aren't transferred, as this imposes executable objects transfer
-
-4. Full userdata transfer protocol:
-	a) __channel_size__ metatable field or function, should be positive integral size of userdata in bytes (or return it)
-		default: sizeof(void*)
-	b) __channel_send__: used for placing userdata onto channel buffer
-		parameter 1: userdata
-		parameter 2: buffer to store userdata, at least __channel_size__ bytes long
-		default:     blind buffer copy
-	c) __channel_recv__: used to restore userdata from channel buffer; responsible for de-initializing buffer in any case
-		parameter 1: on-channel buffer with userdata
-		parameter 2: empty full userdata object, at least __channel_size__ bytes long
-		default:     blind buffer copy
-*/
-#include <lua.h>
-
-#ifdef WIN32
-#	ifdef LUACHANNELS_EXPORTS
-#		define LUACHANNELS_API __declspec(dllexport)
-#	else
-#		define LUACHANNELS_API __declspec(dllimport)
-#	endif
-#else
-#	define LUACHANNELS_API
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-    int LUACHANNELS_API luaopen_channels(lua_State* L);
-#ifdef __cplusplus
-}
-#endif
-
-#endif // ifndef __LUA_CHANNELS_HEADER__

src/luaVariant.hpp

-extern "C"
-{
-#include <lua.h>
-}
+#include <lua.hpp>
 #include <boost/variant/variant_fwd.hpp>
 #include <utility>
 #include <vector>
-extern "C"
-{
-#include <lua.h>
-#include <lauxlib.h>
-}
+#include <lua.hpp>
 #include "utility.hpp"
 
 int lua_newmetatableP(lua_State* L, void* key)
 #ifndef __LUA_CHANNELS_UTILITY_HEADER__
 #define __LUA_CHANNELS_UTILITY_HEADER__
 
-#include <lua.h>
+#include <lua.hpp>
 
 int   lua_newmetatableP (lua_State* L, void* key);
 void *lua_checkudataP   (lua_State *L, int ud, void* key);
 
 def build(c):
 	c.shlib(
-		source = 'src/channels.cpp src/libmain.cpp src/utility.cpp',
-		target = 'channels',
-		use    = 'BOOST LUALIB'
+		source  = 'src/channels.cpp src/libmain.cpp src/utility.cpp',
+		target  = 'channels',
+		use     = 'BOOST LUALIB',
+		defines = 'LUACHANNELS_EXPORTS',
 	)