[Housebot-developers] SF.net SVN: housebot: [466] trunk/housebot/src
Status: Alpha
Brought to you by:
j_house
|
From: <j_...@us...> - 2007-02-07 00:16:26
|
Revision: 466
http://svn.sourceforge.net/housebot/?rev=466&view=rev
Author: j_house
Date: 2007-02-06 16:16:24 -0800 (Tue, 06 Feb 2007)
Log Message:
-----------
A truly generic and functional GTP command registration
Sadly, most uses are commented out right now :(
On a positive note, they work if you uncomment them...
Modified Paths:
--------------
trunk/housebot/src/brains.cpp
trunk/housebot/src/gtp/GTPBoard.h
trunk/housebot/src/gtp/GTPFunctionObject.h
trunk/housebot/src/housebot.cpp
Added Paths:
-----------
trunk/housebot/src/gtp/GTPFunctionObjectTemplate.hpp
Modified: trunk/housebot/src/brains.cpp
===================================================================
--- trunk/housebot/src/brains.cpp 2007-02-07 00:15:28 UTC (rev 465)
+++ trunk/housebot/src/brains.cpp 2007-02-07 00:16:24 UTC (rev 466)
@@ -580,14 +580,12 @@
void
collective::register_gtp(GTPBoard >p_engine){
-/// \bug since these command bypass the GoBoardInterface and other data structures, like the GameTree, are not updated and causes the program to crash.
-
-// gtp_engine.RegisterCommand("boardsize", GTPCommandCallBack(new boost::function<void (int)> (boost::lambda::bind(boost::mem_fn(&collective::reinitialize), (collective*)this, boost::lambda::_1))));
-// gtp_engine.RegisterCommand("clear_board", GTPCommandCallBack(new boost::function<void ()> (boost::lambda::bind(boost::mem_fn(&collective::clear), (collective*)this))));
-// gtp_engine.RegisterCommand("komi", GTPCommandCallBack(new boost::function<void (float)>(boost::lambda::bind(boost::mem_fn(&collective::set_komi), (collective*)this, boost::lambda::_1))));
-// gtp_engine.RegisterCommand("undo", GTPCommandCallBack(new boost::function<void ()> (boost::lambda::bind(boost::mem_fn(&collective::undo), (collective*)this))));
- //gtp_engine.RegisterCommand("time_left", GTPCommandCallBack(new boost::function<void (color_t, int, int)>(boost::lambda::bind(boost::mem_fn(&collective::time_left), (collective*)this, boost::lambda::_1, boost::lambda::_2, boost::lambda::_3))));
-
+ /// \bug since these command bypass the GoBoardInterface and other data structures, like the GameTree, are not updated and causes the program to crash.
+// gtp_engine.RegisterCommand("boardsize", GTPCommandCallBack1(new boost::function1<void, int> (boost::lambda::bind(boost::mem_fn(&collective::reinitialize), (collective*)this, boost::lambda::_1))));
+// gtp_engine.RegisterCommand("clear_board", GTPCommandCallBack0(new boost::function0<void> (boost::lambda::bind(boost::mem_fn(&collective::clear), (collective*)this))));
+// gtp_engine.RegisterCommand("komi", GTPCommandCallBack1(new boost::function1<void, float>(boost::lambda::bind(boost::mem_fn(&collective::set_komi), (collective*)this, boost::lambda::_1))));
+// gtp_engine.RegisterCommand("time_left", GTPCommandCallBack3(new boost::function3<void, color_t, int, int>(boost::lambda::bind(boost::mem_fn(&collective::time_left), (collective*)this, boost::lambda::_1, boost::lambda::_2, boost::lambda::_3))));
+// gtp_engine.RegisterCommand("undo", GTPCommandCallBack0(new boost::function0<void> (boost::lambda::bind(boost::mem_fn(&collective::undo), (collective*)this))));
}
bool
Modified: trunk/housebot/src/gtp/GTPBoard.h
===================================================================
--- trunk/housebot/src/gtp/GTPBoard.h 2007-02-07 00:15:28 UTC (rev 465)
+++ trunk/housebot/src/gtp/GTPBoard.h 2007-02-07 00:16:24 UTC (rev 466)
@@ -140,7 +140,7 @@
// RegisterCommand("known_command", >PBoard::GTPKnownComand);
RegisterCommand("list_commands", GTPListCommands);
RegisterCommand("cputime", >PCPUTime);
- RegisterCommand("echo", GTPCommandCallBack(GTPBoard::GTPEcho));
+ RegisterCommand("echo", GTPCommandCallBack1(new boost::function1<std::string, std::string>(GTPBoard::GTPEcho)));
RegisterCommand("quit", >PBoard::GTPQuit);
RegisterCommand("timer_start", >PTimerStart);
RegisterCommand("timer_now", >PTimerNow);
Modified: trunk/housebot/src/gtp/GTPFunctionObject.h
===================================================================
--- trunk/housebot/src/gtp/GTPFunctionObject.h 2007-02-07 00:15:28 UTC (rev 465)
+++ trunk/housebot/src/gtp/GTPFunctionObject.h 2007-02-07 00:16:24 UTC (rev 466)
@@ -4,20 +4,27 @@
#include "GTPInternalResponse.h"
#include "GTPCommand.h"
+/// \bug This should be made indpendent of the housebot core
+#include "go_board.hpp" // for color_t
+
#include <boost/function.hpp>
#include <boost/lambda/bind.hpp>
#include <assert.h>
#include <list>
+#include <boost/static_assert.hpp>
+#include <boost/preprocessor/enum_params.hpp> // expands for 0 ... N-1
+#include <boost/preprocessor/repetition/enum_shifted_params.hpp> // expands for 1 ... N-1
+
typedef boost::function<GTPInternalResponse (GTPCommand)> GTPFunctionObject;
namespace gtp_detail{
-
/// \bug Not very general purpose at this time
/// \bug Having to declare this inline is an anti-ld-error feature...
template<typename inputType, typename outputType> inline
outputType converter(inputType x){
outputType y = (outputType) x;
+ //BOOST_STATIC_ASSERT(false);
return y;
}
@@ -51,6 +58,15 @@
return x.GetAsFloat();
}
+ template<> inline
+ color_t converter(SmartString &x){
+ if (x=="black" || x=="Black" || x=="BLACK")
+ return black;
+ if (x=="white" || x=="White" || x=="WHITE")
+ return white;
+ assert(false);
+ }
+
template<typename inputType> inline
inputType extract(GTPCommand &x, unsigned int &position){
SmartString arg = x.GetArgument(position++);
@@ -67,122 +83,22 @@
return return_val;
}
- template <typename inputType, typename outputType> inline
- GTPInternalResponse type_wrapper(boost::function<outputType (inputType)> *callback_function, GTPCommand cmd){
- unsigned int position = 0;
- inputType arg = extract<inputType>(cmd, position);
- assert(position == cmd.GetArgumentCount());
- return converter<outputType, GTPInternalResponse>( (*callback_function)(arg) );
- }
-
- // If there's no input argument, special handling is required
- template<typename outputType> inline
- GTPInternalResponse type_wrapper(boost::function<outputType (void)> *callback_function, GTPCommand cmd){
- assert(cmd.GetArgumentCount()==0);
- return converter<outputType, GTPInternalResponse>( (*callback_function)() );
- }
-
- // If there's no output argument, special handling is required
- template<typename inputType> inline
- GTPInternalResponse type_wrapper(boost::function<void (inputType)> *callback_function, GTPCommand cmd){
- unsigned int position = 0;
- inputType arg = extract<inputType>(cmd, position);
- assert(position == cmd.GetArgumentCount());
- (*callback_function)(arg);
- return GTPInternalResponse(true, "");
- }
-
- // If neither... you get the idea...
- template<> inline
- GTPInternalResponse type_wrapper(boost::function<void ()> *callback_function, GTPCommand cmd){
- assert(cmd.GetArgumentCount() == 0);
- (*callback_function)();
- return GTPInternalResponse(true, "");
- }
- /*
- template<typename inputType1, typename inputType2, typename outputType> inline
- GTPInternalResponse type_wrapper(boost::function<outputType (inputType1, inputType2)> *callback_function, GTPCommand cmd){
- unsigned int position = 0;
- assert (position < cmd.GetArgumentCount());
- inputType1 arg1 = extract<inputType1>(cmd, position);
- assert(position < cmd.GetArgumentCount());
- inputType2 arg2 = extract<inputType2>(cmd, position);
- assert(position == cmd.GetArgumentCount());
- return converter<outputType, GTPInternalResponse>( (*callback_function)(arg1, arg2) );
- }
-
- template<typename inputType1, typename inputType2> inline
- GTPInternalResponse type_wrapper(boost::function<void (inputType1, inputType2)> *callback_function, GTPCommand cmd){
- unsigned int position = 0;
- assert (position < cmd.GetArgumentCount());
- inputType1 arg1 = extract<inputType1>(cmd, position);
- assert(position < cmd.GetArgumentCount());
- inputType2 arg2 = extract<inputType2>(cmd, position);
- assert(position == cmd.GetArgumentCount());
- (*callback_function)(arg1,arg2);
- return GTPInternalResponse (true, "");
- }
- */
-
};
-template <typename inputType, typename outputType> inline
-GTPFunctionObject* GTPCommandCallBack(boost::function<outputType (inputType)> *callback_function){
- GTPInternalResponse (*type_wrapper)(boost::function<outputType (inputType)>*, GTPCommand) = gtp_detail::type_wrapper<inputType,outputType>;
- return new GTPFunctionObject(boost::lambda::bind(type_wrapper, callback_function, boost::lambda::_1));
-}
+#define GTP_PARAM_COUNT 0
+#include "GTPFunctionObjectTemplate.hpp"
+#undef GTP_PARAM_COUNT
-template <typename inputType> inline
-GTPFunctionObject* GTPCommandCallBack(boost::function<void (inputType)> *callback_function){
- GTPInternalResponse (*type_wrapper)(boost::function<void (inputType)>*, GTPCommand) = gtp_detail::type_wrapper<inputType>;
- return new GTPFunctionObject(boost::lambda::bind(type_wrapper, callback_function, boost::lambda::_1));
-}
+#define GTP_PARAM_COUNT 1
+#include "GTPFunctionObjectTemplate.hpp"
+#undef GTP_PARAM_COUNT
-template <typename outputType> inline
-GTPFunctionObject* GTPCommandCallBack(boost::function<outputType ()> *callback_function){
- GTPInternalResponse (*type_wrapper)(boost::function<outputType ()>*, GTPCommand) = gtp_detail::type_wrapper<outputType>;
- return new GTPFunctionObject(boost::lambda::bind(type_wrapper, callback_function, boost::lambda::_1));
-}
+#define GTP_PARAM_COUNT 2
+#include "GTPFunctionObjectTemplate.hpp"
+#undef GTP_PARAM_COUNT
-template <typename inputType1, typename inputType2, typename outputType>
-GTPFunctionObject* GTPCommandCallBack(boost::function<outputType(inputType1, inputType2)> *callback_function){
- GTPInternalResponse (*type_wrapper)(boost::function<outputType (inputType1,inputType2)>*, GTPCommand) = gtp_detail::type_wrapper<inputType1, inputType2, outputType>;
- return new GTPFunctionObject(boost::lambda::bind(type_wrapper, callback_function, boost::lambda::_1));
-}
-/*
-template <typename inputType1, typename inputType2, typename inputType3, typename outputType>
-GTPFunctionObject* GTPCommandCallBack(boost::function<outputType(inputType1, inputType2, inputType3)> *callback_function){
- GTPInternalResponse (*type_wrapper)(boost::function<outputType (inputType1,inputType2,inputType3)>*, GTPCommand) = gtp_detail::type_wrapper<inputType1, inputType2, inputType3, outputType>;
- return new GTPFunctionObject(boost::lambda::bind(type_wrapper, callback_function, boost::lambda::_1));
-}
+#define GTP_PARAM_COUNT 3
+#include "GTPFunctionObjectTemplate.hpp"
+#undef GTP_PARAM_COUNT
-template <typename inputType1, typename inputType2, typename inputType3>
-GTPFunctionObject* GTPCommandCallBack(boost::function<void (inputType1, inputType2, inputType3)> *callback_function){
- GTPInternalResponse (*type_wrapper)(boost::function<void (inputType1,inputType2,inputType3)>*, GTPCommand) = gtp_detail::type_wrapper<inputType1, inputType2, inputType3>;
- return new GTPFunctionObject(boost::lambda::bind(type_wrapper, callback_function, boost::lambda::_1));
-}
-*/
-
-////////////////////////
-
-template <typename inputType, typename outputType> inline
-GTPFunctionObject* GTPCommandCallBack(outputType (*callback_function)(inputType)){
- return GTPCommandCallBack(new boost::function<outputType (inputType)>(callback_function));
-}
-
-template <typename inputType> inline
-GTPFunctionObject* GTPCommandCallBAck(void (*callback_function)(inputType)){
- return GTPCommandCallBack(new boost::function<void (inputType)>(callback_function));
-}
-
-template <typename outputType> inline
-GTPFunctionObject* GTPCommandCallBack(outputType (*callback_function)()){
- return GTPCommandCallBack(new boost::function<outputType ()>(callback_function));
-}
-
-template <typename inputType1, typename inputType2, typename outputType>
-GTPFunctionObject* GTPCommandCallBack(outputType(*callback_function)(inputType1, inputType2)){
- return GTPCommandCallBack(new boost::function<outputType (inputType1, inputType2)>(callback_function));
-}
-
#endif
Added: trunk/housebot/src/gtp/GTPFunctionObjectTemplate.hpp
===================================================================
--- trunk/housebot/src/gtp/GTPFunctionObjectTemplate.hpp (rev 0)
+++ trunk/housebot/src/gtp/GTPFunctionObjectTemplate.hpp 2007-02-07 00:16:24 UTC (rev 466)
@@ -0,0 +1,113 @@
+#if GTP_PARAM_COUNT == 0
+# define GTP_OPTIONAL_COMMA
+#else
+# define GTP_OPTIONAL_COMMA ,
+#endif
+
+
+// GTP_PARMS expands to " typename T0, typename T1, typename T2" if GTP_PARAM_COUNT is 3
+#define GTP_TEMPLATE_PARAMS BOOST_PP_ENUM_PARAMS(GTP_PARAM_COUNT, typename T)
+
+// expands to "typename R0 , typename T0, typename T1, typename T2" if GTP_PARAM_COUNT is 3
+#define GTP_FULL_TEMPLATE_PARAMS typename R0 GTP_OPTIONAL_COMMA GTP_TEMPLATE_PARAMS
+
+// GTP_PARAM expands to " T3 a3" if INDEX is 3
+#define GTP_PARAM(UNKNOWN1,INDEX,UNKNOWN2) BOOST_PP_CAT(T,I) BOOST_PP_CAT(a,I)
+
+// GTP_PARAMS expands to " T0 a0, T1 a1, T2 a2" if GTP_PARAM_COUNT is 3
+#define GTP_PARAMS BOOST_PP_ENUM(GTP_PARAM_COUNT,GTP_PARAM,BOOST_PP_EMPTY)
+
+// GTP_PARAM_TYPES expands to " T0, T1, T2" if GTP_PARAM_COUNT is 3
+#define GTP_PARAM_TYPES BOOST_PP_ENUM_PARAMS(GTP_PARAM_COUNT, T)
+
+// expands to "R0 , T0, T1, T2" if GTP_PARAM_COUNT is 3
+#define GTP_FULL_PARAM_TYPES R0 GTP_OPTIONAL_COMMA GTP_PARAM_TYPES
+
+// GTP_PARAM_NAMES expands to " a0, a1, a2" if GTP_PARAM_COUNT is 3
+#define GTP_PARAM_NAMES BOOST_PP_ENUM_PARAMS(GTP_PARAM_COUNT, a)
+
+// expands to "boost::function3 < R0 , T0, T1, T2 >" when GTP_PARAM_COUNT is 3
+#define GTP_BOOST_FUNCTION BOOST_PP_CAT(boost::function,GTP_PARAM_COUNT) < GTP_FULL_PARAM_TYPES >
+
+// expands to "boost::function3 < void , T0, T1, T2 >" when GTP_PARAM_COUNT is 3
+#define GTP_BOOST_FUNCTION_VOID BOOST_PP_CAT(boost::function,GTP_PARAM_COUNT) < void GTP_OPTIONAL_COMMA GTP_PARAM_TYPES >
+
+// expands to type_wrapper3 when GTP_PARAM_COUNT is 3
+#define GTP_TYPE_WRAPPER BOOST_PP_CAT(type_wrapper,GTP_PARAM_COUNT)
+
+//////////////////////////////////////////////////////////////
+// gtp_detail::type_wrapper for converting all input arguments
+namespace gtp_detail{
+
+ template < GTP_FULL_TEMPLATE_PARAMS >
+ struct GTP_TYPE_WRAPPER{
+ static GTPInternalResponse wrap(GTP_BOOST_FUNCTION *(callback_function), GTPCommand cmd){
+ unsigned int position = 0;
+ /// \bug Must figure out how to auto generate this repetative body
+#if GTP_PARAM_COUNT >= 1
+ assert(position < cmd.GetArgumentCount());
+ T0 a0 = extract<T0>(cmd, position);
+#endif
+#if GTP_PARAM_COUNT >= 2
+ assert(position < cmd.GetArgumentCount());
+ T1 a1 = extract<T1>(cmd,position);
+#endif
+#if GTP_PARAM_COUNT >= 3
+ assert(position < cmd.GetArgumentCount());
+ T2 a2 = extract<T2>(cmd,position);
+#endif
+ assert(position == cmd.GetArgumentCount());
+ return converter<R0, GTPInternalResponse>( (*callback_function)(GTP_PARAM_NAMES) );
+ }
+ };
+
+ template < GTP_TEMPLATE_PARAMS >
+ struct GTP_TYPE_WRAPPER < void GTP_OPTIONAL_COMMA GTP_PARAM_TYPES >{
+ static GTPInternalResponse wrap(GTP_BOOST_FUNCTION_VOID *(callback_function), GTPCommand cmd){
+ unsigned int position = 0;
+ /// \bug Must figure out how to auto generate this repetative body
+#if GTP_PARAM_COUNT >= 1
+ assert(position < cmd.GetArgumentCount());
+ T0 a0 = extract<T0>(cmd, position);
+#endif
+#if GTP_PARAM_COUNT >= 2
+ assert(position < cmd.GetArgumentCount());
+ T1 a1 = extract<T1>(cmd,position);
+#endif
+#if GTP_PARAM_COUNT >= 3
+ assert(position < cmd.GetArgumentCount());
+ T2 a2 = extract<T2>(cmd,position);
+#endif
+ assert(position == cmd.GetArgumentCount());
+ (*callback_function)(GTP_PARAM_NAMES);
+ return GTPInternalResponse();
+ }
+ };
+
+};
+
+///////////////////////////////////////////////////////
+// GTPCommandCallBack accepting a boost function object
+
+// expands to GTPFunctionObject3 when GTP_PARAM_COUNT is 3
+#define GTP_COMMAND_CALLBACK BOOST_PP_CAT(GTPCommandCallBack,GTP_PARAM_COUNT)
+
+template< GTP_FULL_TEMPLATE_PARAMS > inline
+GTPFunctionObject* GTP_COMMAND_CALLBACK(GTP_BOOST_FUNCTION *callback_function){
+ return new GTPFunctionObject(boost::lambda::bind((>p_detail::GTP_TYPE_WRAPPER<GTP_FULL_PARAM_TYPES>::wrap), callback_function, boost::lambda::_1));
+}
+
+///////////////////////////////////////////////////////
+// Cleanup
+
+#undef GTP_OPTIONAL_COMMA
+#undef GTP_TEMPLATE_PARAMS
+#undef GTP_FULL_TEMPLATE_PARAMS
+#undef GTP_PARAM
+#undef GTP_PARAMS
+#undef GTP_PARAM_TYPES
+#undef GTP_PARAM_NAMES
+#undef GTP_BOOST_FUNCTION
+#undef GTP_BOOST_FUNCTION_VOID
+#undef GTP_TYPE_WRAPPER
+#undef GTP_COMMAND_CALLBACK
Modified: trunk/housebot/src/housebot.cpp
===================================================================
--- trunk/housebot/src/housebot.cpp 2007-02-07 00:15:28 UTC (rev 465)
+++ trunk/housebot/src/housebot.cpp 2007-02-07 00:16:24 UTC (rev 466)
@@ -83,10 +83,10 @@
the_collective.register_gtp(lGTPGoBoard);
- lGTPGoBoard.RegisterCommand("name", GTPCommandCallBack(name));
- lGTPGoBoard.RegisterCommand("version", GTPCommandCallBack(version));
- lGTPGoBoard.RegisterCommand("kgs-game_over", GTPCommandCallBack(consider_shutdown));
- lGTPGoBoard.RegisterCommand("kgs-chat", GTPCommandCallBack(chat));
+ lGTPGoBoard.RegisterCommand("name", GTPCommandCallBack0(new boost::function0<std::string>(name)));
+ lGTPGoBoard.RegisterCommand("version", GTPCommandCallBack0(new boost::function0<std::string>(version)));
+ lGTPGoBoard.RegisterCommand("kgs-game_over", GTPCommandCallBack0(new boost::function0<void>(consider_shutdown)));
+ lGTPGoBoard.RegisterCommand("kgs-chat", GTPCommandCallBack1(new boost::function1<std::string,std::list<std::string> >(chat)));
GTPCommStream lComm(&std::cin,&std::cout);
GTPEngine lGTPEngine(lGTPGoBoard, lComm);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|