From: <geo...@us...> - 2008-02-22 15:46:16
|
Revision: 2351 http://freeorion.svn.sourceforge.net/freeorion/revision/?rev=2351&view=rev Author: geoffthemedio Date: 2008-02-22 07:46:11 -0800 (Fri, 22 Feb 2008) Log Message: ----------- Moved Python-exposed logging to its own file Modified Paths: -------------- trunk/FreeOrion/AI/AIInterface.h trunk/FreeOrion/AI/PythonAI.cpp trunk/FreeOrion/SConscript trunk/FreeOrion/client/AI/AIClientApp.h trunk/FreeOrion/msvc2005/FreeOrion/freeorionca/freeorionca.vcproj trunk/FreeOrion/python/PythonWrappers.h Added Paths: ----------- trunk/FreeOrion/python/PythonLoggingWrapper.cpp Modified: trunk/FreeOrion/AI/AIInterface.h =================================================================== --- trunk/FreeOrion/AI/AIInterface.h 2008-02-22 14:54:12 UTC (rev 2350) +++ trunk/FreeOrion/AI/AIInterface.h 2008-02-22 15:46:11 UTC (rev 2351) @@ -29,64 +29,64 @@ namespace AIInterface { /** Gamestate Accessors */ //@{ - const std::string& PlayerName(); ///< returns the player name of this client - const std::string& PlayerName(int player_id); ///< returns the name of player with \a player_id + const std::string& PlayerName(); ///< returns the player name of this client + const std::string& PlayerName(int player_id); ///< returns the name of player with \a player_id - int PlayerID(); ///< returns the player ID of this client - int EmpirePlayerID(int empire_id); ///< returns ID of player controlling empire with id \a empire_id - std::vector<int> AllPlayerIDs(); ///< returns vector containing IDs of all players in game + int PlayerID(); ///< returns the player ID of this client + int EmpirePlayerID(int empire_id); ///< returns ID of player controlling empire with id \a empire_id + std::vector<int> AllPlayerIDs(); ///< returns vector containing IDs of all players in game - bool PlayerIsAI(int player_id); ///< returns true iff the player with id \a player_id is an AI - bool PlayerIsHost(int player_id); ///< returns true iff the player with id \a player_id is the game host + bool PlayerIsAI(int player_id); ///< returns true iff the player with id \a player_id is an AI + bool PlayerIsHost(int player_id); ///< returns true iff the player with id \a player_id is the game host - int EmpireID(); ///< returns the empire ID of this client - int PlayerEmpireID(int player_id); ///< returns ID of empire controlled by player with id \a player_id - std::vector<int> AllEmpireIDs(); ///< returns vector containing IDs of all empires in game + int EmpireID(); ///< returns the empire ID of this client + int PlayerEmpireID(int player_id); ///< returns ID of empire controlled by player with id \a player_id + std::vector<int> AllEmpireIDs(); ///< returns vector containing IDs of all empires in game - const Empire* GetEmpire(); ///< returns empire of this client's player - const Empire* GetEmpire(int empire_id); ///< returns empire with id \a empire_id + const Empire* GetEmpire(); ///< returns empire of this client's player + const Empire* GetEmpire(int empire_id); ///< returns empire with id \a empire_id - const Universe& GetUniverse(); ///< returns Universe known to this player + const Universe& GetUniverse(); ///< returns Universe known to this player - const Tech* GetTech(const std::string& tech_name); ///< returns Tech with name \a name + const Tech* GetTech(const std::string& tech_name); ///< returns Tech with name \a name - int CurrentTurn(); ///< returns the current game turn + int CurrentTurn(); ///< returns the current game turn //@} /** Gamestate Prediction Utilites */ //@{ - void InitTurn(); ///< intializes and calculates meters, resource pools and queues so info based on latest turn update - void UpdateMeterEstimates(bool pretend_unowned_planets_owned_by_this_ai_empire = true); ///< sets object meters to what they are expected to be during the next turn processing phase, after orders are submitted. if \a pretend_unowned_planets_owned_by_this_ai_empire is true, unowned planets known of by this player will have this player added as an owner before meter values are calculated, so that their max meter values will be what they would be if those planets were colonized by this empire - void UpdateResourcePoolsAndQueues(); ///< determines how much of each resource is available at each object owned by this empire, and updates resource pool amounts and spending on queues accordingly + void InitTurn(); ///< intializes and calculates meters, resource pools and queues so info based on latest turn update + void UpdateMeterEstimates(bool pretend_unowned_planets_owned_by_this_ai_empire = true); ///< sets object meters to what they are expected to be during the next turn processing phase, after orders are submitted. if \a pretend_unowned_planets_owned_by_this_ai_empire is true, unowned planets known of by this player will have this player added as an owner before meter values are calculated, so that their max meter values will be what they would be if those planets were colonized by this empire + void UpdateResourcePoolsAndQueues(); ///< determines how much of each resource is available at each object owned by this empire, and updates resource pool amounts and spending on queues accordingly //@} /** Order-Giving */ //@{ - int IssueRenameOrder(int object_id, const std::string& new_name); + int IssueRenameOrder(int object_id, const std::string& new_name); - int IssueFleetMoveOrder(int fleet_id, int destination_id); - int IssueNewFleetOrder(const std::string& fleet_name, const std::vector<int>& ship_ids); - int IssueNewFleetOrder(const std::string& fleet_name, int ship_id); - int IssueFleetTransferOrder(int ship_id, int new_fleet_id); - int IssueFleetColonizeOrder(int ship_id, int planet_id); - int IssueDeleteFleetOrder(); + int IssueFleetMoveOrder(int fleet_id, int destination_id); + int IssueNewFleetOrder(const std::string& fleet_name, const std::vector<int>& ship_ids); + int IssueNewFleetOrder(const std::string& fleet_name, int ship_id); + int IssueFleetTransferOrder(int ship_id, int new_fleet_id); + int IssueFleetColonizeOrder(int ship_id, int planet_id); + int IssueDeleteFleetOrder(); - int IssueChangeFocusOrder(int planet_id, FocusType focus_type, bool primary); + int IssueChangeFocusOrder(int planet_id, FocusType focus_type, bool primary); - int IssueEnqueueTechOrder(const std::string& tech_name, int position); - int IssueDequeueTechOrder(const std::string& tech_name); + int IssueEnqueueTechOrder(const std::string& tech_name, int position); + int IssueDequeueTechOrder(const std::string& tech_name); - int IssueEnqueueBuildingProductionOrder(const std::string& item_name, int location_id); - int IssueEnqueueShipProductionOrder(int design_id, int location_id); - int IssueRequeueProductionOrder(int old_queue_index, int new_queue_index); - int IssueDequeueProductionOrder(int queue_index); + int IssueEnqueueBuildingProductionOrder(const std::string& item_name, int location_id); + int IssueEnqueueShipProductionOrder(int design_id, int location_id); + int IssueRequeueProductionOrder(int old_queue_index, int new_queue_index); + int IssueDequeueProductionOrder(int queue_index); - void SendPlayerChatMessage(int recipient_player_id, const std::string& message_text); + void SendPlayerChatMessage(int recipient_player_id, const std::string& message_text); - void DoneTurn(); ///< AI player is done submitting orders for this turn + void DoneTurn(); ///< AI player is done submitting orders for this turn //@} /** Logging */ //@{ - void LogOutput(const std::string& log_text); ///< output text to as DEBUG - void ErrorOutput(const std::string& log_text); ///< output text to as ERROR + void LogOutput(const std::string& log_text); ///< output text to as DEBUG + void ErrorOutput(const std::string& log_text); ///< output text to as ERROR //@} }; Modified: trunk/FreeOrion/AI/PythonAI.cpp =================================================================== --- trunk/FreeOrion/AI/PythonAI.cpp 2008-02-22 14:54:12 UTC (rev 2350) +++ trunk/FreeOrion/AI/PythonAI.cpp 2008-02-22 15:46:11 UTC (rev 2351) @@ -12,18 +12,16 @@ #include <boost/lexical_cast.hpp> using boost::python::class_; -using boost::python::bases; using boost::python::def; -using boost::python::iterator; -using boost::python::no_init; -using boost::noncopyable; using boost::python::return_value_policy; using boost::python::copy_const_reference; using boost::python::reference_existing_object; using boost::python::return_by_value; using boost::python::return_internal_reference; + using boost::python::vector_indexing_suite; using boost::python::map_indexing_suite; + using boost::python::object; using boost::python::import; using boost::python::error_already_set; @@ -36,71 +34,35 @@ // Python AIInterface // //////////////////////// // disambiguation of overloaded functions -const std::string& (*AIIntPlayerNameVoid)(void) = &AIInterface::PlayerName; -const std::string& (*AIIntPlayerNameInt)(int) = &AIInterface::PlayerName; +const std::string& (*AIIntPlayerNameVoid)(void) = &AIInterface::PlayerName; +const std::string& (*AIIntPlayerNameInt)(int) = &AIInterface::PlayerName; -const Empire* (*AIIntGetEmpireVoid)(void) = &AIInterface::GetEmpire; -const Empire* (*AIIntGetEmpireInt)(int) = &AIInterface::GetEmpire; +const Empire* (*AIIntGetEmpireVoid)(void) = &AIInterface::GetEmpire; +const Empire* (*AIIntGetEmpireInt)(int) = &AIInterface::GetEmpire; -int (*AIIntNewFleet)(const std::string&, int) = &AIInterface::IssueNewFleetOrder; +int (*AIIntNewFleet)(const std::string&, int) = &AIInterface::IssueNewFleetOrder; namespace { // static s_save_state_string, getter and setter to be exposed to Python static std::string s_save_state_string(""); + static const std::string& GetStaticSaveStateString() { - //Logger().debugStream() << "Python-exposed GetSaveStateString() returning " << s_save_state_string; return s_save_state_string; } + static void SetStaticSaveStateString(const std::string& new_state_string) { s_save_state_string = new_state_string; - //Logger().debugStream() << "Python-exposed SetSaveStateString(" << s_save_state_string << ")"; } } -// Expose interface for redirecting standard output and error to FreeOrion logging. Can be imported -// before loading the main FreeOrion AI interface library. -static const int MAX_SINGLE_CHUNK_TEXT_SIZE = 1000; -static std::string log_buffer(""); -void LogText(const char* text) { - // Python sends text as several null-terminated array of char which need to be - // concatenated before they are output to the logger. There's probably a better - // way to do this, but I don't know what it is, and this seems reasonably safe... - if (!text) return; - for (int i = 0; i < MAX_SINGLE_CHUNK_TEXT_SIZE; ++i) { - if (text[i] == '\0') break; - if (text[i] == '\n' || i == MAX_SINGLE_CHUNK_TEXT_SIZE - 1) { - AIInterface::LogOutput(log_buffer); - log_buffer = ""; - } else { - log_buffer += text[i]; - } - } -} -static std::string error_buffer(""); -void ErrorText(const char* text) { - // Python sends text as several null-terminated array of char which need to be - // concatenated before they are output to the logger. There's probably a better - // way to do this, but I don't know what it is, and this seems reasonably safe... - if (!text) return; - for (int i = 0; i < MAX_SINGLE_CHUNK_TEXT_SIZE; ++i) { - if (text[i] == '\0') break; - if (text[i] == '\n' || i == MAX_SINGLE_CHUNK_TEXT_SIZE - 1) { - AIInterface::ErrorOutput(error_buffer); - error_buffer = ""; - } else { - error_buffer += text[i]; - } - } -} - -// Expose minimal debug and error (stdout and stderr respectively) sinks so Python text output can be -// recovered and saved in c++ +// Create the freeOrionLogger Python module, which exposes debug and error (stdout and stderr respectively) +// sinks so Python text output can be recovered and saved in c++. These can be accessed from within Python +// by freeOrionLogger.log(stringParam) and freeOrionLogger.error(stringParam) BOOST_PYTHON_MODULE(freeOrionLogger) { - def("log", LogText); - def("error", ErrorText); + FreeOrionPython::WrapLogger(); } /** Expose AIInterface and all associated classes to Python. @@ -113,13 +75,7 @@ * return_value_policy<return_by_value> when returning either a simple data type or a temporary object * in a function that will go out of scope after being returned * - * return_internal_reference<> when returning an object or data that is a member of the object - * on which the function is called (and shares its lifetime) - * - * return_value_policy<reference_existing_object> when returning an object from a non-member function, or a - * member function where the returned object's lifetime is not - * fixed to the lifetime of the object on which the function is - * called + * return_value_policy<reference_existing_object> when returning an object from a non-member function */ BOOST_PYTHON_MODULE(freeOrionAIInterface) { @@ -168,9 +124,9 @@ def("doneTurn", AIInterface::DoneTurn); - /////////////////// - // Empire // - /////////////////// + ////////////////// + // Empire // + ////////////////// FreeOrionPython::WrapEmpire(); @@ -180,9 +136,9 @@ FreeOrionPython::WrapUniverseClasses(); - //////////////////// - // Enums // - //////////////////// + /////////////////// + // Enums // + /////////////////// FreeOrionPython::WrapGameStateEnums(); @@ -200,9 +156,9 @@ FreeOrionPython::SetWrapper<std::string>::Wrap("StringSet"); } -/////////////////////// -// PythonAI // -/////////////////////// +////////////////////// +// PythonAI // +////////////////////// static dict s_main_namespace = dict(); static object s_ai_module = object(); static PythonAI* s_ai = 0; Modified: trunk/FreeOrion/SConscript =================================================================== --- trunk/FreeOrion/SConscript 2008-02-22 14:54:12 UTC (rev 2350) +++ trunk/FreeOrion/SConscript 2008-02-22 15:46:11 UTC (rev 2351) @@ -78,7 +78,8 @@ 'AI/PythonAI.cpp', 'python/PythonEnumWrapper.cpp', 'python/PythonUniverseWrapper.cpp', - 'python/PythonEmpireWrapper.cpp' + 'python/PythonEmpireWrapper.cpp', + 'python/PythonLoggingWrapper.cpp' ] target = 'ai' Modified: trunk/FreeOrion/client/AI/AIClientApp.h =================================================================== --- trunk/FreeOrion/client/AI/AIClientApp.h 2008-02-22 14:54:12 UTC (rev 2350) +++ trunk/FreeOrion/client/AI/AIClientApp.h 2008-02-22 15:46:11 UTC (rev 2351) @@ -3,8 +3,9 @@ #define _AIClientApp_h_ #include "../ClientApp.h" -#include "../../AI/AIInterface.h" +class AIBase; + namespace log4cpp {class Category;} /** the application framework for an AI player FreeOrion client.*/ Modified: trunk/FreeOrion/msvc2005/FreeOrion/freeorionca/freeorionca.vcproj =================================================================== --- trunk/FreeOrion/msvc2005/FreeOrion/freeorionca/freeorionca.vcproj 2008-02-22 14:54:12 UTC (rev 2350) +++ trunk/FreeOrion/msvc2005/FreeOrion/freeorionca/freeorionca.vcproj 2008-02-22 15:46:11 UTC (rev 2351) @@ -605,6 +605,10 @@ > </File> <File + RelativePath="..\..\..\Python\PythonLoggingWrapper.cpp" + > + </File> + <File RelativePath="..\..\..\Python\PythonSetWrapper.h" > </File> Added: trunk/FreeOrion/python/PythonLoggingWrapper.cpp =================================================================== --- trunk/FreeOrion/python/PythonLoggingWrapper.cpp (rev 0) +++ trunk/FreeOrion/python/PythonLoggingWrapper.cpp 2008-02-22 15:46:11 UTC (rev 2351) @@ -0,0 +1,55 @@ +#include <string> + +#include "../util/AppInterface.h" + +#include <boost/python.hpp> + +namespace { + // Expose interface for redirecting standard output and error to FreeOrion logging. Can be imported + // before loading the main FreeOrion AI interface library. + static const int MAX_SINGLE_CHUNK_TEXT_SIZE = 1000; + + // stdout logger + static std::string log_buffer(""); + void LogText(const char* text) { + // Python sends text as several null-terminated array of char which need to be + // concatenated before they are output to the logger. There's probably a better + // way to do this, but I don't know what it is, and this seems reasonably safe... + if (!text) return; + for (int i = 0; i < MAX_SINGLE_CHUNK_TEXT_SIZE; ++i) { + if (text[i] == '\0') break; + if (text[i] == '\n' || i == MAX_SINGLE_CHUNK_TEXT_SIZE - 1) { + Logger().debugStream() << log_buffer; + log_buffer = ""; + } else { + log_buffer += text[i]; + } + } + } + + // stderr logger + static std::string error_buffer(""); + void ErrorText(const char* text) { + // Python sends text as several null-terminated array of char which need to be + // concatenated before they are output to the logger. There's probably a better + // way to do this, but I don't know what it is, and this seems reasonably safe... + if (!text) return; + for (int i = 0; i < MAX_SINGLE_CHUNK_TEXT_SIZE; ++i) { + if (text[i] == '\0') break; + if (text[i] == '\n' || i == MAX_SINGLE_CHUNK_TEXT_SIZE - 1) { + Logger().debugStream() << error_buffer; + error_buffer = ""; + } else { + error_buffer += text[i]; + } + } + } +} + +namespace FreeOrionPython { + using boost::python::def; + void WrapLogger() { + def("log", LogText); + def("error", ErrorText); + } +} \ No newline at end of file Modified: trunk/FreeOrion/python/PythonWrappers.h =================================================================== --- trunk/FreeOrion/python/PythonWrappers.h 2008-02-22 14:54:12 UTC (rev 2350) +++ trunk/FreeOrion/python/PythonWrappers.h 2008-02-22 15:46:11 UTC (rev 2351) @@ -7,6 +7,8 @@ void WrapUniverseClasses(); void WrapGameStateEnums(); void WrapEmpire(); + + void WrapLogger(); } #endif \ No newline at end of file |