From b5bdaedde2f96d245cf626ed97d58dd825adfe9e Mon Sep 17 00:00:00 2001 From: twanvl Date: Thu, 7 Aug 2008 16:26:33 +0000 Subject: [PATCH] Fixed conversion from Values to other types: Values now report being of the contained type. Added toImage function to ScriptValue. git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@1083 0fc631ac-6414-0410-93d0-97cfa31319b6 --- src/data/field/image.cpp | 15 +- src/gfx/generated_image.cpp | 3 + src/gfx/generated_image.hpp | 1 + src/script/functions/regex.cpp | 268 --------------------------------- src/script/image.cpp | 20 +-- src/script/to_value.hpp | 6 +- src/script/value.cpp | 8 + src/script/value.hpp | 3 + 8 files changed, 34 insertions(+), 290 deletions(-) diff --git a/src/data/field/image.cpp b/src/data/field/image.cpp index f34f4b3c..33ff2cec 100644 --- a/src/data/field/image.cpp +++ b/src/data/field/image.cpp @@ -8,6 +8,7 @@ #include #include +#include // ----------------------------------------------------------------------------- : ImageField @@ -38,6 +39,16 @@ String ImageValue::toString() const { return filename.empty() ? wxEmptyString : _(""); } -IMPLEMENT_REFLECTION_NAMELESS(ImageValue) { - if (fieldP->save_value || tag.scripting() || tag.reading()) REFLECT_NAMELESS(filename); +// custom reflection: convert to ScriptImageP for scripting + +void ImageValue::reflect(Reader& tag) { + tag.handle(filename); +} +void ImageValue::reflect(Writer& tag) { + if (fieldP->save_value) tag.handle(filename); +} +void ImageValue::reflect(GetMember& tag) {} +void ImageValue::reflect(GetDefaultMember& tag) { + // convert to ScriptImageP for scripting + tag.handle( (ScriptValueP)new_intrusive2(filename, last_update) ); } diff --git a/src/gfx/generated_image.cpp b/src/gfx/generated_image.cpp index ecbe77e7..0df1b0e2 100644 --- a/src/gfx/generated_image.cpp +++ b/src/gfx/generated_image.cpp @@ -19,6 +19,9 @@ ScriptType GeneratedImage::type() const { return SCRIPT_IMAGE; } String GeneratedImage::typeName() const { return _TYPE_("image"); } +GeneratedImageP GeneratedImage::toImage(const ScriptValueP& thisP) const { + return static_pointer_cast(thisP); +} Image GeneratedImage::generateConform(const Options& options) const { return conform_image(generate(options),options); diff --git a/src/gfx/generated_image.hpp b/src/gfx/generated_image.hpp index 52edb7d1..36b48174 100644 --- a/src/gfx/generated_image.hpp +++ b/src/gfx/generated_image.hpp @@ -61,6 +61,7 @@ class GeneratedImage : public ScriptValue { virtual ScriptType type() const; virtual String typeName() const; + virtual GeneratedImageP toImage(const ScriptValueP& thisP) const; }; /// Resize an image to conform to the options diff --git a/src/script/functions/regex.cpp b/src/script/functions/regex.cpp index 16ca3d66..c282aa05 100644 --- a/src/script/functions/regex.cpp +++ b/src/script/functions/regex.cpp @@ -1,4 +1,3 @@ - //+----------------------------------------------------------------------------+ //| Description: Magic Set Editor - Program to make Magic (tm) cards | //| Copyright: (C) 2001 - 2008 Twan van Laarhoven and "coppro" | @@ -47,101 +46,6 @@ template <> inline ScriptRegexP from_script(const ScriptValueP& va // ----------------------------------------------------------------------------- : Rules : regex replace -/* -class ScriptReplaceRule : public ScriptValue { - public: - virtual ScriptType type() const { return SCRIPT_FUNCTION; } - virtual String typeName() const { return _("replace_rule"); } - virtual ScriptValueP eval(Context& ctx) const { - SCRIPT_PARAM_C(String, input); - if (context.IsValid() || replacement_function || recursive) { - SCRIPT_RETURN(apply(ctx, input)); - } else { - // dumb replacing - regex.Replace(&input, replacement); - SCRIPT_RETURN(input); - } - } - String apply(Context& ctx, String& input, int level = 0) const { - // match first, then check context of match - String ret; - while (regex.Matches(input)) { - // for each match ... - size_t start, len; - bool ok = regex.GetMatch(&start, &len, 0); - assert(ok); - ret += input.substr(0, start); // everything before the match position stays - String inside = input.substr(start, len); // inside the match - String next_input = input.substr(start + len); // next loop the input is after this match - String after_replace = ret + _("") + next_input; // after replacing, the resulting context would be - if (!context.IsValid() || context.Matches(after_replace)) { - // the context matches -> perform replacement - if (replacement_function) { - // set match results in context - for (UInt m = 0 ; m < regex.GetMatchCount() ; ++m) { - regex.GetMatch(&start, &len, m); - String name = m == 0 ? _("input") : String(_("_")) << m; - String value = input.substr(start, len); - ctx.setVariable(name, to_script(value)); - } - // call - inside = replacement_function->eval(ctx)->toString(); - } else { - regex.Replace(&inside, replacement, 1); // replace inside - } - } - if (recursive && level < 20) { - ret += apply(ctx, inside, level + 1); - } else { - ret += inside; - } - input = next_input; - } - ret += input; - return ret; - } - - wxRegEx regex; ///< Regex to match - wxRegEx context; ///< Match only in a given context, optional - String replacement; ///< Replacement - ScriptValueP replacement_function; ///< Replacement function instead of a simple string, optional - bool recursive; ///< Recurse into the replacement -}; - -// Create a regular expression rule for replacing in strings -ScriptValueP replace_rule(Context& ctx) { - intrusive_ptr ret(new ScriptReplaceRule); - // match - SCRIPT_PARAM_C(String, match); - if (!ret->regex.Compile(match, wxRE_ADVANCED)) { - throw ScriptError(_("Error while compiling regular expression: '")+match+_("'")); - } - // replace - SCRIPT_PARAM_C(ScriptValueP, replace); - if (replace->type() == SCRIPT_FUNCTION) { - ret->replacement_function = replace; - } else { - ret->replacement = replace->toString(); - } - // in_context - SCRIPT_OPTIONAL_PARAM_C(String, in_context) { - if (!ret->context.Compile(in_context, wxRE_ADVANCED)) { - throw ScriptError(_("Error while compiling regular expression: '")+in_context+_("'")); - } - } - SCRIPT_OPTIONAL_PARAM_(bool, recursive); - ret->recursive = recursive; - return ret; -} - -SCRIPT_FUNCTION(replace_rule) { - return replace_rule(ctx); -} -SCRIPT_FUNCTION(replace) { - return replace_rule(ctx)->eval(ctx); -} -*/ - struct RegexReplacer { ScriptRegexP match; ///< Regex to match ScriptRegexP context; ///< Match only in a given context, optional @@ -226,85 +130,6 @@ SCRIPT_FUNCTION_SIMPLIFY_CLOSURE(replace) { // ----------------------------------------------------------------------------- : Rules : regex filter -/* -class ScriptFilterRule : public ScriptValue { - public: - virtual ScriptType type() const { return SCRIPT_FUNCTION; } - virtual String typeName() const { return _("filter_rule"); } - virtual ScriptValueP eval(Context& ctx) const { - SCRIPT_PARAM_C(String, input); - String ret; - while (regex.Matches(input)) { - // match, append to result - size_t start, len; - bool ok = regex.GetMatch(&start, &len, 0); - assert(ok); - String inside = input.substr(start, len); // the match - String next_input = input.substr(start + len); // everything after the match - if (!context.IsValid() || context.Matches(input.substr(0,start) + _("") + next_input)) { - // no context or context match - ret += inside; - } - input = next_input; - } - SCRIPT_RETURN(ret); - } - - wxRegEx regex; ///< Regex to match - wxRegEx context; ///< Match only in a given context, optional -}; - -// Create a regular expression rule for filtering strings -ScriptValueP filter_rule(Context& ctx) { - // cached? - SCRIPT_PARAM_C(String, match); - SCRIPT_PARAM_DEFAULT_C(String, in_context, String()); - - // cache - // * - const int CACHE_SIZE = 6; - struct CacheItem{ - String match, in_context; - intrusive_ptr rule; - }; - static CacheItem cache[CACHE_SIZE]; - static int cache_pos = 0; - // find in cache? - for (int i = 0 ; i < CACHE_SIZE ; ++i) { - if (cache[i].rule && cache[i].match == match && cache[i].in_context == in_context) { - return cache[i].rule; - } - } - // add item - cache[cache_pos].match = match; - cache[cache_pos].in_context = in_context; - cache[cache_pos].rule = intrusive_ptr(new ScriptFilterRule); - intrusive_ptr& ret = cache[cache_pos].rule; - cache_pos = (cache_pos+1) % CACHE_SIZE; - / * / - intrusive_ptr ret(new ScriptFilterRule); - //* / - - // match - if (!ret->regex.Compile(match, wxRE_ADVANCED)) { - throw ScriptError(_("Error while compiling regular expression: '")+match+_("'")); - } - // in_context - if (!in_context.empty()) { - if (!ret->context.Compile(in_context, wxRE_ADVANCED)) { - throw ScriptError(_("Error while compiling regular expression: '")+in_context+_("'")); - } - } - return ret; -} - -SCRIPT_FUNCTION(filter_rule) { - return filter_rule(ctx); -} -SCRIPT_FUNCTION(filter_text) { - return filter_rule(ctx)->eval(ctx); -}*/ - SCRIPT_FUNCTION_WITH_SIMPLIFY(filter_text) { SCRIPT_PARAM_C(String, input); SCRIPT_PARAM_C(ScriptRegexP, match); @@ -337,58 +162,6 @@ SCRIPT_FUNCTION_SIMPLIFY_CLOSURE(filter_text) { // ----------------------------------------------------------------------------- : Rules : regex break -/* -class ScriptBreakRule : public ScriptValue { - public: - virtual ScriptType type() const { return SCRIPT_FUNCTION; } - virtual String typeName() const { return _("break_rule"); } - virtual ScriptValueP eval(Context& ctx) const { - SCRIPT_PARAM_C(String, input); - ScriptCustomCollectionP ret(new ScriptCustomCollection); - while (regex.Matches(input)) { - // match, append to result - size_t start, len; - bool ok = regex.GetMatch(&start, &len, 0); - assert(ok); - String inside = input.substr(start, len); // the match - String next_input = input.substr(start + len); // everything after the match - if (!context.IsValid() || context.Matches(input.substr(0,start) + _("") + next_input)) { - // no context or context match - ret->value.push_back(to_script(inside)); - } - input = next_input; - } - return ret; - } - - wxRegEx regex; ///< Regex to match - wxRegEx context; ///< Match only in a given context, optional -}; - -// Create a regular expression rule for breaking strings -ScriptValueP break_rule(Context& ctx) { - intrusive_ptr ret(new ScriptBreakRule); - // match - SCRIPT_PARAM_C(String, match); - if (!ret->regex.Compile(match, wxRE_ADVANCED)) { - throw ScriptError(_("Error while compiling regular expression: '")+match+_("'")); - } - // in_context - SCRIPT_OPTIONAL_PARAM_C(String, in_context) { - if (!ret->context.Compile(in_context, wxRE_ADVANCED)) { - throw ScriptError(_("Error while compiling regular expression: '")+in_context+_("'")); - } - } - return ret; -} - -SCRIPT_FUNCTION(break_rule) { - return break_rule(ctx); -} -SCRIPT_FUNCTION(break_text) { - return break_rule(ctx)->eval(ctx); -}*/ - SCRIPT_FUNCTION_WITH_SIMPLIFY(break_text) { SCRIPT_PARAM_C(String, input); SCRIPT_PARAM_C(ScriptRegexP, match); @@ -421,47 +194,6 @@ SCRIPT_FUNCTION_SIMPLIFY_CLOSURE(break_text) { // ----------------------------------------------------------------------------- : Rules : regex match - -/* -class ScriptMatchRule : public ScriptValue { - public: - virtual ScriptType type() const { return SCRIPT_FUNCTION; } - virtual String typeName() const { return _("match_rule"); } - virtual ScriptValueP eval(Context& ctx) const { - SCRIPT_PARAM_C(String, input); - SCRIPT_RETURN(regex.Matches(input)); - } - - wxRegEx regex; ///< Regex to match -}; - -// Create a regular expression rule for filtering strings -ScriptValueP match_rule(Context& ctx) { - intrusive_ptr ret(new ScriptMatchRule); - // match - SCRIPT_PARAM_C(String, match); - if (!ret->regex.Compile(match, wxRE_ADVANCED)) { - throw ScriptError(_("Error while compiling regular expression: '")+match+_("'")); - } - return ret; -} - -SCRIPT_FUNCTION(match_rule) { - return match_rule(ctx); -} -SCRIPT_FUNCTION_WITH_SIMPLIFY(match) { - return match_rule(ctx)->eval(ctx); -} -SCRIPT_FUNCTION_SIMPLIFY_CLOSURE(match) { - ScriptValueP match = closure.getBinding(SCRIPT_VAR_match); - if (match) { - intrusive_ptr ret(new ScriptMatchRule); - from_script(match, ret->regex); - return ret; - } - return ScriptValueP(); -} -*/ SCRIPT_FUNCTION_WITH_SIMPLIFY(match) { SCRIPT_PARAM_C(String, input); SCRIPT_PARAM_C(ScriptRegexP, match); diff --git a/src/script/image.cpp b/src/script/image.cpp index 0837c5b8..513b1361 100644 --- a/src/script/image.cpp +++ b/src/script/image.cpp @@ -19,25 +19,7 @@ // convert any script value to a GeneratedImageP GeneratedImageP image_from_script(const ScriptValueP& value) { - ScriptType t = value->type(); - if (t == SCRIPT_IMAGE) { - GeneratedImageP img = dynamic_pointer_cast(value); - if (img) return img; - } else if (t == SCRIPT_STRING) { - return new_intrusive1(value->toString()); - } else if (t == SCRIPT_NIL) { - return new_intrusive(); - } else if (t == SCRIPT_OBJECT) { - // maybe it's an image value? - intrusive_ptr > v = dynamic_pointer_cast >(value); - if (v) { - ImageValueP iv = dynamic_pointer_cast(v->getValue()); - if (iv) { - return new_intrusive2(iv->filename, iv->last_update); - } - } - } - throw ScriptError(_ERROR_2_("can't convert", value->typeName(), _TYPE_("image"))); + return value->toImage(value); } // ----------------------------------------------------------------------------- : ScriptableImage diff --git a/src/script/to_value.hpp b/src/script/to_value.hpp index f7814eb6..360ae88c 100644 --- a/src/script/to_value.hpp +++ b/src/script/to_value.hpp @@ -14,6 +14,7 @@ #include #include #include +#include // we need the dtor of GeneratedImage // ----------------------------------------------------------------------------- : Overloadable templates @@ -246,13 +247,16 @@ template class ScriptObject : public ScriptValue { public: inline ScriptObject(const T& v) : value(v) {} - virtual ScriptType type() const { return SCRIPT_OBJECT; } + virtual ScriptType type() const { ScriptValueP d = getDefault(); return d ? d->type() : SCRIPT_OBJECT; } virtual String typeName() const { return type_name(*value); } virtual operator String() const { ScriptValueP d = getDefault(); return d ? *d : ScriptValue::operator String(); } virtual operator double() const { ScriptValueP d = getDefault(); return d ? *d : ScriptValue::operator double(); } virtual operator int() const { ScriptValueP d = getDefault(); return d ? *d : ScriptValue::operator int(); } virtual operator bool() const { ScriptValueP d = getDefault(); return d ? *d : ScriptValue::operator bool(); } virtual operator AColor() const { ScriptValueP d = getDefault(); return d ? *d : ScriptValue::operator AColor(); } + virtual GeneratedImageP toImage(const ScriptValueP& thisP) const { + ScriptValueP d = getDefault(); return d ? d->toImage(d) : ScriptValue::toImage(thisP); + } virtual ScriptValueP getMember(const String& name) const { GetMember gm(name); gm.handle(*value); diff --git a/src/script/value.cpp b/src/script/value.cpp index d1b0ef45..5ef4d894 100644 --- a/src/script/value.cpp +++ b/src/script/value.cpp @@ -10,6 +10,7 @@ #include