Commit 6f543cb1 authored by twanvl's avatar twanvl

implemented reflection

parent f1193df0
......@@ -24,7 +24,7 @@ void store(const ScriptValueP& val, Defaultable<String>& var) { var.assign(*val)
OptionalScript::~OptionalScript() {}
ScriptValueP OptionalScript::invoke(Context& ctx) {
ScriptValueP OptionalScript::invoke(Context& ctx) const {
if (script) {
return ctx.eval(*script);
} else {
......@@ -44,14 +44,11 @@ template <> void Writer::handle(const OptionalScript& os) {
handle(os.unparsed);
}
template <> void GetMember::handle(const OptionalScript& os) {
// no members
}
template <> void GetMember::store(const OptionalScript& os) {
template <> void GetDefaultMember::handle(const OptionalScript& os) {
// reflect as the script itself
if (os.script) {
store(os.script);
handle(os.script);
} else {
store(script_nil);
handle(script_nil);
}
}
......@@ -13,6 +13,7 @@
#include <util/reflect.hpp>
#include <util/defaultable.hpp>
#include <script/script.hpp>
#include <script/parser.hpp>
DECLARE_INTRUSIVE_POINTER_TYPE(Script);
class Context;
......@@ -33,17 +34,17 @@ class OptionalScript {
public:
~OptionalScript();
/// Is the script set?
inline operator bool() { return !!script; }
inline operator bool() const { return !!script; }
/// Invoke the script, return the result, or script_nil if there is no script
ScriptValueP invoke(Context& ctx);
ScriptValueP invoke(Context& ctx) const;
/// Invoke the script on a value
/** Assigns the result to value if it has changed.
* Returns true if the value has changed.
*/
template <typename T>
bool invokeOn(Context& ctx, T& value) {
bool invokeOn(Context& ctx, T& value) const {
if (script) {
T new_value;
store(new_value, script->invoke(ctx));
......@@ -59,6 +60,7 @@ class OptionalScript {
ScriptP script; ///< The script, may be null if there is no script
String unparsed; ///< Unparsed script, for writing back to a file
DECLARE_REFLECTION();
template <typename T> friend class Scriptable;
};
// ----------------------------------------------------------------------------- : Scriptable
......@@ -86,5 +88,31 @@ class Scriptable {
DECLARE_REFLECTION();
};
// we need some custom io, because the behaviour is different for each of Reader/Writer/GetMember
template <typename T>
void Reader::handle(Scriptable<T>& s) {
handle(s.script.unparsed);
if (starts_with(s.script.unparsed, _("script:"))) {
s.script.script = parse(s.script.unparsed);
} else {
handle(value);
}
}
template <typename T>
void Writer::handle(const Scriptable<T>& s) {
if (s.script) {
handle(s.script);
} else {
handle(s.value);
}
}
template <typename T>
void GetDefaultMember::handle(const Scriptable<T>& s) {
// just handle as the value
handle(s.value);
}
// ----------------------------------------------------------------------------- : EOF
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment