From 50f167898fe6d13496aa62c9204421b83c430640 Mon Sep 17 00:00:00 2001 From: Roy Falk Date: Wed, 2 Oct 2024 23:29:09 +0300 Subject: [PATCH] Refactor python code (#873) * Refactor python code Replace project specific macros with original boost python ones. Add python unit test - demonstrates how to properly call a python module from C++ Delete unused files - mmorpg Add missing imports Replace include command.h with proper header file for that cpp file (rendertext) --- engine/CMakeLists.txt | 9 + engine/src/cmd/base_init.cpp | 100 +++--- engine/src/cmd/script/director_generic.cpp | 34 +- engine/src/cmd/script/director_server.cpp | 8 +- engine/src/components/tests/python_tests.py | 4 + engine/src/gfx/halo_system.h | 2 + engine/src/mmorpgclient.cpp | 325 -------------------- engine/src/mmorpgclient.h | 65 ---- engine/src/python/briefing_wrapper.cpp | 25 +- engine/src/python/python_class.h | 6 +- engine/src/python/unit_wrapper.cpp | 4 +- engine/src/rendertext.cpp | 60 ++-- engine/src/resource/python_utils.cpp | 45 +++ engine/src/resource/python_utils.h | 35 +++ engine/src/resource/tests/python_tests.cpp | 143 +++++++++ engine/src/vegastrike.h | 1 - engine/src/vs_globals.cpp | 2 + engine/src/vs_globals.h | 1 + 18 files changed, 357 insertions(+), 512 deletions(-) create mode 100644 engine/src/components/tests/python_tests.py delete mode 100644 engine/src/mmorpgclient.cpp delete mode 100644 engine/src/mmorpgclient.h create mode 100644 engine/src/resource/python_utils.cpp create mode 100644 engine/src/resource/python_utils.h create mode 100644 engine/src/resource/tests/python_tests.cpp diff --git a/engine/CMakeLists.txt b/engine/CMakeLists.txt index a0407d0c37..f81f8b0c91 100644 --- a/engine/CMakeLists.txt +++ b/engine/CMakeLists.txt @@ -712,6 +712,7 @@ SET(LIBRESOURCE src/resource/product.cpp src/resource/cargo.cpp src/resource/manifest.cpp + src/resource/python_utils.cpp src/resource/random_utils.cpp src/cmd/json.cpp ) @@ -1720,6 +1721,7 @@ IF (USE_GTEST) src/resource/tests/resource_test.cpp src/resource/tests/manifest_tests.cpp src/resource/tests/random_tests.cpp + src/resource/tests/python_tests.cpp src/exit_unit_tests.cpp src/components/tests/energy_container_tests.cpp src/components/tests/balancing_tests.cpp @@ -1744,6 +1746,8 @@ IF (USE_GTEST) TARGET_LINK_LIBRARIES( ${TEST_NAME} + ${Boost_LIBRARIES} + ${Python3_LIBRARIES} gtest_main vegastrike-testing Boost::log @@ -1767,6 +1771,11 @@ IF (USE_GTEST) DESTINATION ${CMAKE_BINARY_DIR}/test_assets ) + FILE( + COPY "src/components/tests/python_tests.py" + DESTINATION ${CMAKE_BINARY_DIR} + ) + INCLUDE(GoogleTest) gtest_discover_tests(${TEST_NAME}) ENDIF (USE_GTEST) diff --git a/engine/src/cmd/base_init.cpp b/engine/src/cmd/base_init.cpp index 6ba73c56a6..79b7544541 100644 --- a/engine/src/cmd/base_init.cpp +++ b/engine/src/cmd/base_init.cpp @@ -82,60 +82,60 @@ static boost::python::tuple GetRandomBarMessage() { } } -PYTHON_BEGIN_MODULE(Base) - PYTHON_DEFINE_GLOBAL(Base, &BaseUtil::Room, "Room"); - PYTHON_DEFINE_GLOBAL(Base, &BaseUtil::SetCurRoom, "SetCurRoom"); - PYTHON_DEFINE_GLOBAL(Base, &BaseUtil::GetCurRoom, "GetCurRoom"); - PYTHON_DEFINE_GLOBAL(Base, &BaseUtil::GetNumRoom, "GetNumRoom"); - PYTHON_DEFINE_GLOBAL(Base, &BaseUtil::GetNumRoom, "HasObject"); - PYTHON_DEFINE_GLOBAL(Base, &BaseUtil::Comp, "Comp"); - PYTHON_DEFINE_GLOBAL(Base, &BaseUtil::CompPython, "CompPython"); - PYTHON_DEFINE_GLOBAL(Base, &BaseUtil::Launch, "Launch"); - PYTHON_DEFINE_GLOBAL(Base, &BaseUtil::LaunchPython, "LaunchPython"); - PYTHON_DEFINE_GLOBAL(Base, &BaseUtil::Link, "Link"); - PYTHON_DEFINE_GLOBAL(Base, &BaseUtil::LinkPython, "LinkPython"); - PYTHON_DEFINE_GLOBAL(Base, &BaseUtil::Python, "Python"); - PYTHON_DEFINE_GLOBAL(Base, &BaseUtil::EraseLink, "EraseLink"); - PYTHON_DEFINE_GLOBAL(Base, &BaseUtil::Ship, "Ship"); - PYTHON_DEFINE_GLOBAL(Base, &BaseUtil::Texture, "Texture"); - PYTHON_DEFINE_GLOBAL(Base, &BaseUtil::Video, "Video"); - PYTHON_DEFINE_GLOBAL(Base, &BaseUtil::VideoStream, "VideoStream"); - PYTHON_DEFINE_GLOBAL(Base, &BaseUtil::PlayVideo, "PlayVideo"); - PYTHON_DEFINE_GLOBAL(Base, &BaseUtil::StopVideo, "StopVideo"); - PYTHON_DEFINE_GLOBAL(Base, &BaseUtil::SetVideoCallback, "SetVideoCallback"); - PYTHON_DEFINE_GLOBAL(Base, &BaseUtil::SetDJEnabled, "SetDJEnabled"); - PYTHON_DEFINE_GLOBAL(Base, &BaseUtil::SetTexture, "SetTexture"); - PYTHON_DEFINE_GLOBAL(Base, &BaseUtil::SetTextureSize, "SetTextureSize"); - PYTHON_DEFINE_GLOBAL(Base, &BaseUtil::SetTexturePos, "SetTexturePos"); - PYTHON_DEFINE_GLOBAL(Base, &BaseUtil::EnqueueMessageToRoom, "EnqueueMessageToRoom"); - PYTHON_DEFINE_GLOBAL(Base, &BaseUtil::MessageToRoom, "MessageToRoom"); - PYTHON_DEFINE_GLOBAL(Base, &BaseUtil::EnqueueMessage, "EnqueueMessage"); - PYTHON_DEFINE_GLOBAL(Base, &BaseUtil::Message, "Message"); - PYTHON_DEFINE_GLOBAL(Base, &BaseUtil::EraseObj, "EraseObj"); - PYTHON_DEFINE_GLOBAL(Base, &::GetRandomBarMessage, "GetRandomBarMessage"); - PYTHON_DEFINE_GLOBAL(Base, &BaseUtil::RunScript, "RunScript"); - PYTHON_DEFINE_GLOBAL(Base, &BaseUtil::TextBox, "TextBox"); - PYTHON_DEFINE_GLOBAL(Base, &BaseUtil::SetTextBoxText, "SetTextBoxText"); - PYTHON_DEFINE_GLOBAL(Base, &BaseUtil::GlobalKeyPython, "GlobalKeyPython"); - PYTHON_DEFINE_GLOBAL(Base, &BaseUtil::SetLinkArea, "SetLinkArea"); - PYTHON_DEFINE_GLOBAL(Base, &BaseUtil::SetLinkText, "SetLinkText"); - PYTHON_DEFINE_GLOBAL(Base, &BaseUtil::SetLinkPython, "SetLinkPython"); - PYTHON_DEFINE_GLOBAL(Base, &BaseUtil::SetLinkRoom, "SetLinkRoom"); - PYTHON_DEFINE_GLOBAL(Base, &BaseUtil::SetLinkEventMask, "SetLinkEventMask"); - PYTHON_DEFINE_GLOBAL(Base, &BaseUtil::BuyShip, "BuyShip"); - PYTHON_DEFINE_GLOBAL(Base, &BaseUtil::SellShip, "SellShip"); +BOOST_PYTHON_MODULE(Base) { + boost::python::def("Room", &BaseUtil::Room); + boost::python::def("SetCurRoom", &BaseUtil::SetCurRoom); + boost::python::def("GetCurRoom", &BaseUtil::GetCurRoom); + boost::python::def("GetNumRoom", &BaseUtil::GetNumRoom); + boost::python::def("HasObject", &BaseUtil::GetNumRoom); + boost::python::def("Comp", &BaseUtil::Comp); + boost::python::def("CompPython", &BaseUtil::CompPython); + boost::python::def("Launch", &BaseUtil::Launch); + boost::python::def("LaunchPython", &BaseUtil::LaunchPython); + boost::python::def("Link", &BaseUtil::Link); + boost::python::def("LinkPython", &BaseUtil::LinkPython); + boost::python::def("Python", &BaseUtil::Python); + boost::python::def("EraseLink", &BaseUtil::EraseLink); + boost::python::def("Ship", &BaseUtil::Ship); + boost::python::def("Texture", &BaseUtil::Texture); + boost::python::def("Video", &BaseUtil::Video); + boost::python::def("VideoStream", &BaseUtil::VideoStream); + boost::python::def("PlayVideo", &BaseUtil::PlayVideo); + boost::python::def("StopVideo", &BaseUtil::StopVideo); + boost::python::def("SetVideoCallback", &BaseUtil::SetVideoCallback); + boost::python::def("SetDJEnabled", &BaseUtil::SetDJEnabled); + boost::python::def("SetTexture", &BaseUtil::SetTexture); + boost::python::def("SetTextureSize", &BaseUtil::SetTextureSize); + boost::python::def("SetTexturePos", &BaseUtil::SetTexturePos); + boost::python::def("EnqueueMessageToRoom", &BaseUtil::EnqueueMessageToRoom); + boost::python::def("MessageToRoom", &BaseUtil::MessageToRoom); + boost::python::def("EnqueueMessage", &BaseUtil::EnqueueMessage); + boost::python::def("Message", &BaseUtil::Message); + boost::python::def("EraseObj", &BaseUtil::EraseObj); + boost::python::def("GetRandomBarMessage", &::GetRandomBarMessage); + boost::python::def("RunScript", &BaseUtil::RunScript); + boost::python::def("TextBox", &BaseUtil::TextBox); + boost::python::def("SetTextBoxText", &BaseUtil::SetTextBoxText); + boost::python::def("GlobalKeyPython", &BaseUtil::GlobalKeyPython); + boost::python::def("SetLinkArea", &BaseUtil::SetLinkArea); + boost::python::def("SetLinkText", &BaseUtil::SetLinkText); + boost::python::def("SetLinkPython", &BaseUtil::SetLinkPython); + boost::python::def("SetLinkRoom", &BaseUtil::SetLinkRoom); + boost::python::def("SetLinkEventMask", &BaseUtil::SetLinkEventMask); + boost::python::def("BuyShip", &BaseUtil::BuyShip); + boost::python::def("SellShip", &BaseUtil::SellShip); - PYTHON_DEFINE_GLOBAL(Base, &BaseUtil::SetEventData, "SetEventData"); - PYTHON_DEFINE_GLOBAL(Base, &BaseUtil::SetMouseEventData, "SetMouseEventData"); - PYTHON_DEFINE_GLOBAL(Base, &::GetEventDataPython, "GetEventData"); + boost::python::def("SetEventData", &BaseUtil::SetEventData); + boost::python::def("SetMouseEventData", &BaseUtil::SetMouseEventData); + boost::python::def("GetEventData", &::GetEventDataPython); - PYTHON_DEFINE_GLOBAL(Base, &BaseUtil::GetTextWidth, "GetTextWidth"); - PYTHON_DEFINE_GLOBAL(Base, &BaseUtil::GetTextHeight, "GetTextHeight"); + boost::python::def("GetTextWidth", &BaseUtil::GetTextWidth); + boost::python::def("GetTextHeight", &BaseUtil::GetTextHeight); - PYTHON_DEFINE_GLOBAL(Base, &BaseUtil::LoadBaseInterface, "LoadBaseInterface"); - PYTHON_DEFINE_GLOBAL(Base, &BaseUtil::ExitGame, "ExitGame"); + boost::python::def("LoadBaseInterface", &BaseUtil::LoadBaseInterface); + boost::python::def("ExitGame", &BaseUtil::ExitGame); -PYTHON_END_MODULE(Base) +} void InitBase() { PyImport_AppendInittab("Base", PYTHON_MODULE_INIT_FUNCTION(Base)); diff --git a/engine/src/cmd/script/director_generic.cpp b/engine/src/cmd/script/director_generic.cpp index 5e834b6d70..b85eb3dd73 100644 --- a/engine/src/cmd/script/director_generic.cpp +++ b/engine/src/cmd/script/director_generic.cpp @@ -329,7 +329,7 @@ static bool isUtf8SaveGamePy(string savegame) { return isUtf8SaveGame(savegame); } -PYTHON_BEGIN_MODULE(Director) +BOOST_PYTHON_MODULE(Director) { PYTHON_BEGIN_INHERIT_CLASS(Director, pythonMission, PythonMissionBaseClass, "Mission") PYTHON_DEFINE_METHOD_DEFAULT(Class, &PythonMissionBaseClass::Pickle, "Pickle", pythonMission::default_Pickle); PYTHON_DEFINE_METHOD_DEFAULT(Class, @@ -341,22 +341,22 @@ PYTHON_BEGIN_MODULE(Director) "Execute", pythonMission::default_Execute); PYTHON_END_CLASS(Director, pythonMission) - PYTHON_DEFINE_GLOBAL(Director, &putSaveDataPy, "putSaveData"); - PYTHON_DEFINE_GLOBAL(Director, &pushSaveDataPy, "pushSaveData"); - PYTHON_DEFINE_GLOBAL(Director, &eraseSaveDataPy, "eraseSaveData"); - PYTHON_DEFINE_GLOBAL(Director, &clearSaveDataPy, "clearSaveData"); - PYTHON_DEFINE_GLOBAL(Director, &getSaveDataPy, "getSaveData"); - PYTHON_DEFINE_GLOBAL(Director, &getSaveDataLengthPy, "getSaveDataLength"); - PYTHON_DEFINE_GLOBAL(Director, &putSaveStringPy, "putSaveString"); - PYTHON_DEFINE_GLOBAL(Director, &pushSaveStringPy, "pushSaveString"); - PYTHON_DEFINE_GLOBAL(Director, &getSaveStringPy, "getSaveString"); - PYTHON_DEFINE_GLOBAL(Director, &getSaveStringLengthPy, "getSaveStringLength"); - PYTHON_DEFINE_GLOBAL(Director, &eraseSaveStringPy, "eraseSaveString"); - PYTHON_DEFINE_GLOBAL(Director, &clearSaveStringPy, "clearSaveString"); - PYTHON_DEFINE_GLOBAL(Director, &loadStringListPy, "loadStringList"); - PYTHON_DEFINE_GLOBAL(Director, &saveStringListPy, "saveStringList"); - PYTHON_DEFINE_GLOBAL(Director, &isUtf8SaveGamePy, "isUtf8SaveGame"); -PYTHON_END_MODULE(Director) + boost::python::def("putSaveData", &putSaveDataPy); + boost::python::def("pushSaveData", &pushSaveDataPy); + boost::python::def("eraseSaveData", &eraseSaveDataPy); + boost::python::def("clearSaveData", &clearSaveDataPy); + boost::python::def("getSaveData", &getSaveDataPy); + boost::python::def("getSaveDataLength", &getSaveDataLengthPy); + boost::python::def("putSaveString", &putSaveStringPy); + boost::python::def("pushSaveString", &pushSaveStringPy); + boost::python::def("getSaveString", &getSaveStringPy); + boost::python::def("getSaveStringLength", &getSaveStringLengthPy); + boost::python::def("eraseSaveString", &eraseSaveStringPy); + boost::python::def("clearSaveString", &clearSaveStringPy); + boost::python::def("loadStringList", &loadStringListPy); + boost::python::def("saveStringList", &saveStringListPy); + boost::python::def("isUtf8SaveGame", &isUtf8SaveGamePy); +} void InitDirector() { PyImport_AppendInittab("Director", PYTHON_MODULE_INIT_FUNCTION(Director)); diff --git a/engine/src/cmd/script/director_server.cpp b/engine/src/cmd/script/director_server.cpp index f7799cb9ba..963c9d9acc 100644 --- a/engine/src/cmd/script/director_server.cpp +++ b/engine/src/cmd/script/director_server.cpp @@ -46,13 +46,13 @@ #include "cmd/unit_generic.h" #include "mission.h" -PYTHON_BEGIN_MODULE(Base) +BOOST_PYTHON_MODULE(Base) { //Nothing here, but keeps those files that do a "import Base" happy. -PYTHON_END_MODULE(Base) +} -PYTHON_BEGIN_MODULE(Briefing) +BOOST_PYTHON_MODULE(Briefing) { //Nothing here, but keeps those files that do a "import Briefing" happy. -PYTHON_END_MODULE(Briefing) +} void InitBase() { PyImport_AppendInittab("Base", PYTHON_MODULE_INIT_FUNCTION(Base)); diff --git a/engine/src/components/tests/python_tests.py b/engine/src/components/tests/python_tests.py new file mode 100644 index 0000000000..d668a1967c --- /dev/null +++ b/engine/src/components/tests/python_tests.py @@ -0,0 +1,4 @@ + + +def append(first, second): + return first+second diff --git a/engine/src/gfx/halo_system.h b/engine/src/gfx/halo_system.h index 82d01d64b5..c4bc3894f0 100644 --- a/engine/src/gfx/halo_system.h +++ b/engine/src/gfx/halo_system.h @@ -27,6 +27,8 @@ #define VEGA_STRIKE_ENGINE_GFX_HALOSYSTEM_H #include +#include + #include "matrix.h" class Mesh; struct GFXColor; diff --git a/engine/src/mmorpgclient.cpp b/engine/src/mmorpgclient.cpp deleted file mode 100644 index 22d0e81a63..0000000000 --- a/engine/src/mmorpgclient.cpp +++ /dev/null @@ -1,325 +0,0 @@ -/* - * Copyright (C) 2001-2022 Daniel Horn, pyramid3d, Stephen G. Tuggy, - * and other Vega Strike contributors. - * - * https://github.com/vegastrike/Vega-Strike-Engine-Source - * - * This file is part of Vega Strike. - * - * Vega Strike is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Vega Strike is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Vega Strike. If not, see . - */ - -#include "command.h" -#include "mmorpgclient.h" -#include "SDL/SDL.h" -#include "SDL_thread.h" -#include "vegastrike.h" -#include "vs_globals.h" - -//#ifdef WIN32 -//#include // For socket(), connect(), send(), and recv() -//typedef int socklen_t; -//#else -//#include // For data types -//#include // For socket(), connect(), send(), and recv() -//#include // For gethostbyname() -//#include // For inet_addr() -//#include // For close() -//#include // For sockaddr_in -//#endif -#include "networking/inet.h" - -//This is created in command.cpp with single like (search for mmoc) -//If you wish to disable this module, just comment out that single line in command.cpp, -//and don't compile this .cpp file. - -mmoc::mmoc() { - //{{{ - status = false; //used to let the thread exit - binmode = false; - POSmode = false; - INET_startup(); - //add the connectto to the players command interp. - cmd = new Functor(this, &mmoc::connectTo); - CommandInterpretor->addCommand(cmd, "connectto"); - //{{{ - //add commands here to be parsed from network input. - //some notes: - //just make them like normal, and the word "FOO" will be the "tag" that triggers it. - //eg: the server sends args, the input routines will parse it to: - //FOO , and try sending it through the LOCAL command processor (NOT the main one used for the player console). - - //now some notes more to myself - //The users console at the highest level (in the main ship rendering routines) will need to gather data from the mmoc console to render it there. - //and never call mmoc::renderconsole. I'll need to make a mutex'd function for this. - //}}} -} //}}} -void mmoc::connectTo(const char *address_in, const char *port_in) { - //{{{ -//sockaddr_in m_addr; - char *address = (char *) address_in; - char *port = (char *) port_in; - if (address == NULL) { - CommandInterpretor->conoutf("Need a host at least, a host and port at most!"); - return; - } - if (port == NULL) { - port = "5555"; - } - std::string test; - test.append(address); - if (test.compare("default") == 0) { - address = "ant.infice.com"; - port = "5555"; - } - if ((socket = INET_ConnectTo(address, atoi(port))) < 0) { - CommandInterpretor->conoutf( - "Error connecting. Specify another host or verify the status if your network connection."); - return; - } -//hostent *server; // Resolve name -//if ((server = gethostbyname(address)) == NULL) { -//CommandInterpretor->conoutf("Error, couldn't find host"); - //strerror() will not work for gethostbyname() and hstrerror() - //is supposedly obsolete -//return; -//} - -//bzero((char *) &m_addr, sizeof(m_addr)); -//m_addr.sin_family = AF_INET; -//bcopy((char *)server->h_addr, -//(char *)&m_addr.sin_addr.s_addr, -//server->h_length); -//m_addr.sin_port = htons(atoi(port)); -//int status = 0; - -//if ( (status = ::connect(socket,reinterpret_cast(&m_addr),sizeof(m_addr))) < 0) { -//CommandInterpretor->conoutf("Couldn't Connect\n"); -//return; -//} - std::string hellomsg; - hellomsg.append("Vegastrike-user"); - send(hellomsg); - cl = new Functor(this, &mmoc::close); - CommandInterpretor->addCommand(cl, "disconnect"); - - csay = new Functor(this, &mmoc::send); - CommandInterpretor->addCommand(csay, "send"); - - createThread(); -} //}}} -bool mmoc::getStatus(int in) { - //{{{ -//if in = 0, return status, else toggle status. - SDL_mutex *m = SDL_CreateMutex(); - SDL_mutexP(m); - if (in != 0) { - status = !status; - } - bool returner = status; - SDL_mutexV(m); - SDL_DestroyMutex(m); - return returner; -} //}}} -void mmoc::ParseRemoteInput(char *buf) { - //{{{ Main parser -//add binary modes here. - if (buf != NULL) { - start.append(buf); - } - size_t teststart; - if ((teststart = start.find("\n")) < std::string::npos) { - //we have a full string and are ready to process - if (teststart < start.size() - 2) { - for (unsigned int soda = teststart + 1; soda < start.size(); soda++) { - tempstr += start[soda]; - } - while (start.size() > teststart) { - std::string::iterator iter = start.end(); - iter--; - start.erase(iter); //pop goes the weasle - } - } - } else { -//return; - } - unsigned int end = start.size(); - std::string hackedup; - bool open = false, ignore2close = false; - unsigned int fopend = 0; - unsigned int counter; - //parse commands to be executed - for (counter = 0; counter < end; counter++) { - if (open) { - if (start[counter] == '=') { - hackedup.append("\" "); - } else if (start[counter] == '>') { - open = false; - start.replace(fopend, (counter + 1) - fopend, ""); - unsigned int offset = (counter + 1) - fopend; - counter = counter - offset; - commandI::execute(&hackedup, true, socket); - hackedup.erase(); - end = start.size(); - } else { - hackedup += start[counter]; - } - } else if (start[counter] == '<') { - open = true; - fopend = counter; - hackedup.append("\""); - } - } - //optimize by moving this above. - unsigned int ender = start.size(); - for (counter = 0; counter < ender; counter++) { //remove \r's - if (start[counter] == '\r') { - start.replace(counter, 1, ""); - counter = counter - 2; - ender = start.size(); - } - } - CommandInterpretor->conoutf(start); //print what's left to the console - - start.erase(); - if (tempstr.size() > 0) { - start.append(tempstr); - tempstr.erase(); - } - { - size_t asdf; - while ((asdf = start.find("\n")) < std::string::npos) { - ParseRemoteInput(NULL); - } -//if(start.size() > 0 ) { -//start.append("\n\r"); -//ParseRemoteInput(NULL); -//} - } -} //}}} -class POSpack { -public: - int playernum; //who's position is this - double x, y, z; //the position -}; - -bool mmoc::listenThread() { - //{{{ - const int MAXBUF = 1000; - char buffer[MAXBUF + 1]; - bool stat; - while ((stat = getStatus(0)) == true) { - bzero(buffer, MAXBUF); - if (!binmode) { - if (::INET_Recv(socket, buffer, sizeof(buffer) - 1) <= 0) { - getStatus(1); //1 toggles status, 0 reads status - return false; - } else { - ParseRemoteInput(buffer); - } - } - if (binmode) { - if (POSmode) { - //if Position mode - POSpack position; - if (::INET_Read(socket, reinterpret_cast< char * > (&position), sizeof(POSpack)) <= 0) { - //I believe INET_Read will keep looping until size is filled - getStatus(1); //toggle status - return false; - } - ParseMovement(position); - POSmode = false; - } - //other bin modes - binmode = false; //done - } - } - /*---Clean up---*/ - return stat; -} //}}} -void mmoc::createThread() { - //{{{ - ::SDL_CreateThread(startThread, reinterpret_cast< void * > (this)); -} //}}} -void mmoc::send(char *buffer, int size) { - //{{{ - ::INET_Write(socket, size, buffer); //or write(socket, buffer, size) for windwos? -} //}}} -void mmoc::send(std::string &instring) { - //{{{ - unsigned int x = instring.find("send "); - if (x == 0) { - instring.replace(0, 5, ""); - } - instring.append("\r\n"); - send((char *) instring.c_str(), instring.size()); -} //}}} -void mmoc::negotiate(std::vector *d) { - std::vector::iterator iter = d->begin(); - iter++; - if (iter >= d->end()) { - return; - } //nothing to negotiate - if ((*(iter))->compare("P")) { - binarysize = sizeof(POSpack); - //check the next iterator for a number (X), if there is one - //set it up to loop in the listenThread() to read X Position packets - binmode = true; - POSmode = true; - std::string ack; - ack.append("ap"); //ack position, tell the server to send it - send(ack); - } -} - -void mmoc::ParseMovement(POSpack &in) { - //..... -} - -int startThread(void *mmoc2use) { - //{{{ - mmoc *looper = reinterpret_cast< mmoc * > (mmoc2use); - if (!looper->getStatus(0)) { - looper->getStatus(1); - } - CommandInterpretor->conoutf("Connected."); - while (looper->listenThread()) { - } - ::close(looper->getSocket()); - CommandInterpretor->remCommand(looper->csay); - CommandInterpretor->remCommand(looper->cl); - CommandInterpretor->conoutf("Closed"); - if (looper->getStatus(0)) { - looper->getStatus(1); - } - return 0; -} //}}} -void mmoc::close() { - if (getStatus(0)) { - getStatus(1); - } -} - -void mmoc::conoutf(std::string &in, int x, int y, int z) { - CommandInterpretor->conoutf(in, x, y, z); -} -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - * vim600: sw=4 ts=4 fdm=marker - * vim<600: sw=4 ts=4 - */ - diff --git a/engine/src/mmorpgclient.h b/engine/src/mmorpgclient.h deleted file mode 100644 index 7ce773daa0..0000000000 --- a/engine/src/mmorpgclient.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2001-2023 Daniel Horn, pyramid3d, Stephen G. Tuggy, Benjamen R. Meyer, - * and other Vega Strike contributors. - * - * https://github.com/vegastrike/Vega-Strike-Engine-Source - * - * This file is part of Vega Strike. - * - * Vega Strike is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Vega Strike is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Vega Strike. If not, see . - */ -// NO HEADER GUARD -// well, technically the MMPORGC_INC acts as one... -#ifndef MMORPGC_INC -#define MMORPGC_INC 1 - -//linux version is int -//extern commandI CommandInterpretor; -class POSpack; -class mmoc : public commandI { -//sockaddr_in m_addr; - int socket; - std::string start; //holds strings waiting to be processed - std::string tempstr; //holds temporary strings - bool status; - int binarysize; - bool binmode; //bypass string processing - bool POSmode; //expect position packet -public: - bool getStatus(int); //also sets it, mutex'd - mmoc(); - - int getSocket() { - return socket; - } - - void connectTo(const char *host, const char *port); - void negotiate(std::vector *d); - bool listenThread(); - void createThread(); - void send(char *buffer, int size); - void send(std::string &string); - void ParseBinaryData(std::vector &in); - void ParseMovement(POSpack &in); - void mmoc::ParseRemoteInput(char *buf); - virtual void conoutf(std::string &, int x = 0, int y = 0, int z = 0); - void close(); - Functor *cmd; - Functor *cl; //disconnect/close - Functor *csay; -}; - -int startThread(void *mmoc2use); -#endif //MMORPGC_INC - diff --git a/engine/src/python/briefing_wrapper.cpp b/engine/src/python/briefing_wrapper.cpp index 27a89cb7e5..4fe9e7e1af 100644 --- a/engine/src/python/briefing_wrapper.cpp +++ b/engine/src/python/briefing_wrapper.cpp @@ -74,18 +74,19 @@ void setCloak(int whichship, float cloak) { mission->briefing->SetCloak(whichship, cloak); } } -PYTHON_BEGIN_MODULE(Briefing) - PYTHON_DEFINE_GLOBAL(Briefing, &BriefingUtil::addShip, "addShip"); - PYTHON_DEFINE_GLOBAL(Briefing, &BriefingUtil::removeShip, "removeShip"); - PYTHON_DEFINE_GLOBAL(Briefing, &BriefingUtil::enqueueOrder, "enqueueOrder"); - PYTHON_DEFINE_GLOBAL(Briefing, &BriefingUtil::replaceOrder, "replaceOrder"); - PYTHON_DEFINE_GLOBAL(Briefing, &BriefingUtil::getShipPosition, "getShipPosition"); - PYTHON_DEFINE_GLOBAL(Briefing, &BriefingUtil::setShipPosition, "setShipPosition"); - PYTHON_DEFINE_GLOBAL(Briefing, &BriefingUtil::terminate, "terminate"); - PYTHON_DEFINE_GLOBAL(Briefing, &BriefingUtil::setCamPosition, "setCamPosition"); - PYTHON_DEFINE_GLOBAL(Briefing, &BriefingUtil::setCamOrientation, "setCamOrientation"); - PYTHON_DEFINE_GLOBAL(Briefing, &BriefingUtil::setCloak, "setCloak"); -PYTHON_END_MODULE(Briefing) + +BOOST_PYTHON_MODULE(Briefing) { + boost::python::def("addShip", &BriefingUtil::addShip); + boost::python::def("removeShip", &BriefingUtil::removeShip); + boost::python::def("enqueueOrder", &BriefingUtil::enqueueOrder); + boost::python::def("replaceOrder", &BriefingUtil::replaceOrder); + boost::python::def("getShipPosition", &BriefingUtil::getShipPosition); + boost::python::def("setShipPosition", &BriefingUtil::setShipPosition); + boost::python::def("terminate", &BriefingUtil::terminate); + boost::python::def("setCamPosition", &BriefingUtil::setCamPosition); + boost::python::def("setCamOrientation", &BriefingUtil::setCamOrientation); + boost::python::def("setCloak", &BriefingUtil::setCloak); +} void InitBriefing() { PyImport_AppendInittab("Briefing", PYTHON_MODULE_INIT_FUNCTION(Briefing)); diff --git a/engine/src/python/python_class.h b/engine/src/python/python_class.h index 9d4ebc696e..5cb056fc0f 100644 --- a/engine/src/python/python_class.h +++ b/engine/src/python/python_class.h @@ -77,7 +77,7 @@ These following #defines will create a module for python call them with: -PYTHON_BEGIN_MODULE(VS) +BOOST_PYTHON_MODULE(VS) { PYTHON_BEGIN_INHERIT_CLASS(VS,FireAt,"PythonFire") //begins an inherited class with a virtual Execute function... //You can call any other virtual functions by defining: // void callFunction(std::string name){} @@ -97,7 +97,7 @@ PYTHON_BEGIN_MODULE(VS) Class.def(&MyOtherClass::MyOtherFunc,"FunctionName"); PYTHON_END_CLASS(VS,MyOtherClass) VS.def(&MyGlobalFunction,"GlobalFunc") //the global functions are easiest; you can call these in python with VS.globalfunc -PYTHON_END_MODULE(VS) +} ... int main (int argc,char *argv[]) { ... @@ -147,7 +147,6 @@ BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE \ //These two functions purposely have opening/closing braces that don't match up -#define PYTHON_BEGIN_MODULE(name) BOOST_PYTHON_MODULE(name) { #define PYTHON_DEFINE_GLOBAL(modul, fun, funname) boost::python::def (funname,fun) #define VS_BOOST_MAKE_TUPLE(a, b, c) boost::python::make_tuple(a,b,c) #define VS_BOOST_MAKE_TUPLE_2(a, b) boost::python::make_tuple(a,b) @@ -159,7 +158,6 @@ BOOST_PYTHON_BEGIN_CONVERSION_NAMESPACE \ #define PYTHON_MODULE_INIT_FUNCTION(name) PyInit_##name #endif // (PY_VERSION_HEX < 0x03000000) -#define PYTHON_END_MODULE(name) } #define PYTHON_INIT_MODULE(name) PYTHON_MODULE_INIT_FUNCTION(name)() #define PYTHON_BASE_BEGIN_INHERIT_CLASS(name, NewClass, SuperClass, myclass) { \ diff --git a/engine/src/python/unit_wrapper.cpp b/engine/src/python/unit_wrapper.cpp index 956e1b0d53..46321bd47b 100644 --- a/engine/src/python/unit_wrapper.cpp +++ b/engine/src/python/unit_wrapper.cpp @@ -68,7 +68,7 @@ void setOwner(int obj, UnitWrapper un) { } PYTHON_INIT_INHERIT_GLOBALS(VS, FireAt); PYTHON_INIT_INHERIT_GLOBALS(VS, VegaStrike::EngineVersionData); -PYTHON_BEGIN_MODULE(VS) +BOOST_PYTHON_MODULE(VS) { //#undef EXPORT_UTIL //#undef voidEXPORT_UTIL @@ -191,7 +191,7 @@ PYTHON_BEGIN_MODULE(VS) PYTHON_DEFINE_METHOD(Class, &VegaStrike::EngineVersionData::GetAssetAPIVersion, "GetAssetAPIVersion"); PYTHON_END_CLASS(VS, VegaStrike::EngineVersionData) -PYTHON_END_MODULE(VS) +} void InitVS() { PyImport_AppendInittab("VS", PYTHON_MODULE_INIT_FUNCTION(VS)); diff --git a/engine/src/rendertext.cpp b/engine/src/rendertext.cpp index d00fa3d7d1..abf498fa91 100644 --- a/engine/src/rendertext.cpp +++ b/engine/src/rendertext.cpp @@ -23,7 +23,7 @@ //rendertext.cpp: based on Don's gl_text.cpp //Based on Aardarples rendertext -#include "command.h" +#include "rendertext.h" #include "vegastrike.h" #include "cg_global.h" @@ -35,12 +35,8 @@ #include #include #include +#include -using std::vector; -using std::string; -using std::ostringstream; -using std::cout; -using std::endl; //**************** //Console Rendering System by Rogue @@ -101,8 +97,8 @@ void RText::draw_text(std::string &str, float left, float top, int gl_num) { void RText::renderconsole() //render buffer { int nd = 0; - vector refs; - for (vector::iterator iter = conlines.begin(); iter < conlines.end(); iter++) { + std::vector refs; + for (std::vector::iterator iter = conlines.begin(); iter < conlines.end(); iter++) { if (nd < ndraw) { refs.push_back((*(iter)).cref); } else { @@ -112,10 +108,10 @@ void RText::renderconsole() //render buffer } float x = -1; float y = -0.5; - string workIt; + std::string workIt; workIt.append("\n"); bool breakout = true; - vector::iterator iter = refs.end(); + std::vector::iterator iter = refs.end(); if (iter == refs.begin()) { breakout = false; } @@ -128,8 +124,8 @@ void RText::renderconsole() //render buffer workIt.append("\n"); } y = 1; - ostringstream drawCommand; - string shorter; + std::ostringstream drawCommand; + std::string shorter; shorter.append(getcurcommand()); while (shorter.size() > 80) { shorter.erase(shorter.begin()); @@ -137,19 +133,19 @@ void RText::renderconsole() //render buffer //erase the front of the current command while it's larger than 80 //charactors, as to not draw off the screen drawCommand << workIt << "#FF1100> " << "#FF1100" << shorter << "#00000"; - string Acdraw; //passing .str() straight to draw_text produces an + std::string Acdraw; //passing .str() straight to draw_text produces an //error with gcc 4, because it's constant I believe Acdraw.append(drawCommand.str()); draw_text(Acdraw, x, y, 2); } //append a line to the console, optional "highlight" method , untested {{{ -void RText::conline(string &sf, bool highlight) //add a line to the console buffer +void RText::conline(std::string &sf, bool highlight) //add a line to the console buffer { { size_t search = 0; size_t lastsearch = 0; - for (; (search = sf.find("/r")) != string::npos;) { + for (; (search = sf.find("/r")) != std::string::npos;) { sf.replace(lastsearch, search - lastsearch, ""); lastsearch = search; } @@ -169,21 +165,21 @@ void RText::conline(string &sf, bool highlight) //add a line to the conso //print a line to the console, broken at \n's {{{ void RText::conoutf(char *in) { - string foobar(in); + std::string foobar(in); conoutf(foobar); } -void RText::conoutf(string &s, int a, int b, int c) { +void RText::conoutf(std::string &s, int a, int b, int c) { #ifdef HAVE_SDL //NOTE: first call must be single-threaded! SDL_mutex *mymutex = _rtextSDLMutex(); SDL_LockMutex(mymutex); #endif // stephengtuggy 2020-11-22: Leaving for now -- this should perhaps continue to call cout, I'm not sure - cout << s << endl; - string::size_type fries = s.size(); - string customer; - for (string::size_type burger = 0; burger < fries; burger++) { + std::cout << s << std::endl; + std::string::size_type fries = s.size(); + std::string customer; + for (std::string::size_type burger = 0; burger < fries; burger++) { if (s[burger] == '\n' || burger == fries - 1) { if (burger == fries - 1) { if (s[fries - 1] != '\n' && s[fries - 1] != '\r') { @@ -194,17 +190,17 @@ void RText::conoutf(string &s, int a, int b, int c) { customer.erase(); } else if (customer.size() >= static_cast(WORDWRAP)) { customer += s[burger]; - string fliptheburger; + std::string fliptheburger; while (customer[customer.size() - 1] != ' ') { fliptheburger += customer[customer.size() - 1]; - string::iterator oldfloormeat = customer.end(); + std::string::iterator oldfloormeat = customer.end(); oldfloormeat--; customer.erase(oldfloormeat); } conline(customer, 1); customer.erase(); { - string spatchula; + std::string spatchula; for (int salt = fliptheburger.size() - 1; salt >= 0; salt--) { spatchula += fliptheburger[salt]; } @@ -222,21 +218,21 @@ void RText::conoutf(string &s, int a, int b, int c) { } //same as above, but I think it works better {{{ -void RText::conoutn(string &s, int a, int b, int c) { +void RText::conoutn(std::string &s, int a, int b, int c) { size_t x = s.find("\n"); size_t xlast = 0; - if (x >= string::npos) { + if (x >= std::string::npos) { conoutf(s); } - string::iterator iter = s.end(); + std::string::iterator iter = s.end(); if (iter != s.begin()) { iter--; if (strcmp(&(*(iter)), "\n") != 0) { s.append("\n"); }; } - while (x < string::npos) { - string part; + while (x < std::string::npos) { + std::string part; part.append(s.substr(xlast, x - xlast)); xlast = x + 1; x = s.find("\n", x + 1); @@ -256,7 +252,7 @@ void RText::ConsoleKeyboardI(int code, bool isdown) { switch (code) { //pop teh back of commandbuf case WSK_BACKSPACE: { - string::iterator iter = commandbuf.begin(); + std::string::iterator iter = commandbuf.begin(); if (iter < commandbuf.end()) { iter = commandbuf.end(); iter--; @@ -271,7 +267,7 @@ void RText::ConsoleKeyboardI(int code, bool isdown) { case WSK_RETURN: if (commandbuf[0]) { - vector::iterator iter = vhistory.end(); + std::vector::iterator iter = vhistory.end(); bool noSize = false; if (iter <= vhistory.begin() && iter >= vhistory.end()) { noSize = true; @@ -309,7 +305,7 @@ void RText::ConsoleKeyboardI(int code, bool isdown) { //}}} //get the current command buffer, to execute at enter {{{ -string RText::getcurcommand() { +std::string RText::getcurcommand() { return commandbuf; } //footer, leave at bottom diff --git a/engine/src/resource/python_utils.cpp b/engine/src/resource/python_utils.cpp new file mode 100644 index 0000000000..23590f49cb --- /dev/null +++ b/engine/src/resource/python_utils.cpp @@ -0,0 +1,45 @@ +/* + * python_utils.cpp + * + * Copyright (c) 2001-2002 Daniel Horn + * Copyright (c) 2002-2019 pyramid3d and other Vega Strike Contributors + * Copyright (c) 2019-2023 Stephen G. Tuggy, Benjamen R. Meyer, Roy Falk and other Vega Strike Contributors + * + * https://github.com/vegastrike/Vega-Strike-Engine-Source + * + * This file is part of Vega Strike. + * + * Vega Strike is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Vega Strike is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Vega Strike. If not, see . + */ + +// -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- + +#include "python_utils.h" + +#include +#include + +using namespace boost::python; + +const std::string GetPythonPath() { + Py_Initialize(); + wchar_t* w_path_ptr = Py_GetPath(); + Py_Finalize(); + + std::wstring w_path_w( w_path_ptr ); + std::string path( w_path_w.begin(), w_path_w.end() ); + std::cout << "Python path: " << path << std::endl; + + return path; +} \ No newline at end of file diff --git a/engine/src/resource/python_utils.h b/engine/src/resource/python_utils.h new file mode 100644 index 0000000000..083f3f1cbd --- /dev/null +++ b/engine/src/resource/python_utils.h @@ -0,0 +1,35 @@ +/* + * python_utils.h + * + * Copyright (c) 2001-2002 Daniel Horn + * Copyright (c) 2002-2019 pyramid3d and other Vega Strike Contributors + * Copyright (c) 2019-2023 Stephen G. Tuggy, Benjamen R. Meyer, Roy Falk and other Vega Strike Contributors + * + * https://github.com/vegastrike/Vega-Strike-Engine-Source + * + * This file is part of Vega Strike. + * + * Vega Strike is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Vega Strike is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Vega Strike. If not, see . + */ + +// -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- + +#ifndef VEGA_STRIKE_ENGINE_RESOURCE_PYTHON_UTILS_H +#define VEGA_STRIKE_ENGINE_RESOURCE_PYTHON_UTILS_H + +#include + +const std::string GetPythonPath(); + +#endif //VEGA_STRIKE_ENGINE_RESOURCE_PYTHON_UTILS_H \ No newline at end of file diff --git a/engine/src/resource/tests/python_tests.cpp b/engine/src/resource/tests/python_tests.cpp new file mode 100644 index 0000000000..4f3d39734a --- /dev/null +++ b/engine/src/resource/tests/python_tests.cpp @@ -0,0 +1,143 @@ +/* + * python_tests.cpp + * + * Copyright (c) 2001-2002 Daniel Horn + * Copyright (c) 2002-2019 pyramid3d and other Vega Strike Contributors + * Copyright (c) 2019-2023 Stephen G. Tuggy, Benjamen R. Meyer, Roy Falk and other Vega Strike Contributors + * + * https://github.com/vegastrike/Vega-Strike-Engine-Source + * + * This file is part of Vega Strike. + * + * Vega Strike is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * Vega Strike is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Vega Strike. If not, see . + */ + +// -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- + +#include +#include +#include +#include + +#include "python_utils.h" + +using namespace boost::python; + +// This code shows how to call a python file from c++ +// It is not portable + +struct World +{ + World(std::string msg) : msg(msg) {} + void set(std::string msg) { this->msg = msg; } + std::string greet() { return msg; } + std::string msg; +}; + +BOOST_PYTHON_MODULE(python_sanity) +{ + class_("World", init()) + .def("greet", &World::greet) + .def("set", &World::set) + ; +} + +const std::string hello_world = "Hello World\n"; + + +TEST(Python, Sanity) { + World world(hello_world); + + EXPECT_EQ(world.greet(), hello_world); +} + +TEST(Python, Call_Function) { + boost::filesystem::path full_path(boost::filesystem::current_path()); + std::cout << full_path << std::endl; + + bool exists = boost::filesystem::exists("test_assets/python_tests.py"); + std::cout << "python_tests.py exists " << exists << std::endl; + + boost::filesystem::current_path(full_path.concat("/test_assets")); + full_path = boost::filesystem::current_path(); + std::cout << full_path << std::endl; + + exists = boost::filesystem::exists("python_tests.py"); + std::cout << "python_tests.py exists in current folder " << exists << std::endl; + + // Set path is called before + + //const wchar_t* path = L"/usr/lib/python38.zip:/usr/lib/python3.8:/usr/lib/python3.8/lib-dynload:."; + const std::string path_string = GetPythonPath(); + const std::wstring path_wstring = std::wstring(path_string.begin(), path_string.end()); + const wchar_t* path = path_wstring.c_str(); + Py_SetPath(path); + + Py_Initialize(); + + // Use the following code to figure out your original path, as the above Py_SetPath overrides it. + // Note that Py_GetPath must be called after Py_Initialize and Py_SetPath before. + /*wchar_t* w_path_ptr = Py_GetPath(); + std::wstring w_path_w( w_path_ptr ); + std::string path( w_path_w.begin(), w_path_w.end() ); + std::cout << "Path: " << path << std::endl;*/ + + //PyObject* moduleString = PyUnicode_FromString((char*)"python_tests"); + //PyObject* module = PyImport_Import(moduleString); + PyObject* module = PyImport_ImportModule("python_tests"); + std::cout << "PyImport_ImportModule did not crash\n" << std::flush; + if(!module) { + std::cout << "PyImport_ImportModule is null\n" << std::flush; + PyErr_Print(); + Py_Finalize(); + return; + } else { + std::cout << "PyImport_ImportModule is not null\n" << std::flush; + } + + PyObject* function = PyObject_GetAttrString(module,"append"); + std::cout << "PyObject_GetAttrString did not crash\n" << std::flush; + if(function == nullptr) { + std::cout << "PyObject_GetAttrString is null\n" << std::flush; + //PyErr_Print(); + Py_Finalize(); + return; + } else { + std::cout << "PyObject_GetAttrString is not null\n" << std::flush; + } + + PyObject* args = PyTuple_Pack(2, + PyUnicode_FromString("Hello "), + PyUnicode_FromString("World\n")); + std::cout << "PyTuple_Pack did not crash\n" << std::flush; + if(args == nullptr) { + std::cout << "PyTuple_Pack is null\n" << std::flush; + PyErr_Print(); + Py_Finalize(); + return; + } else { + std::cout << "PyTuple_Pack is not null\n" << std::flush; + } + + PyObject* pyResult = PyObject_CallObject(function, args); + std::cout << "PyObject_CallObject\n"; + std::string result = PyUnicode_AsUTF8(pyResult); + std::cout << result << std::endl << std::flush; + Py_Finalize(); + + EXPECT_EQ(result, hello_world); + + // Uncomment to see prints + //EXPECT_FALSE(true); +} \ No newline at end of file diff --git a/engine/src/vegastrike.h b/engine/src/vegastrike.h index 41fed397ea..4b5de10409 100644 --- a/engine/src/vegastrike.h +++ b/engine/src/vegastrike.h @@ -63,7 +63,6 @@ extern float AUDIO_ATOM; #include #include #include -//#include "command.h" #endif //defined (WIN32) || defined (__CYGWIN__) #ifndef NO_GFX diff --git a/engine/src/vs_globals.cpp b/engine/src/vs_globals.cpp index 8242e6d6bb..8e82483990 100644 --- a/engine/src/vs_globals.cpp +++ b/engine/src/vs_globals.cpp @@ -22,6 +22,8 @@ #include "vs_globals.h" #include +#include + /* * Globals */ diff --git a/engine/src/vs_globals.h b/engine/src/vs_globals.h index f9317f547d..2de2435fad 100644 --- a/engine/src/vs_globals.h +++ b/engine/src/vs_globals.h @@ -23,6 +23,7 @@ #define VEGA_STRIKE_ENGINE_VS_GLOBALS_H #include +#include #include "command.h" #include "vs_exit.h"