00001 //---------------------------------------------------------------------------- 00002 /** @file GtpEngine.h 00003 Basic implementation of the Go Text Protocol (GTP). 00004 00005 Depends only on the standard C++ library for maximum reusability. 00006 If ponder or interrupt functionality is enabled by setting the macros 00007 GTPENGINE_PONDER and/or GTPENGINE_INTERRUPT to 1, the Boost.Thread library 00008 is also needed. 00009 00010 GtpEngine implements a GTP engine with some basic commands. This class 00011 is typically used as a base class for other GTP engines. 00012 GtpEngine::Register allows to register additional commands. 00013 GtpEngine::MainLoop starts the main command loop. 00014 Command handlers implement the interface GtpCallbackBase. 00015 For class member functions, such a callback can be constructed with 00016 the GtpCallback template class. 00017 Each callback function is passed a GtpCommand argument, which can be 00018 queried for arguments and used for writing the response to. 00019 GTP error responses are created by throwing an instance of GtpFailure. 00020 All such exceptions are caught in the main loop and converted 00021 into a response with error status. */ 00022 //---------------------------------------------------------------------------- 00023 00024 #ifndef GTPENGINE_H 00025 #define GTPENGINE_H 00026 00027 #include <cstddef> 00028 #include <iostream> 00029 #include <map> 00030 #include <sstream> 00031 #include <string> 00032 #include <vector> 00033 #include <limits> 00034 #include <typeinfo> 00035 00036 #include "GtpInputStream.h" 00037 #include "GtpOutputStream.h" 00038 00039 #ifndef GTPENGINE_PONDER 00040 /** Macro for enabling pondering. 00041 If this macro is enabled, GtpEngine has the additional functions 00042 Ponder(), InitPonder() and StopPonder(), which will be called while 00043 waiting for the next command. This can be used for thinking during the 00044 opponent's time. 00045 Enabling this macro adds a dependency on the Boost.Thread library. 00046 @see GtpEngine::Ponder() */ 00047 #define GTPENGINE_PONDER 1 00048 #endif 00049 00050 #ifndef GTPENGINE_INTERRUPT 00051 /** Macro for enabling interrupt ability. 00052 If this macro is enabled, GtpEngine has the additional function 00053 Interrupt() to interrupt a running command. 00054 Enabling this macro adds a dependency on the Boost.Thread library. 00055 @see GtpEngine::Interrupt() */ 00056 #define GTPENGINE_INTERRUPT 1 00057 #endif 00058 00059 //---------------------------------------------------------------------------- 00060 00061 /** GTP failure. 00062 Command handlers generate a GTP error response by throwing an instance 00063 of GtpFailure. 00064 It contains an internal string stream for building the reponse using 00065 stream output operators. 00066 To make formatting of responses with a temporary object more convenient, 00067 operator<< uses non-standard semantics, such that a new object is 00068 returned. 00069 Usage examples: 00070 @verbatim 00071 // OK. Construct with string 00072 throw GtpFailure("message"); 00073 00074 // OK. Use temporary object 00075 throw GtpFailure() << message << ...; 00076 00077 // NOT OK. Object is not modified, the return value of << is ignored 00078 GtpFailure failure; 00079 failure << message << ...; 00080 throw failure; 00081 00082 // OK. Use the internal string stream 00083 GtpFailure failure; 00084 failure.ResponseStream() << message << ...; 00085 throw failure; 00086 @endverbatim */ 00087 class GtpFailure 00088 { 00089 public: 00090 /** Construct with no message. */ 00091 GtpFailure(); 00092 00093 /** Construct with message. */ 00094 GtpFailure(const std::string& response); 00095 00096 /** Copy constructor. 00097 Needed for operator<<. 00098 Preserves the internal string stream format state. */ 00099 GtpFailure(const GtpFailure& failure); 00100 00101 /** Destructor. */ 00102 ~GtpFailure() throw(); 00103 00104 /** Get the response. 00105 Returns a copy of the text in the internal string stream. */ 00106 std::string Response() const; 00107 00108 /** Get the internal string stream. */ 00109 std::ostream& ResponseStream(); 00110 00111 private: 00112 std::ostringstream m_response; 00113 }; 00114 00115 /** @relates GtpFailure 00116 @note Returns a new object, see @ref GtpFailure */ 00117 template<typename TYPE> 00118 GtpFailure operator<<(const GtpFailure& failure, const TYPE& type) 00119 { 00120 GtpFailure result(failure); 00121 result.ResponseStream() << type; 00122 return result; 00123 } 00124 00125 /** @relates GtpFailure 00126 @note Returns a new object, see @ref GtpFailure */ 00127 template<typename TYPE> 00128 GtpFailure operator<<(const GtpFailure& failure, TYPE& type) 00129 { 00130 GtpFailure result(failure); 00131 result.ResponseStream() << type; 00132 return result; 00133 } 00134 00135 inline std::string GtpFailure::Response() const 00136 { 00137 return m_response.str(); 00138 } 00139 00140 inline std::ostream& GtpFailure::ResponseStream() 00141 { 00142 return m_response; 00143 } 00144 00145 //---------------------------------------------------------------------------- 00146 00147 /** GTP command. 00148 GtpCommands are passed to command handlers. 00149 They can be queried for arguments and used for writing the response to. 00150 00151 Arguments can contain spaces if they are double quoted, for instance: 00152 @verbatim loadsgf "My File.sgf" @endverbatim 00153 Double quotes in a quoted argument have to be escaped with '\'. 00154 00155 The response message format does not have any special requirement, 00156 it will be sanitized by GtpEngine before writing to form a valid 00157 GTP response (see @ref GtpEngine::MainLoop). */ 00158 00159 class GtpCommand 00160 { 00161 public: 00162 /** Construct empty command. 00163 @warning An empty command cannot be used, before Init() was called. 00164 This constructor exists only to reuse instances. */ 00165 GtpCommand(); 00166 00167 /** Construct with a command line. 00168 @see Init() */ 00169 GtpCommand(const std::string& line); 00170 00171 /** Conversion to output stream. 00172 Returns reference to response stream. */ 00173 operator std::ostream&(); 00174 00175 /** Get argument. 00176 @param number Argument index starting with 0 00177 @return Argument value 00178 @throws GtpFailure If no such argument */ 00179 const std::string& Arg(std::size_t number) const; 00180 00181 /** Get single argument. 00182 @return Argument value 00183 @throws GtpFailure If no such argument or command has more than one 00184 arguments */ 00185 const std::string& Arg() const; 00186 00187 /** Get argument converted to lowercase. 00188 @param number Argument index starting with 0 00189 @return Copy of argument value converted to lowercase 00190 @throws GtpFailure If no such argument */ 00191 std::string ArgToLower(std::size_t number) const; 00192 00193 /** Get argument converted to a type. 00194 This function allows to parse any argument type that implements 00195 <tt>operator<<(istream)</tt>. 00196 @param i Argument index starting with 0 00197 @return The converted argument 00198 @throws Failure If no such argument, or argument cannot be converted */ 00199 template<typename T> 00200 T Arg(std::size_t i) const; 00201 00202 /** Get single argument converted to a type. 00203 This function allows to parse any argument type that implements 00204 <tt>operator<<(istream)</tt>. 00205 @return The converted argument 00206 @throws Failure If no such argument, argument cannot be converted or 00207 command has more than one arguments */ 00208 template<typename T> 00209 T Arg() const; 00210 00211 /** Get argument converted to a type and check for a minimum value. 00212 This function allows to parse any argument type that implements 00213 <tt>operator<<(istream)</tt>. 00214 @param i Argument index starting with 0 00215 @param min The minimum value 00216 @return The converted argument 00217 @throws Failure If no such argument, argument cannot be converted, 00218 or is less than the minimum value */ 00219 template<typename T> 00220 T ArgMin(std::size_t i, const T& min) const; 00221 00222 /** Get argument converted to a type and check for a range. 00223 This function allows to parse any argument type that implements 00224 <tt>operator<<(istream)</tt>. 00225 @param i Argument index starting with 0 00226 @param min The minimum value of the range 00227 @param max The maximum value of the range 00228 @return The converted argument 00229 @throws Failure If no such argument, argument cannot be converted, 00230 or is not contained in the range. */ 00231 template<typename T> 00232 T ArgMinMax(std::size_t i, const T& min, const T& max) const; 00233 00234 /** Check that command has no arguments. 00235 @throws GtpFailure If command has arguments */ 00236 void CheckArgNone() const; 00237 00238 /** Check number of arguments. 00239 @param number Expected number of arguments 00240 @throws GtpFailure If command has a different number of arguments */ 00241 void CheckNuArg(std::size_t number) const; 00242 00243 /** Check maximum number of arguments. 00244 @param number Expected maximum number of arguments 00245 @throws GtpFailure If command has more arguments */ 00246 void CheckNuArgLessEqual(std::size_t number) const; 00247 00248 /** Get command ID. 00249 @return ID or empty string, if command has no ID */ 00250 std::string ID() const; 00251 00252 /** Initialize with a command line. 00253 The line should be not empty, not contain only whitespaces and not 00254 be a comment line. 00255 It will be split into the optional numeric command ID, the command 00256 name, and arguments. */ 00257 void Init(const std::string& line); 00258 00259 /** Get argument line. 00260 Get all arguments as a line. 00261 No modfications to the line were made apart from trimmimg leading 00262 and trailing white spaces. */ 00263 std::string ArgLine() const; 00264 00265 /** Get command line. 00266 Returns full command line as given to the constructor or 00267 GtpCommand::Init. 00268 No modfications to the line were made apart from trimmimg leading 00269 and trailing white spaces. */ 00270 const std::string& Line() const; 00271 00272 /** Get argument name. */ 00273 const std::string& Name() const; 00274 00275 /** Get number of arguments. */ 00276 std::size_t NuArg() const; 00277 00278 /** Return remaining line after argument. 00279 @param number Argument index starting with 0 00280 @return The remaining line after the given argument, unmodified apart 00281 from leading and trailing whitespaces, which are trimmed. Quotation 00282 marks are not handled. 00283 @throws GtpFailure If no such argument */ 00284 std::string RemainingLine(std::size_t number) const; 00285 00286 /** Get response. 00287 @return A copy of the internal response string stream */ 00288 std::string Response() const; 00289 00290 /** Get internal response string stream */ 00291 std::ostringstream& ResponseStream(); 00292 00293 /** Set response. */ 00294 void SetResponse(const std::string& response); 00295 00296 /** Set response to "true" or "false". */ 00297 void SetResponseBool(bool value); 00298 00299 00300 /** @name Deprecated functions 00301 Will be removed in the future. */ 00302 // @{ 00303 00304 /** Deprecated 00305 @deprecated Use Arg<bool>() instead */ 00306 bool BoolArg(std::size_t number) const; 00307 00308 /** Deprecated 00309 @deprecated Use Arg<double>() instead */ 00310 double FloatArg(std::size_t number) const; 00311 00312 /** Deprecated 00313 @deprecated Use Arg<int>() instead */ 00314 int IntArg(std::size_t number) const; 00315 00316 /** Deprecated 00317 @deprecated Use ArgMin<int>() instead */ 00318 int IntArg(std::size_t number, int min) const; 00319 00320 /** Deprecated 00321 @deprecated Use ArgMinMax<int>() instead */ 00322 int IntArg(std::size_t number, int min, int max) const; 00323 00324 /** Deprecated 00325 @deprecated Use Arg<size_t>() instead */ 00326 std::size_t SizeTypeArg(std::size_t number) const; 00327 00328 /** Deprecated 00329 @deprecated Use ArgMin<size_t>() instead */ 00330 std::size_t SizeTypeArg(std::size_t number, std::size_t min) const; 00331 00332 // @} 00333 00334 private: 00335 /** Argument in command line. */ 00336 struct Argument 00337 { 00338 /** Argument value. 00339 Enclosing quotes are removed if there were any and escape 00340 characters within enclosing quotes are removed. */ 00341 std::string m_value; 00342 00343 /** Position of first character in m_line after this argument. */ 00344 std::size_t m_end; 00345 00346 Argument(const std::string& value, std::size_t end); 00347 }; 00348 00349 /** Dummy stream for copying default formatting settings. */ 00350 static std::ostringstream s_dummy; 00351 00352 /** ID of command or empty string, if command has no ID */ 00353 std::string m_id; 00354 00355 /** Full command line. */ 00356 std::string m_line; 00357 00358 /** Response stream */ 00359 std::ostringstream m_response; 00360 00361 /** Arguments of command. */ 00362 std::vector<Argument> m_arguments; 00363 00364 void ParseCommandId(); 00365 00366 void SplitLine(const std::string& line); 00367 }; 00368 00369 /** @relates GtpCommand */ 00370 template<typename TYPE> 00371 GtpCommand& operator<<(GtpCommand& cmd, const TYPE& type) 00372 { 00373 cmd.ResponseStream() << type; 00374 return cmd; 00375 } 00376 00377 /** @relates GtpCommand */ 00378 template<typename TYPE> 00379 GtpCommand& operator<<(GtpCommand& cmd, TYPE& type) 00380 { 00381 cmd.ResponseStream() << type; 00382 return cmd; 00383 } 00384 00385 inline GtpCommand::GtpCommand() 00386 { 00387 } 00388 00389 inline GtpCommand::GtpCommand(const std::string& line) 00390 { 00391 Init(line); 00392 } 00393 00394 inline GtpCommand::operator std::ostream&() 00395 { 00396 return ResponseStream(); 00397 } 00398 00399 template<typename T> 00400 T GtpCommand::Arg(std::size_t i) const 00401 { 00402 std::string s = Arg(i); 00403 std::istringstream in(s); 00404 T result; 00405 in >> result; 00406 if (! in) 00407 throw GtpFailure() << "argument " << (i + 1) << " (" << s 00408 << ") must be of type " << typeid(T).name(); 00409 return result; 00410 } 00411 00412 /** Specialization of Arg<T> for T=size_t to work around a GCC bug. 00413 Workaround for bug in standard library of some GCC versions (e.g. GCC 00414 4.4.1 on Ubuntu 9.10): negative numbers are parsed without error as 00415 size_t. The definition of this function is in GtpEngine.cpp, otherwise 00416 GCC 4.5.5 produces a link error, but there must be the function 00417 declaration in this header file, otherwise Visual Studio 2010 produces a 00418 link error. */ 00419 template<> 00420 std::size_t GtpCommand::Arg<std::size_t>(std::size_t i) const; 00421 00422 template<typename T> 00423 inline T GtpCommand::Arg() const 00424 { 00425 CheckNuArg(1); 00426 return Arg<T>(0); 00427 } 00428 00429 template<typename T> 00430 T GtpCommand::ArgMin(std::size_t i, const T& min) const 00431 { 00432 T result = Arg<T>(i); 00433 if (result < min) 00434 throw GtpFailure() << "argument " << (i + 1) << " (" << result 00435 << ") must be greater or equal " << min; 00436 return result; 00437 } 00438 00439 template<typename T> 00440 T GtpCommand::ArgMinMax(std::size_t i, const T& min, const T& max) const 00441 { 00442 T result = ArgMin(i, min); 00443 if (result > max) 00444 throw GtpFailure() << "argument " << (i + 1) << " (" << result 00445 << ") must be less or equal " << max; 00446 return result; 00447 } 00448 00449 inline void GtpCommand::CheckArgNone() const 00450 { 00451 CheckNuArg(0); 00452 } 00453 00454 inline std::string GtpCommand::ID() const 00455 { 00456 return m_id; 00457 } 00458 00459 inline const std::string& GtpCommand::Line() const 00460 { 00461 return m_line; 00462 } 00463 00464 inline const std::string& GtpCommand::Name() const 00465 { 00466 return m_arguments[0].m_value; 00467 } 00468 00469 inline std::size_t GtpCommand::NuArg() const 00470 { 00471 return m_arguments.size() - 1; 00472 } 00473 00474 inline std::string GtpCommand::Response() const 00475 { 00476 return m_response.str(); 00477 } 00478 00479 inline std::ostringstream& GtpCommand::ResponseStream() 00480 { 00481 return m_response; 00482 } 00483 00484 //---------------------------------------------------------------------------- 00485 00486 /** Abstract base class for command handlers. */ 00487 class GtpCallbackBase 00488 { 00489 public: 00490 virtual ~GtpCallbackBase() throw(); 00491 00492 virtual void operator()(GtpCommand&) = 0; 00493 }; 00494 00495 //---------------------------------------------------------------------------- 00496 00497 /** Member function command handlers. 00498 For registering member functions in GtpEngine::Register(). 00499 @note Instances keep a pointer to the object containing the member 00500 function. If the object does is not a subclass of GtpEngine and registers 00501 only its own members, you have to make sure that the object's lifetime 00502 exceeds the lifetime of the GtpEngine. */ 00503 template<class ENGINE> 00504 class GtpCallback 00505 : public GtpCallbackBase 00506 { 00507 public: 00508 /** Signature of the member function. */ 00509 typedef void (ENGINE::*Method)(GtpCommand&); 00510 00511 GtpCallback(ENGINE* instance, 00512 typename GtpCallback<ENGINE>::Method method); 00513 00514 ~GtpCallback() throw(); 00515 00516 /** Execute the member function. */ 00517 void operator()(GtpCommand&); 00518 00519 private: 00520 ENGINE* m_instance; 00521 00522 Method m_method; 00523 }; 00524 00525 template<class ENGINE> 00526 GtpCallback<ENGINE>::GtpCallback(ENGINE* instance, 00527 typename GtpCallback<ENGINE>::Method method) 00528 : m_instance(instance), 00529 m_method(method) 00530 { 00531 } 00532 00533 template<class ENGINE> 00534 GtpCallback<ENGINE>::~GtpCallback() throw() 00535 { 00536 #ifndef NDEBUG 00537 m_instance = 0; 00538 #endif 00539 } 00540 00541 template<class ENGINE> 00542 void GtpCallback<ENGINE>::operator()(GtpCommand& cmd) 00543 { 00544 (m_instance->*m_method)(cmd); 00545 } 00546 00547 //---------------------------------------------------------------------------- 00548 00549 /** @page gtpenginesimulatedelay Simulated Delays 00550 If the engine receives a special comment line 00551 <code># gtpengine-sleep n</code>, it will sleep for @c n seconds before 00552 reading the next line. This feature can be used for adding simulated 00553 delays in test GTP scripts (e.g. to test pondering functionality). 00554 Note that the start time for sleeping is at the start of the previous 00555 command, not when the response to the previous command is received, 00556 because GtpEngine continues reading the stream while the previous command 00557 is in progress. This functionality is only enabled, if GtpEngine was 00558 compiled with GTPENGINE_INTERRUPT. */ 00559 00560 /** Base class for GTP (Go Text Protocol) engines. 00561 Commands can be added with GtpEngine::Register(). 00562 Existing commands can be overridden by registering a new handler for 00563 the command or by overriding the command handler member function 00564 in subclasses. 00565 @see @ref gtpenginecommands, @ref gtpenginesimulatedelay 00566 @bug With newer versions of Boost, there is an assertion triggered in 00567 debug mode if a GTP command handler throws an exception other than 00568 GtpFailure. See http://sourceforge.net/apps/trac/fuego/ticket/59 */ 00569 class GtpEngine 00570 { 00571 public: 00572 /** @page gtpenginecommands GtpEngine Commands 00573 - @link CmdKnownCommand() @c known_command @endlink 00574 - @link CmdListCommands() @c list_commands @endlink 00575 - @link CmdName() @c name @endlink 00576 - @link CmdProtocolVersion() @c protocol_version @endlink 00577 - @link CmdQuit() @c quit @endlink 00578 - @link CmdVersion() @c version @endlink */ 00579 /** @name Command Callbacks */ 00580 // @{ 00581 virtual void CmdKnownCommand(GtpCommand&); 00582 virtual void CmdListCommands(GtpCommand&); 00583 virtual void CmdName(GtpCommand&); 00584 virtual void CmdProtocolVersion(GtpCommand&); 00585 virtual void CmdQuit(GtpCommand&); 00586 virtual void CmdVersion(GtpCommand&); 00587 // @} // @name 00588 00589 GtpEngine(); 00590 00591 virtual ~GtpEngine(); 00592 00593 /** Execute commands from file. 00594 Aborts on the first command that fails. 00595 @param name The file name 00596 @param log Stream for logging the commands and responses to (default 00597 is std::cerr). 00598 @throw GtpFailure If a command fails */ 00599 void ExecuteFile(const std::string& name, std::ostream& log = std::cerr); 00600 00601 /** Execute a single command string. 00602 @param cmd The command line 00603 @param log Stream for logging the command and response to (default 00604 is std::cerr). 00605 @returns The command response 00606 @throw GtpFailure If the command fails */ 00607 std::string ExecuteCommand(const std::string& cmd, 00608 std::ostream& log = std::cerr); 00609 00610 /** Run the main command loop. 00611 Reads lines from input stream, calls the corresponding command 00612 handler and writes the response to the output stream. 00613 Empty lines in the command responses will be replaced by a line 00614 containing a single space, because empty lines are not allowed 00615 in GTP responses. 00616 @param in Input GTP stream 00617 @param out Output GTP stream */ 00618 void MainLoop(GtpInputStream& in, GtpOutputStream& out); 00619 00620 /** Register command handler. 00621 Takes ownership of callback. 00622 If a command was already registered with the same name, 00623 it will be replaced by the new command. */ 00624 void Register(const std::string& name, GtpCallbackBase* callback); 00625 00626 /** Register a member function as a command handler. 00627 If a command was already registered with the same name, 00628 it will be replaced by the new command. */ 00629 template<class T> 00630 void Register(const std::string& command, 00631 typename GtpCallback<T>::Method method, T* instance); 00632 00633 /** Returns if command registered. */ 00634 bool IsRegistered(const std::string& command) const; 00635 00636 /** Set flag for quitting the main command loop. 00637 Currently, this function works only for the "quit" command, if the 00638 engine is compiled with interrupt functionality (GTENGINE_INTERRUPT). 00639 Therefore, it is not possible for other commands to decide to quit 00640 (which would be necessary for instance to implement a maximal game 00641 number if playing on KGS and deciding to quit on the kgs-game_over 00642 command, if the maximum number is reached). 00643 00644 The reason is that the command stream is then read from a different 00645 thread using a blocking, non-interruptible read function, which is 00646 entered before the command handler is invoked in the main thread. 00647 Because of the non-interruptible read function, the implementation of 00648 GtpEngine needs to know what commands will quit to avoid entering this 00649 read function after a quit. 00650 00651 If a way is found to interrupt the read thread during the execution 00652 of the blocking std::getline (maybe in a future version of 00653 Boost.Thread), this function could also be called in other GTP 00654 commands. 00655 @see MainLoop() */ 00656 void SetQuit(); 00657 00658 /** Did the last command set the quit flag? */ 00659 bool IsQuitSet() const; 00660 00661 #if GTPENGINE_PONDER 00662 /** Ponder. 00663 This function will be called in MainLoop() while the engine is waiting 00664 for the next command. 00665 It will be called after InitPonder() from a different thread than 00666 the command thread, but only while waiting for the next command, so 00667 no concurrent execution of this function and other engine functions 00668 is possible. The function should return immediately when StopPonder() 00669 is called. InitPonder() and StopPonder() are called from the 00670 command thread. 00671 In a typical implementation, InitPonder() will clear an abort flag and 00672 StopPonder() will set it. Ponder() will poll the abort flag and return 00673 when it is set (or it has nothing to do; or some maximum time limit 00674 for pondering was exceeded). 00675 The default implementation does nothing and returns immediately. */ 00676 virtual void Ponder(); 00677 00678 /** Prepare for pondering. 00679 @see Ponder() 00680 The default implementation does nothing. */ 00681 virtual void InitPonder(); 00682 00683 /** Stop pondering. 00684 @see Ponder() 00685 The default implementation does nothing. */ 00686 virtual void StopPonder(); 00687 #endif // GTPENGINE_PONDER 00688 00689 #if GTPENGINE_INTERRUPT 00690 /** Interrupt the current command. 00691 This function implements interrupt functionality as used by 00692 <a href="http://gogui.sf.net">GoGui</a>. It will be called from a 00693 different thread that the command thread when the special command 00694 line <tt># interrupt</tt> is received. 00695 The default implementation does nothing. */ 00696 virtual void Interrupt(); 00697 #endif // GTPENGINE_INTERRUPT 00698 00699 protected: 00700 /** Hook function to be executed before each command. 00701 Default implementation does nothing. */ 00702 virtual void BeforeHandleCommand(); 00703 00704 /** Hook function to be executed before the response of a command is 00705 written. 00706 Default implementation does nothing. */ 00707 virtual void BeforeWritingResponse(); 00708 00709 private: 00710 typedef std::map<std::string,GtpCallbackBase*> CallbackMap; 00711 00712 bool m_quit; 00713 00714 CallbackMap m_callbacks; 00715 00716 /** Not to be implemented. */ 00717 GtpEngine(const GtpEngine& engine); 00718 00719 /** Not to be implemented. */ 00720 GtpEngine& operator=(const GtpEngine& engine) const; 00721 00722 bool HandleCommand(GtpCommand& cmd, GtpOutputStream& out); 00723 }; 00724 00725 template<class T> 00726 void GtpEngine::Register(const std::string& command, 00727 typename GtpCallback<T>::Method method, T* instance) 00728 { 00729 Register(command, new GtpCallback<T>(instance, method)); 00730 } 00731 00732 //---------------------------------------------------------------------------- 00733 00734 #endif // GTPENGINE_H