vasingletonmethods.hpp 4.63 KB
Newer Older
1 2 3 4 5 6
#include <Python.h>
#include <VANetClient.h>
#include <VACore.h>
#include <VAException.h>
#include <string.h>

7
// If you want to extend the va Python pSelf interface, also add
8 9 10 11
// the function to the va_methods table in vasingleton.cpp - otherwise they will not show up.
// Documentation goes into vasingletondoc.hpp

static IVANetClient* g_pVANetClient = nullptr; //!< Static pointer to VANetClient instance
12
static PyObject* g_pVAError = nullptr; //!< Static pointer to error instance
13

14 15 16 17
// Ugly definitions to ease try-catching VA exceptions
#define VAPY_REQUIRE_CONN_TRY try { RequireCoreAvailable();
#define VAPY_CATCH_RETURN } catch (const CVAException& oError) { PyErr_SetString(PyExc_Exception, oError.ToString().c_str()); return NULL; }

18
//! Helper for API dev
19
static PyObject* va_not_implemented(PyObject* pSelf, PyObject** ppArgs, Py_ssize_t nArgs, PyObject* pKeywordNames)
20 21 22
{
	VA_EXCEPT_NOT_IMPLEMENTED;
	return NULL;
23
};
24

25 26 27
//! Raises an exception if core is not available
static void RequireCoreAvailable()
{
28 29
	if (!g_pVANetClient)
		VA_EXCEPT2(CVAException::NETWORK_ERROR, "VA client not available, please connect first");
30

31 32 33
	if (!g_pVANetClient->GetCoreInstance())
		VA_EXCEPT2(CVAException::NETWORK_ERROR, "VA client available, but access to VA interface failed. Please reconnect.");
};
34

35
static PyObject* va_connect(PyObject* pSelf, PyObject** ppArgs, Py_ssize_t nArgs, PyObject* pKeywordNames)
36
{
37
	if (!g_pVANetClient)
38 39
		g_pVANetClient = IVANetClient::Create();

40
	if (g_pVANetClient->IsConnected())
41
	{
42
		PyErr_WarnEx(NULL, "Was still connected, forced disconnect.", 1 );
43
		g_pVANetClient->Disconnect();
44 45 46
	}

	static const char * const _keywords[] = { "server", "port", NULL };
47
	static _PyArg_Parser _parser = { "|si:connect", _keywords, 0 };
48
	char* pcServerIP = nullptr;
49 50
	int iServerPort = 12340;

51
	if (!_PyArg_ParseStack(ppArgs, nArgs, pKeywordNames, &_parser, &pcServerIP, &iServerPort))
52
		return NULL;
53

54
	std::string sServerIP = pcServerIP ? std::string(pcServerIP) : "localhost";
55

56 57 58 59
	if (IVANetClient::VA_NO_ERROR == g_pVANetClient->Initialize(sServerIP, iServerPort))
		return PyBool_FromLong(1);

	PyErr_SetString(PyExc_ConnectionError, std::string("Could not connect to " + sServerIP + " on " + std::to_string((long)iServerPort)).c_str());
60
	return NULL;
61
};
62

63
static PyObject* va_disconnect(PyObject* pSelf, PyObject** ppArgs, Py_ssize_t nArgs, PyObject* pKeywordNames)
64
{
65
	if (g_pVANetClient)
66 67 68 69 70 71 72
	{
		if (g_pVANetClient->IsConnected())
		{
			g_pVANetClient->Disconnect();
			return PyBool_FromLong(1);
		}
	}
73

74
	PyErr_WarnEx(NULL, "Was not connected, doing nothing. Use is_connected to avoid this message.", 1);
75 76
	return PyBool_FromLong(1);
};
77

78
static PyObject* va_is_connected(PyObject* pSelf, PyObject** ppArgs, Py_ssize_t nArgs, PyObject* pKeywordNames)
79
{
80 81
	if (!g_pVANetClient)
		return PyBool_FromLong(0);
82
	else
83 84
		return PyBool_FromLong(g_pVANetClient->IsConnected());
};
85

86
static PyObject* va_reset(PyObject*, PyObject*)
87
{
88
	VAPY_REQUIRE_CONN_TRY;
89 90

	g_pVANetClient->GetCoreInstance()->Reset();
91
	return PyBool_FromLong(1);
92

93 94
	VAPY_CATCH_RETURN;
};
95

96
static PyObject* va_enumerate_modules(PyObject* pSelf, PyObject** ppArgs, Py_ssize_t nArgs, PyObject* pKeywordNames)
97
{
98
	VAPY_REQUIRE_CONN_TRY;
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113

	std::vector< CVAModuleInfo > voModuleInfos;
	g_pVANetClient->GetCoreInstance()->EnumerateModules(voModuleInfos);

	PyObject *pModuleList = PyList_New(voModuleInfos.size());

	for (size_t i = 0; i < voModuleInfos.size(); i++)
	{
		CVAModuleInfo& oModule(voModuleInfos[i]);
		PyObject* pModuleInfo = Py_BuildValue("{s:i,s:s,s:s}", "index", i, "name", oModule.sName, "description", oModule.sDesc);
		PyList_SetItem(pModuleList, i, pModuleInfo); // steals reference
	}

	return pModuleList;

114 115 116 117
	VAPY_CATCH_RETURN;
};

static PyObject* va_call_module(PyObject* pSelf, PyObject** ppArgs, Py_ssize_t nArgs, PyObject* pKeywordNames)
118
{
119
	VAPY_REQUIRE_CONN_TRY;
120
	VA_EXCEPT_NOT_IMPLEMENTED;
121 122 123 124
	VAPY_CATCH_RETURN;
};

static PyObject* va_add_search_path(PyObject* pSelf, PyObject** ppArgs, Py_ssize_t nArgs, PyObject* pKeywordNames)
125
{
126
	VAPY_REQUIRE_CONN_TRY;
127

128 129 130 131 132 133 134
	static const char * const _keywords[] = { "directory_path", NULL };
	static _PyArg_Parser _parser = { "s:add_search_path", _keywords, 0 };
	char* pcPath = nullptr;
	if (!_PyArg_ParseStack(ppArgs, nArgs, pKeywordNames, &_parser, &pcPath))
		return NULL;

	return PyBool_FromLong(g_pVANetClient->GetCoreInstance()->AddSearchPath(std::string(pcPath)));
135

136 137 138 139
	VAPY_CATCH_RETURN;
};

static PyObject* va_create_listener(PyObject* pSelf, PyObject** ppArgs, Py_ssize_t nArgs, PyObject* pKeywordNames)
140
{
141
	VAPY_REQUIRE_CONN_TRY;
142 143

	std::string sName = "PyListener";
144
	int iID = g_pVANetClient->GetCoreInstance()->CreateListener(sName, IVACore::VA_AURAMODE_ALL);
145

146 147 148 149
	return PyLong_FromLong(iID);
	
	VAPY_CATCH_RETURN;
};