Add returnable python commands

requires modified abstractscreenrenderer
This commit is contained in:
2025-01-08 02:19:22 +01:00
parent bb2894d86c
commit 9b6b941d30
4 changed files with 427 additions and 1 deletions

View File

@@ -105,6 +105,32 @@ void render_task::run() {
if( outputwidth != nullptr ) { Py_DECREF( outputwidth ); }
Py_DECREF( output );
}
// get commands from renderer
auto *commandsPO = PyObject_CallMethod(m_renderer, "getCommands", nullptr);
std::vector<std::string> commands = python_external_utils::PyObjectToStringArray(commandsPO);
Py_DECREF(commandsPO);
// we perform any actions ONLY when there are any commands in buffer
if (!commands.empty())
{
for (const auto &command : commands)
{
auto it = simulation::commandMap.find(command);
if (it != simulation::commandMap.end())
{
// command found
command_data cd;
cd.command = it->second;
cd.action = GLFW_PRESS;
simulation::Commands.push(cd, static_cast<std::size_t>(command_target::vehicle) | 1); // player train is always 1
}
else
ErrorLog("Python: Command [" + command + "] not found!");
}
}
}
void render_task::upload()
@@ -470,6 +496,43 @@ python_taskqueue::error() {
}
}
std::vector<std::string> python_external_utils::PyObjectToStringArray(PyObject *pyList)
{
std::vector<std::string> result;
if (!PySequence_Check(pyList))
{
ErrorLog("Provided PyObject is not a sequence.");
return result;
}
Py_ssize_t size = PySequence_Size(pyList);
for (Py_ssize_t i = 0; i < size; ++i)
{
PyObject *item = PySequence_GetItem(pyList, i); // Increments reference count
if (item == nullptr)
{
ErrorLog("Failed to get item from sequence.");
return result;
}
const char *str = PyString_AsString(item);
if (str == nullptr)
{
Py_DECREF(item);
ErrorLog("Failed to convert item to string.");
return result;
}
result.push_back(std::string(str));
Py_DECREF(item); // Decrease reference count for the item
}
return result;
}
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif