I'm using pybind11 to expose this game code (written in c++) to python.
The first thing I'm trying to do is, basicly start the game by exposing a start function in the c++ part. So far is looking like this (c++):
#define NOMINMAX
#include "GameWinMain.h"
#include "GameEngine.h"
#include <iostream>
#include "Contra.h"
#include <pybind11/pybind11.h>
namespace py = pybind11;
using namespace std;
#define GAME_ENGINE (GameEngine::GetSingleton())
int start()
{
// Enable run-time memory leak check for debug builds.
#if defined(DEBUG) | defined(_DEBUG)
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
#endif
WinMain(GetModuleHandle(0), 0, 0, SW_SHOW);
return 0;
}
int _tmain()
{
start();
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
if (GAME_ENGINE == NULL) return FALSE; // create the game engine and exit if it fails
GAME_ENGINE->SetGame(new Contra()); // any class that implements AbstractGame
cout << "jogo foi iniciado?";
return GAME_ENGINE->Run(hInstance, iCmdShow); // run the game engine and return the result
}
PYBIND11_MODULE(contra, m)
{
cout << "modulo importado! ";
m.doc() = "contra game";
m.def("start", &start, "starts the contra game");
}
And in the python side is looking like this:
from threading import Thread
from Contra_remake import contra
Thread(target=contra.start, args=()).start()
print('print!')
The problem is, the print line is only executed when the game closes, even starting the game in another thread.
That is beacuse of the GIL (Global Interpreter Lock) of Python. You can read more about it here.
If you want to fix the issue, you should release the GIL manually in your C++ code, as described in this link.
In short, you can change your start method like below to avoid your Python thread to be blocked:
#include <python.h>
class GilManager
{
public:
GilManager()
{
mThreadState = PyEval_SaveThread();
}
~GilManager()
{
if (mThreadState)
PyEval_RestoreThread(mThreadState);
}
GilManager(const GilManager&) = delete;
GilManager& operator=(const GilManager&) = delete;
private:
PyThreadState* mThreadState;
};
int start()
{
GilManager g;
// Enable run-time memory leak check for debug builds.
#if defined(DEBUG) | defined(_DEBUG)
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
#endif
WinMain(GetModuleHandle(0), 0, 0, SW_SHOW);
return 0;
}