1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
|
// Cyphesis Online RPG Server and AI Engine
// Copyright (C) 2005 Alistair Riddoch
//
// This program 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.
//
// This program 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 this program; if not, write to the Free Software Foundation,
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
// $Id: ScriptFactory.cpp,v 1.11 2007-12-04 00:04:00 alriddoch Exp $
#include "ScriptFactory.h"
#include "rulesets/Py_Thing.h"
#include "rulesets/Python_Script_Utils.h"
#include "rulesets/PythonThingScript.h"
#include "rulesets/Entity.h"
#include "common/log.h"
#include "common/compose.hpp"
/// \brief ScriptFactory constructor
///
/// @param package name of the script package scripts are to be created from
/// @param type name of the type instanced to create scripts
ScriptFactory::ScriptFactory(const std::string & package,
const std::string & type) : m_package(package),
m_type(type)
{
}
ScriptFactory::~ScriptFactory()
{
}
/// \brief Retrieve the pythonclass object from the module which has
/// already been loaded.
int PythonScriptFactory::getClass()
{
std::string classname(m_type);
classname[0] = toupper(classname[0]);
m_class = PyObject_GetAttrString(m_module, (char *)classname.c_str());
if (m_class == NULL) {
log(ERROR, String::compose("Could not find python class %1.%2",
m_package, classname));
PyErr_Print();
return -1;
}
if (PyCallable_Check(m_class) == 0) {
log(ERROR, String::compose("Could not instance python class %1.%2",
m_package, classname));
Py_DECREF(m_class);
m_class = 0;
return -1;
}
return 0;
}
/// \brief PythonScriptFactory constructor
///
/// @param package Name of the script package where the script type is
/// @param type Name of the scrpt types instanced by this factory
PythonScriptFactory::PythonScriptFactory(const std::string & package,
const std::string & type) :
ScriptFactory(package, type),
m_module(0), m_class(0)
{
// FIXME #4 This sort of code should not be in the constructor
PyObject * package_name = PyString_FromString((char *)m_package.c_str());
m_module = PyImport_Import(package_name);
Py_DECREF(package_name);
if (m_module == NULL) {
log(ERROR, String::compose("Missing python module \"%1\"", m_package));
PyErr_Print();
return;
}
getClass();
}
PythonScriptFactory::~PythonScriptFactory()
{
if (m_class != 0) {
Py_DECREF(m_class);
}
if (m_module != 0) {
Py_DECREF(m_module);
}
}
int PythonScriptFactory::addScript(Entity * entity)
{
if (m_class == 0) {
return -1;
}
PyEntity * wrapper = newPyEntity();
wrapper->m_entity = entity;
PyObject * script = Create_PyScript((PyObject *)wrapper, m_class);
if (script == NULL) {
return -1;
}
entity->setScript(new PythonEntityScript(script, (PyObject *)wrapper));
return 0;
}
int PythonScriptFactory::refreshClass()
{
if (m_module == 0) {
return -1;
}
PyObject * new_module = PyImport_ReloadModule(m_module);
if (new_module == 0) {
log(ERROR, String::compose("Error reloading python module \"%1\"",
m_package));
PyErr_Clear();
return -1;
}
Py_DECREF(m_module);
m_module = new_module;
return getClass();
}
|