4 #include "scriptinst.h"
6 struct validate_visitor
: public boost::static_visitor
<bool>
10 validate_visitor(const std::string
& context
) : context(context
) {}
12 bool operator()(void*) const
17 bool operator()(ScriptInst::strref ref
) const
19 Resourcer
* rc
= Resourcer::instance();
21 if (ref
.filename
.empty()) {
23 "script filename is empty");
27 if (!rc
->resourceExists(ref
.filename
)) {
29 ref
.filename
+ "script file not found");
36 bool operator()(boost::python::object
) const
42 struct invoke_visitor
: public boost::static_visitor
<bool>
44 bool operator()(void*) const
49 bool operator()(ScriptInst::strref ref
) const
51 Resourcer
* rc
= Resourcer::instance();
53 if (ref
.funcname
.size()) {
54 rc
->runPythonScript(ref
.filename
);
55 return pythonExec(ref
.funccall
);
58 return rc
->runPythonScript(ref
.filename
);
62 bool operator()(boost::python::object pyfn
) const
69 } catch (boost::python::error_already_set
) {
77 ScriptInst::ScriptInst()
82 ScriptInst::ScriptInst(const std::string
& strloc
)
84 size_t colon
= strloc
.find(':');
86 if (colon
== std::string::npos
) {
87 ref
.filename
= strloc
;
90 ref
.filename
= strloc
.substr(0, colon
);
91 ref
.funcname
= strloc
.substr(colon
+ 1);
92 ref
.funccall
= pythonCompile(
93 "<Tsunagari trigger>",
94 (ref
.funcname
).c_str()
100 ScriptInst::ScriptInst(boost::python::object pyfn
)
105 bool ScriptInst::validate(const std::string
& context
)
107 return boost::apply_visitor(validate_visitor(context
), data
);
110 bool ScriptInst::invoke()
112 return boost::apply_visitor(invoke_visitor(), data
);
122 struct topython_visitor
: public boost::static_visitor
<PyObject
*>
124 PyObject
* operator()(void*) const
126 using namespace boost::python
;
128 return incref(Py_None
);
131 PyObject
* operator()(ScriptInst::strref ref
) const
133 using namespace boost::python
;
136 if (ref
.funcname
.size())
137 str
= object(ref
.filename
+ ":" + ref
.funcname
);
139 str
= object(ref
.filename
);
140 return incref(str
.ptr());
143 PyObject
* operator()(boost::python::object pyfn
) const
145 using namespace boost::python
;
147 return incref(pyfn
.ptr());
152 struct scriptinst_to_python
154 static PyObject
* convert(ScriptInst script
)
156 return boost::apply_visitor(topython_visitor(), script
.data
);
161 struct scriptinst_from_python
163 scriptinst_from_python()
165 boost::python::converter::registry::push_back(
168 boost::python::type_id
<ScriptInst
>());
171 // Can this be converted to a ScriptInst?
172 static void* convertible(PyObject
* obj
)
174 // XXX: Return non-NULL only if string or
175 // callable (fn or lambda?).
179 // Convert. boost::python provides us with a chunch of memory that we
180 // have to construct in-place.
181 static void construct(
183 boost::python::converter::rvalue_from_python_stage1_data
* data
)
185 using namespace boost::python
;
188 ((converter::rvalue_from_python_storage
<ScriptInst
>*)data
)
191 if (PyString_Check(obj
)) {
192 const char* value
= PyString_AsString(obj
);
193 new (storage
) ScriptInst(value
);
196 // By default, the PyObject is a borrowed reference,
197 // which means it hasn't been incref'd.
198 handle
<> hndl(borrowed(obj
));
199 new (storage
) ScriptInst(object(hndl
));
202 data
->convertible
= storage
;
206 void exportScriptInst()
208 using namespace boost::python
;
210 to_python_converter
<ScriptInst
, scriptinst_to_python
>();
211 scriptinst_from_python();