1 /*********************************
2 ** Tsunagari Tile Engine **
4 ** Copyright 2011-2012 OmegaSDG **
5 *********************************/
7 // "OmegaSDG" is defined as Michael D. Reiley and Paul Merrill.
10 // Permission is hereby granted, free of charge, to any person obtaining a copy
11 // of this software and associated documentation files (the "Software"), to
12 // deal in the Software without restriction, including without limitation the
13 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
14 // sell copies of the Software, and to permit persons to whom the Software is
15 // furnished to do so, subject to the following conditions:
17 // The above copyright notice and this permission notice shall be included in
18 // all copies or substantial portions of the Software.
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
35 #include "scriptinst.h"
38 struct validate_visitor
: public boost::static_visitor
<bool>
40 bool operator()(BytecodeRef bc
) const
43 Log::err("ScriptInst", "<null script>: script not valid");
47 Log::err("ScriptInst", bc
->filename() +
48 ": script not valid");
54 bool operator()(boost::python::object
) const
61 struct invoke_visitor
: public boost::static_visitor
<bool>
63 bool operator()(BytecodeRef bc
) const
65 return (bc
&& bc
->valid()) ? bc
->execute() : false;
68 bool operator()(boost::python::object callable
) const
75 } catch (boost::python::error_already_set
) {
77 // XXX: How does this interact with a C++/Python callstack?
78 //Log::err("Python", "Originating from " + source + ":");
87 ScriptInst::ScriptInst(const std::string
& source
)
88 : data(Reader::getBytecode(source
))
91 Log::err("ScriptInst", "Error loading " + source
);
96 ScriptInst::ScriptInst(boost::python::object callable
)
102 bool ScriptInst::validate()
104 return boost::apply_visitor(validate_visitor(), data
);
108 bool ScriptInst::invoke()
110 return boost::apply_visitor(invoke_visitor(), data
);
114 struct topython_visitor
: public boost::static_visitor
<PyObject
*>
116 PyObject
* operator()(BytecodeRef bc
) const
118 boost::python::object str
;
120 str
= boost::python::object(bc
->filename());
122 str
= boost::python::object("");
123 return boost::python::incref(str
.ptr());
126 PyObject
* operator()(boost::python::object callable
) const
128 return boost::python::incref(callable
.ptr());
133 struct scriptinst_to_python
135 static PyObject
* convert(ScriptInst script
)
137 return boost::apply_visitor(topython_visitor(), script
.data
);
142 struct scriptinst_from_python
144 scriptinst_from_python()
146 boost::python::converter::registry::push_back(
149 boost::python::type_id
<ScriptInst
>());
152 // Can this be converted to a ScriptInst?
153 static void* convertible(PyObject
* obj
)
155 //bool callable = obj->ob_type->tp_call != NULL;
156 //const char* tp_name = obj->ob_type->tp_name;
157 // XXX: Return non-NULL only if string or
158 // callable (fn or lambda?).
162 // Convert. boost::python provides us with a chunch of memory that we
163 // have to construct in-place.
164 static void construct(
166 boost::python::converter::rvalue_from_python_stage1_data
* data
)
168 // Prevent compilation name collisions with "object" by making
170 namespace bp
= boost::python
;
173 ((bp::converter::rvalue_from_python_storage
<ScriptInst
>*)data
)
176 if (PyString_Check(obj
)) {
177 const char* value
= PyString_AsString(obj
);
178 new (storage
) ScriptInst(value
);
181 // By default, the PyObject is a borrowed reference,
182 // which means it hasn't been incref'd.
183 bp::handle
<> hndl(bp::borrowed(obj
));
184 new (storage
) ScriptInst(bp::object(hndl
));
187 data
->convertible
= storage
;
192 void exportScriptInst()
194 using namespace boost::python
;
196 to_python_converter
<ScriptInst
, scriptinst_to_python
>();
197 scriptinst_from_python();