Ejemplo n.º 1
0
bool EventListener::Compile()
{
	Rocket::Core::String function_name(64, "Event_%x", this);
	Rocket::Core::String function_code(64, "def %s():", function_name.CString());

	Rocket::Core::StringList lines;
	Rocket::Core::StringUtilities::ExpandString(lines, source_code, ';');
	for (size_t i = 0; i < lines.size(); i++)
	{
		// Python doesn't handle \r's, strip em and indent the code correctly
		function_code += Rocket::Core::String(1024, "\n\t%s", lines[i].CString()).Replace("\r", "");
	}

	ROCKET_ASSERT(element != NULL);

	PyObject* py_namespace = GetGlobalNamespace();

	// Add our function to the namespace
	PyObject* result = PyRun_String(function_code.CString(), Py_file_input, py_namespace, py_namespace);
	if (!result)
	{
		Rocket::Core::Python::Utilities::PrintError();		
		return false;
	}
	Py_DECREF(result);

	// Get a handle to our function
	callable = PyDict_GetItemString(py_namespace, function_name.CString());
	Py_INCREF(callable);

	return true;
}
Ejemplo n.º 2
0
void EventListener::ProcessEvent(Event& event)
{
	// If we've got nothing to do, abort
	if (!callable && source_code.Empty())
		return;

	// Do we need to compile the code?
	if (!callable && !source_code.Empty())
	{
		// Attempt to compile the code
		if (!Compile())
			return;
	}

	PyObject* py_namespace = GetGlobalNamespace();

	// Store current globals
	PyObject* old_event = PyDict_GetItemString(py_namespace, "event");
	PyObject* old_self = PyDict_GetItemString(py_namespace, "self");
	PyObject* old_document = PyDict_GetItemString(py_namespace, "document");
	// Clear any pending errors (KeyErrors if they didn't exist)
	PyErr_Clear();

	// Increase the ref to store the old values locally
	Py_XINCREF(old_event);
	Py_XINCREF(old_self);
	Py_XINCREF(old_document);

	// Set up the new expected globals
	PyDict_SetItemString(py_namespace, "event", Rocket::Core::Python::Utilities::MakeObject(&event).ptr());
	PyDict_SetItemString(py_namespace, "self", Rocket::Core::Python::Utilities::MakeObject(element).ptr());

	// Call the bound function
	PyObject* result = NULL;
	try
	{
		result = PyObject_CallObject(callable, NULL);
	}
	catch (python::error_already_set&)
	{		
	}

	// Check error conditions
	if (result)
	{
		Py_DECREF(result);
	}
	else
	{		
		Rocket::Core::Python::Utilities::PrintError(true);
	}

	// Remove the globals
	PyDict_DelItemString(py_namespace, "document");
	PyDict_DelItemString(py_namespace, "self");
	PyDict_DelItemString(py_namespace, "event");

	// Restore old events if necessary
	if (old_event)
	{
		PyDict_SetItemString(py_namespace, "event", old_event);
		Py_DECREF(old_event);
	}
	if (old_self)
	{
		PyDict_SetItemString(py_namespace, "self", old_self);
		Py_DECREF(old_self);
	}
	if (old_document)
	{
		PyDict_SetItemString(py_namespace, "document", old_document);
		Py_DECREF(old_document);
	}
}