mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-10 04:57:00 -04:00
Use toSomeType() instead of operator SomeType in ScriptValue.
This means that we are more explicit about type conversions. Also use override specifiers for overriden virtual functions in ScriptValue.
This commit is contained in:
+11
-10
@@ -665,7 +665,7 @@ bool KeywordDatabase::tryExpand(const Keyword& kw,
|
||||
ctx.setVariable(_("used_placeholders"), to_script(used_placeholders));
|
||||
|
||||
// Final check whether the keyword matches
|
||||
if (match_condition && (bool)*match_condition->eval(ctx) == false) {
|
||||
if (match_condition && match_condition->eval(ctx)->toBool() == false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -673,7 +673,7 @@ bool KeywordDatabase::tryExpand(const Keyword& kw,
|
||||
bool expand = expand_type == _('1');
|
||||
if (!expand && expand_type != _('0')) {
|
||||
// default expand, determined by script
|
||||
expand = expand_default ? (bool)*expand_default->eval(ctx) : true;
|
||||
expand = expand_default ? expand_default->eval(ctx)->toBool() : true;
|
||||
expand_type = expand ? _('A') : _('a');
|
||||
}
|
||||
|
||||
@@ -711,7 +711,7 @@ bool KeywordDatabase::tryExpand(const Keyword& kw,
|
||||
ScriptType KeywordParamValue::type() const { return SCRIPT_STRING; }
|
||||
String KeywordParamValue::typeName() const { return _("keyword parameter"); }
|
||||
|
||||
KeywordParamValue::operator String() const {
|
||||
String KeywordParamValue::toString() const {
|
||||
String safe_type = replace_all(replace_all(replace_all(type_name,
|
||||
_("("),_("-")),
|
||||
_(")"),_("-")),
|
||||
@@ -719,16 +719,17 @@ KeywordParamValue::operator String() const {
|
||||
return _("<param-") + safe_type + _(">") + value + _("</param-") + safe_type + _(">");
|
||||
}
|
||||
|
||||
KeywordParamValue::operator int() const { return *to_script(value); } // a bit of a hack
|
||||
KeywordParamValue::operator double() const { return *to_script(value); }
|
||||
KeywordParamValue::operator bool() const { return *to_script(value); }
|
||||
KeywordParamValue::operator Color() const { return *to_script(value); }
|
||||
int KeywordParamValue::itemCount() const { return to_script(value)->itemCount(); }
|
||||
// a bit of a hack: use the ScriptString implementation
|
||||
int KeywordParamValue::toInt() const { return to_script(value)->toInt(); }
|
||||
double KeywordParamValue::toDouble() const { return to_script(value)->toDouble(); }
|
||||
bool KeywordParamValue::toBool() const { return to_script(value)->toBool(); }
|
||||
Color KeywordParamValue::toColor() const { return to_script(value)->toColor(); }
|
||||
int KeywordParamValue::itemCount() const { return to_script(value)->itemCount(); }
|
||||
|
||||
ScriptValueP KeywordParamValue::getMember(const String& name) const {
|
||||
if (name == _("type")) return to_script(type_name);
|
||||
if (name == _("separator before")) return to_script(separator_before);
|
||||
if (name == _("separator after")) return to_script(separator_after);
|
||||
if (name == _("separator_before")) return to_script(separator_before);
|
||||
if (name == _("separator_after")) return to_script(separator_after);
|
||||
if (name == _("value")) return to_script(value);
|
||||
if (name == _("param")) return to_script(value);
|
||||
return ScriptValue::getMember(name);
|
||||
|
||||
@@ -190,14 +190,14 @@ class KeywordParamValue : public ScriptValue {
|
||||
String separator_before, separator_after;
|
||||
String value;
|
||||
|
||||
virtual ScriptType type() const;
|
||||
virtual String typeName() const;
|
||||
virtual operator String() const;
|
||||
virtual operator int() const;
|
||||
virtual operator bool() const;
|
||||
virtual operator double() const;
|
||||
virtual operator Color() const;
|
||||
virtual int itemCount() const;
|
||||
virtual ScriptValueP getMember(const String& name) const;
|
||||
ScriptType type() const override;
|
||||
String typeName() const override;
|
||||
String toString() const override;
|
||||
int toInt() const override;
|
||||
bool toBool() const override;
|
||||
double toDouble() const override;
|
||||
Color toColor() const override;
|
||||
int itemCount() const override;
|
||||
ScriptValueP getMember(const String& name) const override;
|
||||
};
|
||||
|
||||
|
||||
+1
-1
@@ -111,7 +111,7 @@ PackInstance::PackInstance(const PackType& pack_type, PackGenerator& parent)
|
||||
if (pack_type.filter) {
|
||||
FOR_EACH(card, parent.set->cards) {
|
||||
Context& ctx = parent.set->getContext(card);
|
||||
bool keep = *pack_type.filter.invoke(ctx);
|
||||
bool keep = pack_type.filter.invoke(ctx)->toBool();
|
||||
if (keep) {
|
||||
cards.push_back(card);
|
||||
}
|
||||
|
||||
+3
-3
@@ -267,9 +267,9 @@ int Set::positionOfCard(const CardP& card, const ScriptValueP& order_by, const S
|
||||
vector<int> keep; if(filter) keep.reserve(cards.size());
|
||||
FOR_EACH_CONST(c, cards) {
|
||||
Context& ctx = getContext(c);
|
||||
values.push_back(*order_by->eval(ctx));
|
||||
values.push_back(order_by->eval(ctx)->toString());
|
||||
if (filter) {
|
||||
keep.push_back((bool)*filter->eval(ctx));
|
||||
keep.push_back(filter->eval(ctx)->toBool());
|
||||
}
|
||||
}
|
||||
#if USE_SCRIPT_PROFILING
|
||||
@@ -289,7 +289,7 @@ int Set::numberOfCards(const ScriptValueP& filter) {
|
||||
} else {
|
||||
int n = 0;
|
||||
FOR_EACH_CONST(c, cards) {
|
||||
if (*filter->eval(getContext(c))) ++n;
|
||||
if (filter->eval(getContext(c))->toBool()) ++n;
|
||||
}
|
||||
filter_cache.insert(make_pair(filter,n));
|
||||
return n;
|
||||
|
||||
+97
-97
@@ -59,9 +59,9 @@ class GeneratedImage : public ScriptValue {
|
||||
/// Is this image blank?
|
||||
virtual bool isBlank() const { return false; }
|
||||
|
||||
virtual ScriptType type() const;
|
||||
virtual String typeName() const;
|
||||
virtual GeneratedImageP toImage(const ScriptValueP& thisP) const;
|
||||
ScriptType type() const override;
|
||||
String typeName() const override;
|
||||
GeneratedImageP toImage(const ScriptValueP& thisP) const override;
|
||||
};
|
||||
|
||||
/// Resize an image to conform to the options
|
||||
@@ -71,13 +71,13 @@ Image conform_image(const Image&, const GeneratedImage::Options&);
|
||||
|
||||
/// Apply some filter to a single image
|
||||
class SimpleFilterImage : public GeneratedImage {
|
||||
public:
|
||||
public:
|
||||
inline SimpleFilterImage(const GeneratedImageP& image)
|
||||
: image(image)
|
||||
{}
|
||||
virtual ImageCombine combine() const { return image->combine(); }
|
||||
virtual bool local() const { return image->local(); }
|
||||
protected:
|
||||
ImageCombine combine() const override { return image->combine(); }
|
||||
bool local() const override { return image->local(); }
|
||||
protected:
|
||||
GeneratedImageP image;
|
||||
};
|
||||
|
||||
@@ -85,14 +85,14 @@ class SimpleFilterImage : public GeneratedImage {
|
||||
|
||||
/// An image generator that returns a blank image
|
||||
class BlankImage : public GeneratedImage {
|
||||
public:
|
||||
virtual Image generate(const Options&) const;
|
||||
virtual bool operator == (const GeneratedImage& that) const;
|
||||
virtual bool isBlank() const { return true; }
|
||||
public:
|
||||
Image generate(const Options&) const override;
|
||||
bool operator == (const GeneratedImage& that) const override;
|
||||
bool isBlank() const override { return true; }
|
||||
|
||||
// Why is this not thread safe? What is GTK smoking?
|
||||
#ifdef __WXGTK__
|
||||
virtual bool threadSafe() const { return false; }
|
||||
bool threadSafe() const override { return false; }
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -100,15 +100,15 @@ class BlankImage : public GeneratedImage {
|
||||
|
||||
/// An image generator that linearly blends two other images
|
||||
class LinearBlendImage : public GeneratedImage {
|
||||
public:
|
||||
public:
|
||||
inline LinearBlendImage(const GeneratedImageP& image1, const GeneratedImageP& image2, double x1, double y1, double x2, double y2)
|
||||
: image1(image1), image2(image2), x1(x1), y1(y1), x2(x2), y2(y2)
|
||||
{}
|
||||
virtual Image generate(const Options& opt) const;
|
||||
virtual ImageCombine combine() const;
|
||||
virtual bool operator == (const GeneratedImage& that) const;
|
||||
virtual bool local() const { return image1->local() && image2->local(); }
|
||||
private:
|
||||
Image generate(const Options& opt) const override;
|
||||
ImageCombine combine() const override;
|
||||
bool operator == (const GeneratedImage& that) const override;
|
||||
bool local() const override { return image1->local() && image2->local(); }
|
||||
private:
|
||||
GeneratedImageP image1, image2;
|
||||
double x1, y1, x2, y2;
|
||||
};
|
||||
@@ -117,15 +117,15 @@ class LinearBlendImage : public GeneratedImage {
|
||||
|
||||
/// An image generator that blends two other images using a third as a mask
|
||||
class MaskedBlendImage : public GeneratedImage {
|
||||
public:
|
||||
public:
|
||||
inline MaskedBlendImage(const GeneratedImageP& light, const GeneratedImageP& dark, const GeneratedImageP& mask)
|
||||
: light(light), dark(dark), mask(mask)
|
||||
{}
|
||||
virtual Image generate(const Options& opt) const;
|
||||
virtual ImageCombine combine() const;
|
||||
virtual bool operator == (const GeneratedImage& that) const;
|
||||
virtual bool local() const { return light->local() && dark->local() && mask->local(); }
|
||||
private:
|
||||
Image generate(const Options& opt) const override;
|
||||
ImageCombine combine() const override;
|
||||
bool operator == (const GeneratedImage& that) const override;
|
||||
bool local() const override { return light->local() && dark->local() && mask->local(); }
|
||||
private:
|
||||
GeneratedImageP light, dark, mask;
|
||||
};
|
||||
|
||||
@@ -133,15 +133,15 @@ class MaskedBlendImage : public GeneratedImage {
|
||||
|
||||
/// An image generator that blends two other images using an ImageCombine function
|
||||
class CombineBlendImage : public GeneratedImage {
|
||||
public:
|
||||
public:
|
||||
inline CombineBlendImage(const GeneratedImageP& image1, const GeneratedImageP& image2, ImageCombine image_combine)
|
||||
: image1(image1), image2(image2), image_combine(image_combine)
|
||||
{}
|
||||
virtual Image generate(const Options& opt) const;
|
||||
virtual ImageCombine combine() const;
|
||||
virtual bool operator == (const GeneratedImage& that) const;
|
||||
virtual bool local() const { return image1->local() && image2->local(); }
|
||||
private:
|
||||
Image generate(const Options& opt) const override;
|
||||
ImageCombine combine() const override;
|
||||
bool operator == (const GeneratedImage& that) const override;
|
||||
bool local() const override { return image1->local() && image2->local(); }
|
||||
private:
|
||||
GeneratedImageP image1, image2;
|
||||
ImageCombine image_combine;
|
||||
};
|
||||
@@ -150,25 +150,25 @@ class CombineBlendImage : public GeneratedImage {
|
||||
|
||||
/// Change the alpha channel of an image
|
||||
class SetMaskImage : public SimpleFilterImage {
|
||||
public:
|
||||
public:
|
||||
inline SetMaskImage(const GeneratedImageP& image, const GeneratedImageP& mask)
|
||||
: SimpleFilterImage(image), mask(mask)
|
||||
{}
|
||||
virtual Image generate(const Options& opt) const;
|
||||
virtual bool operator == (const GeneratedImage& that) const;
|
||||
private:
|
||||
Image generate(const Options& opt) const override;
|
||||
bool operator == (const GeneratedImage& that) const override;
|
||||
private:
|
||||
GeneratedImageP mask;
|
||||
};
|
||||
|
||||
/// Change the alpha channel of an image
|
||||
class SetAlphaImage : public SimpleFilterImage {
|
||||
public:
|
||||
public:
|
||||
inline SetAlphaImage(const GeneratedImageP& image, double alpha)
|
||||
: SimpleFilterImage(image), alpha(alpha)
|
||||
{}
|
||||
virtual Image generate(const Options& opt) const;
|
||||
virtual bool operator == (const GeneratedImage& that) const;
|
||||
private:
|
||||
Image generate(const Options& opt) const override;
|
||||
bool operator == (const GeneratedImage& that) const override;
|
||||
private:
|
||||
double alpha;
|
||||
};
|
||||
|
||||
@@ -176,14 +176,14 @@ class SetAlphaImage : public SimpleFilterImage {
|
||||
|
||||
/// Change the combine mode
|
||||
class SetCombineImage : public SimpleFilterImage {
|
||||
public:
|
||||
public:
|
||||
inline SetCombineImage(const GeneratedImageP& image, ImageCombine image_combine)
|
||||
: SimpleFilterImage(image), image_combine(image_combine)
|
||||
{}
|
||||
virtual Image generate(const Options& opt) const;
|
||||
virtual ImageCombine combine() const;
|
||||
virtual bool operator == (const GeneratedImage& that) const;
|
||||
private:
|
||||
Image generate(const Options& opt) const override;
|
||||
ImageCombine combine() const override;
|
||||
bool operator == (const GeneratedImage& that) const override;
|
||||
private:
|
||||
ImageCombine image_combine;
|
||||
};
|
||||
|
||||
@@ -191,13 +191,13 @@ class SetCombineImage : public SimpleFilterImage {
|
||||
|
||||
/// Saturate/desaturate an image
|
||||
class SaturateImage : public SimpleFilterImage {
|
||||
public:
|
||||
public:
|
||||
inline SaturateImage(const GeneratedImageP& image, double amount)
|
||||
: SimpleFilterImage(image), amount(amount)
|
||||
{}
|
||||
virtual Image generate(const Options& opt) const;
|
||||
virtual bool operator == (const GeneratedImage& that) const;
|
||||
private:
|
||||
Image generate(const Options& opt) const override;
|
||||
bool operator == (const GeneratedImage& that) const override;
|
||||
private:
|
||||
double amount;
|
||||
};
|
||||
|
||||
@@ -205,36 +205,36 @@ class SaturateImage : public SimpleFilterImage {
|
||||
|
||||
/// Invert an image
|
||||
class InvertImage : public SimpleFilterImage {
|
||||
public:
|
||||
public:
|
||||
inline InvertImage(const GeneratedImageP& image)
|
||||
: SimpleFilterImage(image)
|
||||
{}
|
||||
virtual Image generate(const Options& opt) const;
|
||||
virtual bool operator == (const GeneratedImage& that) const;
|
||||
Image generate(const Options& opt) const override;
|
||||
bool operator == (const GeneratedImage& that) const override;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------- : RecolorImage
|
||||
|
||||
/// Recolor an image
|
||||
class RecolorImage : public SimpleFilterImage {
|
||||
public:
|
||||
public:
|
||||
inline RecolorImage(const GeneratedImageP& image, Color color)
|
||||
: SimpleFilterImage(image), color(color)
|
||||
{}
|
||||
virtual Image generate(const Options& opt) const;
|
||||
virtual bool operator == (const GeneratedImage& that) const;
|
||||
private:
|
||||
Image generate(const Options& opt) const override;
|
||||
bool operator == (const GeneratedImage& that) const override;
|
||||
private:
|
||||
Color color;
|
||||
};
|
||||
/// Recolor an image, with custom colors
|
||||
class RecolorImage2 : public SimpleFilterImage {
|
||||
public:
|
||||
public:
|
||||
inline RecolorImage2(const GeneratedImageP& image, Color red, Color green, Color blue, Color white)
|
||||
: SimpleFilterImage(image), red(red), green(green), blue(blue), white(white)
|
||||
{}
|
||||
virtual Image generate(const Options& opt) const;
|
||||
virtual bool operator == (const GeneratedImage& that) const;
|
||||
private:
|
||||
Image generate(const Options& opt) const override;
|
||||
bool operator == (const GeneratedImage& that) const override;
|
||||
private:
|
||||
Color red,green,blue,white;
|
||||
};
|
||||
|
||||
@@ -246,29 +246,29 @@ class FlipImageHorizontal : public SimpleFilterImage {
|
||||
inline FlipImageHorizontal(const GeneratedImageP& image)
|
||||
: SimpleFilterImage(image)
|
||||
{}
|
||||
virtual Image generate(const Options& opt) const;
|
||||
virtual bool operator == (const GeneratedImage& that) const;
|
||||
Image generate(const Options& opt) const override;
|
||||
bool operator == (const GeneratedImage& that) const override;
|
||||
};
|
||||
|
||||
/// Flip an image vertically
|
||||
class FlipImageVertical : public SimpleFilterImage {
|
||||
public:
|
||||
public:
|
||||
inline FlipImageVertical(const GeneratedImageP& image)
|
||||
: SimpleFilterImage(image)
|
||||
{}
|
||||
virtual Image generate(const Options& opt) const;
|
||||
virtual bool operator == (const GeneratedImage& that) const;
|
||||
Image generate(const Options& opt) const override;
|
||||
bool operator == (const GeneratedImage& that) const override;
|
||||
};
|
||||
|
||||
/// Rotate an image
|
||||
class RotateImage : public SimpleFilterImage {
|
||||
public:
|
||||
public:
|
||||
inline RotateImage(const GeneratedImageP& image, Radians angle)
|
||||
: SimpleFilterImage(image), angle(angle)
|
||||
{}
|
||||
virtual Image generate(const Options& opt) const;
|
||||
virtual bool operator == (const GeneratedImage& that) const;
|
||||
private:
|
||||
Image generate(const Options& opt) const override;
|
||||
bool operator == (const GeneratedImage& that) const override;
|
||||
private:
|
||||
Radians angle;
|
||||
};
|
||||
|
||||
@@ -276,13 +276,13 @@ class RotateImage : public SimpleFilterImage {
|
||||
|
||||
/// Enlarge an image by adding a border around it
|
||||
class EnlargeImage : public SimpleFilterImage {
|
||||
public:
|
||||
public:
|
||||
inline EnlargeImage(const GeneratedImageP& image, double border_size)
|
||||
: SimpleFilterImage(image), border_size(fabs(border_size))
|
||||
{}
|
||||
virtual Image generate(const Options& opt) const;
|
||||
virtual bool operator == (const GeneratedImage& that) const;
|
||||
private:
|
||||
Image generate(const Options& opt) const override;
|
||||
bool operator == (const GeneratedImage& that) const override;
|
||||
private:
|
||||
double border_size;
|
||||
};
|
||||
|
||||
@@ -290,13 +290,13 @@ class EnlargeImage : public SimpleFilterImage {
|
||||
|
||||
/// Crop an image at a certain point, to a certain size
|
||||
class CropImage : public SimpleFilterImage {
|
||||
public:
|
||||
public:
|
||||
inline CropImage(const GeneratedImageP& image, double width, double height, double offset_x, double offset_y)
|
||||
: SimpleFilterImage(image), width(width), height(height), offset_x(offset_x), offset_y(offset_y)
|
||||
{}
|
||||
virtual Image generate(const Options& opt) const;
|
||||
virtual bool operator == (const GeneratedImage& that) const;
|
||||
private:
|
||||
Image generate(const Options& opt) const override;
|
||||
bool operator == (const GeneratedImage& that) const override;
|
||||
private:
|
||||
double width, height;
|
||||
double offset_x, offset_y;
|
||||
};
|
||||
@@ -305,14 +305,14 @@ class CropImage : public SimpleFilterImage {
|
||||
|
||||
/// Add a drop shadow to an image
|
||||
class DropShadowImage : public SimpleFilterImage {
|
||||
public:
|
||||
public:
|
||||
inline DropShadowImage(const GeneratedImageP& image, double offset_x, double offset_y, double shadow_alpha, double shadow_blur_radius, Color shadow_color)
|
||||
: SimpleFilterImage(image), offset_x(offset_x), offset_y(offset_y)
|
||||
, shadow_alpha(shadow_alpha), shadow_blur_radius(shadow_blur_radius), shadow_color(shadow_color)
|
||||
{}
|
||||
virtual Image generate(const Options& opt) const;
|
||||
virtual bool operator == (const GeneratedImage& that) const;
|
||||
private:
|
||||
Image generate(const Options& opt) const override;
|
||||
bool operator == (const GeneratedImage& that) const override;
|
||||
private:
|
||||
double offset_x, offset_y;
|
||||
double shadow_alpha;
|
||||
double shadow_blur_radius;
|
||||
@@ -323,13 +323,13 @@ class DropShadowImage : public SimpleFilterImage {
|
||||
|
||||
/// Load an image from a file in a package
|
||||
class PackagedImage : public GeneratedImage {
|
||||
public:
|
||||
public:
|
||||
inline PackagedImage(const String& filename)
|
||||
: filename(filename)
|
||||
{}
|
||||
virtual Image generate(const Options& opt) const;
|
||||
virtual bool operator == (const GeneratedImage& that) const;
|
||||
private:
|
||||
Image generate(const Options& opt) const override;
|
||||
bool operator == (const GeneratedImage& that) const override;
|
||||
private:
|
||||
String filename;
|
||||
};
|
||||
|
||||
@@ -341,9 +341,9 @@ class BuiltInImage : public GeneratedImage {
|
||||
inline BuiltInImage(const String& name)
|
||||
: name(name)
|
||||
{}
|
||||
virtual Image generate(const Options& opt) const;
|
||||
virtual bool operator == (const GeneratedImage& that) const;
|
||||
private:
|
||||
Image generate(const Options& opt) const override;
|
||||
bool operator == (const GeneratedImage& that) const override;
|
||||
private:
|
||||
String name;
|
||||
};
|
||||
|
||||
@@ -351,17 +351,17 @@ class BuiltInImage : public GeneratedImage {
|
||||
|
||||
/// Use a symbol as an image
|
||||
class SymbolToImage : public GeneratedImage {
|
||||
public:
|
||||
public:
|
||||
SymbolToImage(bool is_local, const String& filename, Age age, const SymbolVariationP& variation);
|
||||
~SymbolToImage();
|
||||
virtual Image generate(const Options& opt) const;
|
||||
virtual bool operator == (const GeneratedImage& that) const;
|
||||
virtual bool local() const { return is_local; }
|
||||
Image generate(const Options& opt) const override;
|
||||
bool operator == (const GeneratedImage& that) const override;
|
||||
bool local() const override { return is_local; }
|
||||
|
||||
#ifdef __WXGTK__
|
||||
virtual bool threadSafe() const { return false; }
|
||||
bool threadSafe() const override { return false; }
|
||||
#endif
|
||||
private:
|
||||
private:
|
||||
SymbolToImage(const SymbolToImage&); // copy ctor
|
||||
bool is_local; ///< Use local package?
|
||||
String filename;
|
||||
@@ -373,13 +373,13 @@ class SymbolToImage : public GeneratedImage {
|
||||
|
||||
/// Use an image from an ImageValue as an image
|
||||
class ImageValueToImage : public GeneratedImage {
|
||||
public:
|
||||
public:
|
||||
ImageValueToImage(const String& filename, Age age);
|
||||
~ImageValueToImage();
|
||||
virtual Image generate(const Options& opt) const;
|
||||
virtual bool operator == (const GeneratedImage& that) const;
|
||||
virtual bool local() const { return true; }
|
||||
private:
|
||||
Image generate(const Options& opt) const override;
|
||||
bool operator == (const GeneratedImage& that) const override;
|
||||
bool local() const override { return true; }
|
||||
private:
|
||||
ImageValueToImage(const ImageValueToImage&); // copy ctor
|
||||
String filename;
|
||||
Age age; ///< Age the symbol was last updated
|
||||
|
||||
@@ -319,7 +319,7 @@ int CardListBase::OnGetItemImage(long pos) const {
|
||||
wxListItemAttr* CardListBase::OnGetItemAttr(long pos) const {
|
||||
if (!set->game->card_list_color_script) return nullptr;
|
||||
Context& ctx = set->getContext(getCard(pos));
|
||||
item_attr.SetTextColour(*set->game->card_list_color_script.invoke(ctx));
|
||||
item_attr.SetTextColour(set->game->card_list_color_script.invoke(ctx)->toColor());
|
||||
return &item_attr;
|
||||
}
|
||||
|
||||
|
||||
@@ -508,7 +508,7 @@ void ConsolePanel::exec(String const& command) {
|
||||
message->bitmap = wxBitmap(image);
|
||||
} else if (type == SCRIPT_COLOR) {
|
||||
message->text = result->toCode();
|
||||
Color color = result->operator Color();
|
||||
Color color = result->toColor();
|
||||
wxImage image(30,20);
|
||||
fill_image(image,color);
|
||||
set_alpha(image, color.Alpha() / 255.0);
|
||||
|
||||
@@ -253,7 +253,7 @@ size_t DropDownChoiceList::selection() const {
|
||||
return 0;
|
||||
} else {
|
||||
// run default script to find out what the default choice would be
|
||||
String default_choice = *field().default_script.invoke( cve.viewer.getContext() );
|
||||
String default_choice = field().default_script.invoke( cve.viewer.getContext() )->toString();
|
||||
default_id = group->choiceId(default_choice);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ size_t DropDownColorList::selection() const {
|
||||
return 0;
|
||||
} else if (hasDefault()) {
|
||||
// evaluate script to find default color
|
||||
default_color = *field().default_script.invoke(cve.viewer.getContext());
|
||||
default_color = field().default_script.invoke(cve.viewer.getContext())->toColor();
|
||||
}
|
||||
return selection;
|
||||
}
|
||||
|
||||
+40
-41
@@ -67,7 +67,7 @@ ScriptValueP Context::eval(const Script& script, bool useScope) {
|
||||
}
|
||||
// Conditional jump
|
||||
case I_JUMP_IF_NOT: {
|
||||
bool condition = *stack.back();
|
||||
bool condition = stack.back()->toBool();
|
||||
stack.pop_back();
|
||||
if (!condition) {
|
||||
instr = &script.instructions[0] + i.data;
|
||||
@@ -76,7 +76,7 @@ ScriptValueP Context::eval(const Script& script, bool useScope) {
|
||||
}
|
||||
// Short-circuiting and/or = conditional jump without pop
|
||||
case I_JUMP_SC_AND: {
|
||||
bool condition = *stack.back();
|
||||
bool condition = stack.back()->toBool();
|
||||
if (!condition) {
|
||||
instr = &script.instructions[0] + i.data;
|
||||
} else {
|
||||
@@ -85,7 +85,7 @@ ScriptValueP Context::eval(const Script& script, bool useScope) {
|
||||
break;
|
||||
}
|
||||
case I_JUMP_SC_OR: {
|
||||
bool condition = *stack.back();
|
||||
bool condition = stack.back()->toBool();
|
||||
if (condition) {
|
||||
instr = &script.instructions[0] + i.data;
|
||||
} else {
|
||||
@@ -109,7 +109,7 @@ ScriptValueP Context::eval(const Script& script, bool useScope) {
|
||||
|
||||
// Get an object member
|
||||
case I_MEMBER_C: {
|
||||
stack.back() = stack.back()->getMember(*script.constants[i.data]);
|
||||
stack.back() = stack.back()->getMember(script.constants[i.data]->toString());
|
||||
break;
|
||||
}
|
||||
// Loop over a container, push next value or jump
|
||||
@@ -367,13 +367,13 @@ void instrUnary(UnaryInstructionType i, ScriptValueP& a) {
|
||||
case I_NEGATE: {
|
||||
ScriptType at = a->type();
|
||||
if (at == SCRIPT_DOUBLE) {
|
||||
a = to_script(-(double)*a);
|
||||
a = to_script(-a->toDouble());
|
||||
} else {
|
||||
a = to_script(-(int)*a);
|
||||
a = to_script(-a->toInt());
|
||||
}
|
||||
break;
|
||||
} case I_NOT:
|
||||
a = to_script(!(bool)*a);
|
||||
a = to_script(!a->toBool());
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -382,19 +382,18 @@ void instrUnary(UnaryInstructionType i, ScriptValueP& a) {
|
||||
|
||||
/// Composition of two functions
|
||||
class ScriptCompose : public ScriptValue {
|
||||
public:
|
||||
public:
|
||||
ScriptCompose(ScriptValueP a, ScriptValueP b) : a(a), b(b) {}
|
||||
|
||||
virtual ScriptType type() const { return SCRIPT_FUNCTION; }
|
||||
virtual String typeName() const { return _("function composition"); }
|
||||
ScriptType type() const override { return SCRIPT_FUNCTION; }
|
||||
String typeName() const override { return _("function composition"); }
|
||||
|
||||
virtual ScriptValueP dependencies(Context& ctx, const Dependency& dep) const {
|
||||
ScriptValueP dependencies(Context& ctx, const Dependency& dep) const override {
|
||||
ctx.setVariable(SCRIPT_VAR_input, a->dependencies(ctx, dep));
|
||||
return b->dependencies(ctx, dep);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ScriptValueP do_eval(Context& ctx, bool openScope) const {
|
||||
ScriptValueP eval(Context& ctx, bool openScope) const override {
|
||||
#if USE_SCRIPT_PROFILING
|
||||
Timer timer;
|
||||
{
|
||||
@@ -417,7 +416,7 @@ class ScriptCompose : public ScriptValue {
|
||||
#endif
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
ScriptValueP a,b;
|
||||
};
|
||||
|
||||
@@ -425,29 +424,29 @@ class ScriptCompose : public ScriptValue {
|
||||
|
||||
// operator on ints
|
||||
#define OPERATOR_I(OP) \
|
||||
a = to_script((int)*a OP (int)*b); \
|
||||
a = to_script(a->toInt() OP b->toInt()); \
|
||||
break
|
||||
|
||||
// operator on bools
|
||||
#define OPERATOR_B(OP) \
|
||||
a = to_script((bool)*a OP (bool)*b); \
|
||||
a = to_script(a->toBool() OP b->toBool()); \
|
||||
break
|
||||
|
||||
// operator on doubles or ints
|
||||
#define OPERATOR_DI(OP) \
|
||||
if (at == SCRIPT_DOUBLE || bt == SCRIPT_DOUBLE) { \
|
||||
a = to_script((double)*a OP (double)*b); \
|
||||
a = to_script(a->toDouble() OP b->toDouble()); \
|
||||
} else { \
|
||||
a = to_script((int)*a OP (int)*b); \
|
||||
a = to_script(a->toInt() OP b->toInt()); \
|
||||
} \
|
||||
break
|
||||
|
||||
// operator on doubles or ints, defined as a function
|
||||
#define OPERATOR_FUN_DI(OP) \
|
||||
if (at == SCRIPT_DOUBLE || bt == SCRIPT_DOUBLE) { \
|
||||
a = to_script(OP((double)*a, (double)*b)); \
|
||||
a = to_script(OP(a->toDouble(), b->toDouble())); \
|
||||
} else { \
|
||||
a = to_script(OP((int)*a, (int)*b)); \
|
||||
a = to_script(OP(a->toInt(), b->toInt())); \
|
||||
} \
|
||||
break
|
||||
|
||||
@@ -455,10 +454,10 @@ class ScriptCompose : public ScriptValue {
|
||||
void instrBinary (BinaryInstructionType i, ScriptValueP& a, const ScriptValueP& b) {
|
||||
switch (i) {
|
||||
case I_MEMBER:
|
||||
a = a->getMember(*b);
|
||||
a = a->getMember(b->toString());
|
||||
break;
|
||||
case I_ITERATOR_R:
|
||||
a = rangeIterator(*a, *b);
|
||||
a = rangeIterator(a->toInt(), b->toInt());
|
||||
break;
|
||||
default:
|
||||
ScriptType at = a->type(), bt = b->type();
|
||||
@@ -473,45 +472,45 @@ void instrBinary (BinaryInstructionType i, ScriptValueP& a, const ScriptValueP&
|
||||
} else if (at == SCRIPT_COLLECTION && bt == SCRIPT_COLLECTION) {
|
||||
a = make_intrusive<ScriptConcatCollection>(a, b);
|
||||
} else if (at == SCRIPT_INT && bt == SCRIPT_INT) {
|
||||
a = to_script((int)*a + (int)*b);
|
||||
a = to_script(a->toInt() + b->toInt());
|
||||
} else if ((at == SCRIPT_INT || at == SCRIPT_DOUBLE) &&
|
||||
(bt == SCRIPT_INT || bt == SCRIPT_DOUBLE)) {
|
||||
a = to_script((double)*a + (double)*b);
|
||||
a = to_script(a->toDouble() + b->toDouble());
|
||||
} else {
|
||||
a = to_script(a->toString() + b->toString());
|
||||
a = to_script(a->toString() + b->toString());
|
||||
}
|
||||
break;
|
||||
case I_SUB: OPERATOR_DI(-);
|
||||
case I_MUL: OPERATOR_DI(*);
|
||||
case I_FDIV:
|
||||
a = to_script((double)*a / (double)*b);
|
||||
a = to_script(a->toDouble() / b->toDouble());
|
||||
break;
|
||||
case I_DIV:
|
||||
if (at == SCRIPT_DOUBLE || bt == SCRIPT_DOUBLE) {
|
||||
a = to_script((int)((double)*a / (double)*b));
|
||||
a = to_script((int)(a->toDouble() / b->toDouble()));
|
||||
} else {
|
||||
a = to_script((int)*a / (int)*b);
|
||||
a = to_script(a->toInt() / b->toInt());
|
||||
}
|
||||
break;
|
||||
case I_MOD:
|
||||
if (at == SCRIPT_DOUBLE || bt == SCRIPT_DOUBLE) {
|
||||
a = to_script(fmod((double)*a, (double)*b));
|
||||
a = to_script(fmod(a->toDouble(), b->toDouble()));
|
||||
} else {
|
||||
a = to_script((int)*a % (int)*b);
|
||||
a = to_script(a->toInt() % b->toInt());
|
||||
}
|
||||
break;
|
||||
case I_POW:
|
||||
if (bt == SCRIPT_INT) {
|
||||
int bi = *b;
|
||||
int bi = b->toInt();
|
||||
if (at == SCRIPT_DOUBLE) {
|
||||
double aa = *a;
|
||||
double aa = a->toDouble();
|
||||
if (bi == 0) a = to_script(1);
|
||||
else if (bi == 1) a = to_script(aa);
|
||||
else if (bi == 2) a = to_script(aa * aa);
|
||||
else if (bi == 3) a = to_script(aa * aa * aa);
|
||||
else a = to_script(pow(aa,bi));
|
||||
} else {
|
||||
int aa = *a;
|
||||
int aa = a->toInt();
|
||||
if (bi == 0) a = to_script(1);
|
||||
else if (bi == 1) a = to_script(aa);
|
||||
else if (bi == 2) a = to_script(aa * aa);
|
||||
@@ -519,20 +518,20 @@ void instrBinary (BinaryInstructionType i, ScriptValueP& a, const ScriptValueP&
|
||||
else a = to_script(pow((double)aa,bi));
|
||||
}
|
||||
} else {
|
||||
a = to_script(pow((double)*a, (double)*b));
|
||||
a = to_script(pow(a->toDouble(), b->toDouble()));
|
||||
}
|
||||
break;
|
||||
case I_AND: OPERATOR_B(&&);
|
||||
case I_AND: OPERATOR_B(&&);
|
||||
case I_OR: OPERATOR_B(||);
|
||||
case I_XOR: OPERATOR_B(!=);
|
||||
case I_XOR: OPERATOR_B(!=);
|
||||
case I_EQ: a = to_script( equal(a,b)); break;
|
||||
case I_NEQ: a = to_script(!equal(a,b)); break;
|
||||
case I_NEQ: a = to_script(!equal(a,b)); break;
|
||||
case I_LT: OPERATOR_DI(<);
|
||||
case I_GT: OPERATOR_DI(>);
|
||||
case I_LE: OPERATOR_DI(<=);
|
||||
case I_GE: OPERATOR_DI(>=);
|
||||
case I_MIN: OPERATOR_FUN_DI(min);
|
||||
case I_MAX: OPERATOR_FUN_DI(max);
|
||||
case I_MIN: OPERATOR_FUN_DI(min);
|
||||
case I_MAX: OPERATOR_FUN_DI(max);
|
||||
case I_OR_ELSE:
|
||||
if (at == SCRIPT_ERROR) a = b;
|
||||
break;
|
||||
@@ -546,7 +545,7 @@ void instrBinary (BinaryInstructionType i, ScriptValueP& a, const ScriptValueP&
|
||||
void instrTernary(TernaryInstructionType i, ScriptValueP& a, const ScriptValueP& b, const ScriptValueP& c) {
|
||||
switch (i) {
|
||||
case I_RGB:
|
||||
a = to_script(Color((int)*a, (int)*b, (int)*c));
|
||||
a = to_script(Color(a->toInt(), b->toInt(), c->toInt()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -556,7 +555,7 @@ void instrTernary(TernaryInstructionType i, ScriptValueP& a, const ScriptValueP&
|
||||
void instrQuaternary(QuaternaryInstructionType i, ScriptValueP& a, const ScriptValueP& b, const ScriptValueP& c, const ScriptValueP& d) {
|
||||
switch (i) {
|
||||
case I_RGBA:
|
||||
a = to_script(Color((int)*a, (int)*b, (int)*c, (int)*d));
|
||||
a = to_script(Color(a->toInt(), b->toInt(), c->toInt(), d->toInt()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
+10
-10
@@ -76,16 +76,16 @@ ScriptValueP unified(const ScriptValueP& a, const ScriptValueP& b) {
|
||||
|
||||
/// Behaves like script_nil, but with a name
|
||||
class ScriptMissingVariable : public ScriptValue {
|
||||
public:
|
||||
public:
|
||||
ScriptMissingVariable(const String& name) : name(name) {}
|
||||
virtual ScriptType type() const { return SCRIPT_NIL; }
|
||||
virtual String typeName() const { return _("missing variable '") + name + _("'"); }
|
||||
virtual operator String() const { return wxEmptyString; }
|
||||
virtual operator double() const { return 0.0; }
|
||||
virtual operator int() const { return 0; }
|
||||
virtual operator bool() const { return false; }
|
||||
virtual ScriptValueP eval(Context&) const { return script_nil; } // nil() == nil
|
||||
private:
|
||||
ScriptType type() const override { return SCRIPT_NIL; }
|
||||
String typeName() const override { return _("missing variable '") + name + _("'"); }
|
||||
String toString() const override { return String(); }
|
||||
double toDouble() const override { return 0.0; }
|
||||
int toInt() const override { return 0; }
|
||||
bool toBool() const override { return false; }
|
||||
ScriptValueP eval(Context&, bool) const override { return script_nil; } // nil() == nil
|
||||
private:
|
||||
String name; ///< Name of the variable
|
||||
};
|
||||
|
||||
@@ -224,7 +224,7 @@ ScriptValueP Context::dependencies(const Dependency& dep, const Script& script)
|
||||
|
||||
// Get an object member (almost as normal)
|
||||
case I_MEMBER_C: {
|
||||
String name = *script.constants[i.data];
|
||||
String name = script.constants[i.data]->toString();
|
||||
stack.back() = stack.back()->dependencyMember(name, dep); // dependency on member
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -76,9 +76,9 @@ String format_input(const String& format, const ScriptValue& input) {
|
||||
// determine type expected by format string
|
||||
String fmt = _("%") + replace_all(format, _("%"), _(""));
|
||||
if (format.find_first_of(_("DdIiOoXx")) != String::npos) {
|
||||
return String::Format(fmt, (int)input);
|
||||
return String::Format(fmt, input.toInt());
|
||||
} else if (format.find_first_of(_("EeFfGg")) != String::npos) {
|
||||
return String::Format(fmt, (double)input);
|
||||
return String::Format(fmt, input.toDouble());
|
||||
} else if (format.find_first_of(_("Ss")) != String::npos) {
|
||||
return format_string(fmt, input.toString());
|
||||
} else {
|
||||
@@ -93,13 +93,13 @@ SCRIPT_FUNCTION(to_string) {
|
||||
try {
|
||||
if (format && format->type() == SCRIPT_STRING) {
|
||||
// format specifier. Be careful, the built in function 'format' has the same name
|
||||
SCRIPT_RETURN(format_input(*format, *input));
|
||||
SCRIPT_RETURN(format_input(format->toString(), *input));
|
||||
} else {
|
||||
// simple conversion
|
||||
SCRIPT_RETURN(input->toString());
|
||||
}
|
||||
} catch (const ScriptError& e) {
|
||||
return make_intrusive<ScriptDelayedError>(e);
|
||||
return delay_error(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,9 +109,9 @@ SCRIPT_FUNCTION(to_int) {
|
||||
try {
|
||||
int result;
|
||||
if (t == SCRIPT_BOOL) {
|
||||
result = (bool)*input ? 1 : 0;
|
||||
result = input->toBool() ? 1 : 0;
|
||||
} else if (t == SCRIPT_COLOR) {
|
||||
Color c = input->operator Color();
|
||||
Color c = input->toColor();
|
||||
result = (c.Red() + c.Blue() + c.Green()) / 3;
|
||||
} else if (t == SCRIPT_STRING) {
|
||||
long l;
|
||||
@@ -124,7 +124,7 @@ SCRIPT_FUNCTION(to_int) {
|
||||
return delay_error(ScriptErrorConversion(str, input->typeName(), _TYPE_("integer")));
|
||||
}
|
||||
} else {
|
||||
result = (int)*input;
|
||||
result = input->toInt();
|
||||
}
|
||||
SCRIPT_RETURN(result);
|
||||
} catch (const ScriptError& e) {
|
||||
@@ -138,9 +138,9 @@ SCRIPT_FUNCTION(to_real) {
|
||||
try {
|
||||
double result;
|
||||
if (t == SCRIPT_BOOL) {
|
||||
result = (bool)*input ? 1.0 : 0.0;
|
||||
result = input->toBool() ? 1.0 : 0.0;
|
||||
} else if (t == SCRIPT_COLOR) {
|
||||
Color c = input->operator Color();
|
||||
Color c = input->toColor();
|
||||
result = (c.Red() + c.Blue() + c.Green()) / 3.0;
|
||||
} else if (t == SCRIPT_STRING) {
|
||||
String str = input->toString();
|
||||
@@ -150,7 +150,7 @@ SCRIPT_FUNCTION(to_real) {
|
||||
return delay_error(ScriptErrorConversion(str, input->typeName(), _TYPE_("double")));
|
||||
}
|
||||
} else {
|
||||
result = (double)*input;
|
||||
result = input->toDouble();
|
||||
}
|
||||
SCRIPT_RETURN(result);
|
||||
} catch (const ScriptError& e) {
|
||||
@@ -163,12 +163,12 @@ SCRIPT_FUNCTION(to_number) {
|
||||
ScriptType t = input->type();
|
||||
try {
|
||||
if (t == SCRIPT_BOOL) {
|
||||
SCRIPT_RETURN((bool)*input ? 1 : 0);
|
||||
SCRIPT_RETURN(input->toBool() ? 1 : 0);
|
||||
} else if (t == SCRIPT_COLOR) {
|
||||
Color c = input->operator Color();
|
||||
Color c = input->toColor();
|
||||
SCRIPT_RETURN( (c.Red() + c.Blue() + c.Green()) / 3 );
|
||||
} else if (t == SCRIPT_DOUBLE) {
|
||||
SCRIPT_RETURN((double)*input);
|
||||
SCRIPT_RETURN(input->toDouble());
|
||||
} else if (t == SCRIPT_NIL) {
|
||||
SCRIPT_RETURN(0);
|
||||
} else {
|
||||
@@ -195,9 +195,9 @@ SCRIPT_FUNCTION(to_boolean) {
|
||||
ScriptType t = input->type();
|
||||
bool result;
|
||||
if (t == SCRIPT_INT) {
|
||||
result = (int)*input != 0;
|
||||
result = input->toInt() != 0;
|
||||
} else {
|
||||
result = (bool)*input;
|
||||
result = input->toBool();
|
||||
}
|
||||
SCRIPT_RETURN(result);
|
||||
} catch (const ScriptError& e) {
|
||||
@@ -239,9 +239,9 @@ SCRIPT_FUNCTION(abs) {
|
||||
ScriptValueP input = ctx.getVariable(SCRIPT_VAR_input);
|
||||
ScriptType t = input->type();
|
||||
if (t == SCRIPT_DOUBLE) {
|
||||
SCRIPT_RETURN(fabs((double)*input));
|
||||
SCRIPT_RETURN(fabs(input->toDouble()));
|
||||
} else {
|
||||
SCRIPT_RETURN(abs((int)*input));
|
||||
SCRIPT_RETURN(abs(input->toInt()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -579,7 +579,7 @@ SCRIPT_FUNCTION(filter_list) {
|
||||
ScriptValueP it = input->makeIterator();
|
||||
while (ScriptValueP v = it->next()) {
|
||||
ctx.setVariable(SCRIPT_VAR_input, v);
|
||||
if (*filter->eval(ctx)) {
|
||||
if (filter->eval(ctx)->toBool()) {
|
||||
ret->value.push_back(v);
|
||||
}
|
||||
}
|
||||
@@ -628,7 +628,7 @@ SCRIPT_FUNCTION(random_select_many) {
|
||||
SCRIPT_PARAM_C(ScriptValueP, input);
|
||||
SCRIPT_PARAM(int, count) ;
|
||||
SCRIPT_OPTIONAL_PARAM_C_(ScriptValueP, replace);
|
||||
bool with_replace = replace && replace->type() != SCRIPT_FUNCTION && (bool)*replace;
|
||||
bool with_replace = replace && replace->type() != SCRIPT_FUNCTION && replace->toBool();
|
||||
// pick many
|
||||
ScriptCustomCollectionP ret(new ScriptCustomCollection);
|
||||
int itemCount = input->itemCount();
|
||||
|
||||
@@ -44,7 +44,7 @@ SCRIPT_FUNCTION(new_card) {
|
||||
} else if (PackageChoiceValue* pvalue = dynamic_cast<PackageChoiceValue*>(value)) {
|
||||
pvalue->package_name = v->toString();
|
||||
} else if (ColorValue* cvalue = dynamic_cast<ColorValue*>(value)) {
|
||||
cvalue->value = v->operator Color();
|
||||
cvalue->value = v->toColor();
|
||||
} else {
|
||||
throw ScriptError(format_string(_("Can not set value '%s', it is not of the right type"),name));
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ ScriptRegexP regex_from_script(const ScriptValueP& value) {
|
||||
ScriptRegexP regex = dynamic_pointer_cast<ScriptRegex>(value);
|
||||
if (!regex) {
|
||||
// TODO: introduce some kind of caching?
|
||||
regex = make_intrusive<ScriptRegex>(*value);
|
||||
regex = make_intrusive<ScriptRegex>(value->toString());
|
||||
}
|
||||
return regex;
|
||||
}
|
||||
|
||||
@@ -37,12 +37,12 @@ inline size_t spelled_correctly(const String& input, size_t start, size_t end, S
|
||||
if (extra_test) {
|
||||
// try on untagged
|
||||
ctx.setVariable(SCRIPT_VAR_input, to_script(word));
|
||||
if (*extra_test->eval(ctx)) {
|
||||
if (extra_test->eval(ctx)->toBool()) {
|
||||
return true;
|
||||
}
|
||||
// try on tagged
|
||||
ctx.setVariable(SCRIPT_VAR_input, to_script(input.substr(start,end-start)));
|
||||
if (*extra_test->eval(ctx)) {
|
||||
if (extra_test->eval(ctx)->toBool()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,31 +37,31 @@
|
||||
#define SCRIPT_FUNCTION(name) SCRIPT_FUNCTION_AUX(name,;)
|
||||
|
||||
/// Macro to declare a new script function with custom dependency handling
|
||||
#define SCRIPT_FUNCTION_WITH_DEP(name) \
|
||||
SCRIPT_FUNCTION_AUX(name, virtual ScriptValueP dependencies(Context&, const Dependency&) const;)
|
||||
#define SCRIPT_FUNCTION_WITH_DEP(name) \
|
||||
SCRIPT_FUNCTION_AUX(name, ScriptValueP dependencies(Context&, const Dependency&) const override;)
|
||||
|
||||
#define SCRIPT_FUNCTION_DEPENDENCIES(name) \
|
||||
#define SCRIPT_FUNCTION_DEPENDENCIES(name) \
|
||||
ScriptValueP ScriptBuiltIn_##name::dependencies(Context& ctx, const Dependency& dep) const
|
||||
|
||||
/// Macro to declare a new script function with custom closure simplification
|
||||
#define SCRIPT_FUNCTION_WITH_SIMPLIFY(name) \
|
||||
SCRIPT_FUNCTION_AUX(name, virtual ScriptValueP simplifyClosure(ScriptClosure&) const;)
|
||||
#define SCRIPT_FUNCTION_WITH_SIMPLIFY(name) \
|
||||
SCRIPT_FUNCTION_AUX(name, ScriptValueP simplifyClosure(ScriptClosure&) const override;)
|
||||
|
||||
#define SCRIPT_FUNCTION_SIMPLIFY_CLOSURE(name) \
|
||||
#define SCRIPT_FUNCTION_SIMPLIFY_CLOSURE(name) \
|
||||
ScriptValueP ScriptBuiltIn_##name::simplifyClosure(ScriptClosure& closure) const
|
||||
|
||||
// helper for SCRIPT_FUNCTION and SCRIPT_FUNCTION_DEP
|
||||
#define SCRIPT_FUNCTION_AUX(name,dep) \
|
||||
class ScriptBuiltIn_##name : public ScriptValue { \
|
||||
dep \
|
||||
virtual ScriptType type() const \
|
||||
{ return SCRIPT_FUNCTION; } \
|
||||
virtual String typeName() const \
|
||||
#define SCRIPT_FUNCTION_AUX(name,dep) \
|
||||
class ScriptBuiltIn_##name : public ScriptValue { \
|
||||
dep \
|
||||
ScriptType type() const override \
|
||||
{ return SCRIPT_FUNCTION; } \
|
||||
String typeName() const override \
|
||||
{ return _("built-in function '") _(#name) _("'"); } \
|
||||
virtual ScriptValueP do_eval(Context&, bool) const; \
|
||||
ScriptValueP eval(Context&, bool) const override; \
|
||||
}; \
|
||||
ScriptValueP script_##name(new ScriptBuiltIn_##name); \
|
||||
ScriptValueP ScriptBuiltIn_##name::do_eval(Context& ctx, bool) const
|
||||
ScriptValueP ScriptBuiltIn_##name::eval(Context& ctx, bool) const
|
||||
|
||||
/// Return a value from a SCRIPT_FUNCTION
|
||||
#define SCRIPT_RETURN(value) return to_script(value)
|
||||
@@ -157,10 +157,10 @@ inline Type from_script(const ScriptValueP& v, Variable var) {
|
||||
class ScriptRule_##funname: public ScriptValue { \
|
||||
public: \
|
||||
inline ScriptRule_##funname(const type1& name1) : name1(name1) {} \
|
||||
virtual ScriptType type() const { return SCRIPT_FUNCTION; } \
|
||||
virtual String typeName() const { return _(#funname)_("_rule"); } \
|
||||
ScriptType type() const override { return SCRIPT_FUNCTION; } \
|
||||
String typeName() const override { return _(#funname)_("_rule"); } \
|
||||
protected: \
|
||||
virtual ScriptValueP do_eval(Context& ctx, bool) const; \
|
||||
ScriptValueP eval(Context& ctx, bool) const override; \
|
||||
private: \
|
||||
type1 name1; \
|
||||
}; \
|
||||
@@ -172,7 +172,7 @@ inline Type from_script(const ScriptValueP& v, Variable var) {
|
||||
SCRIPT_PARAM_N(type1, str1, name1); \
|
||||
return ScriptRule_##funname(name1).eval(ctx); \
|
||||
} \
|
||||
ScriptValueP ScriptRule_##funname::do_eval(Context& ctx, bool) const
|
||||
ScriptValueP ScriptRule_##funname::eval(Context& ctx, bool) const
|
||||
|
||||
/// Utility for defining a script rule with two parameters
|
||||
#define SCRIPT_RULE_2(funname, type1, name1, type2, name2) \
|
||||
@@ -185,7 +185,7 @@ inline Type from_script(const ScriptValueP& v, Variable var) {
|
||||
/// Utility for defining a script rule with two named parameters, with dependencies
|
||||
#define SCRIPT_RULE_2_N_DEP(funname, type1, str1, name1, type2, str2, name2) \
|
||||
SCRIPT_RULE_2_N_AUX( funname, type1, str1, name1, type2, str2, name2, \
|
||||
virtual ScriptValueP dependencies(Context&, const Dependency&) const; \
|
||||
ScriptValueP dependencies(Context&, const Dependency&) const override; \
|
||||
SCRIPT_FUNCTION_DEPENDENCIES(funname) { \
|
||||
SCRIPT_PARAM_N(type1, str1, name1); \
|
||||
SCRIPT_PARAM_N(type2, str2, name2); \
|
||||
@@ -197,11 +197,11 @@ inline Type from_script(const ScriptValueP& v, Variable var) {
|
||||
public: \
|
||||
inline ScriptRule_##funname(const type1& name1, const type2& name2) \
|
||||
: name1(name1), name2(name2) {} \
|
||||
virtual ScriptType type() const { return SCRIPT_FUNCTION; } \
|
||||
virtual String typeName() const { return _(#funname)_("_rule"); } \
|
||||
ScriptType type() const override { return SCRIPT_FUNCTION; } \
|
||||
String typeName() const override { return _(#funname)_("_rule"); } \
|
||||
dep \
|
||||
protected: \
|
||||
virtual ScriptValueP do_eval(Context& ctx, bool) const; \
|
||||
ScriptValueP eval(Context& ctx, bool) const override; \
|
||||
private: \
|
||||
type1 name1; \
|
||||
type2 name2; \
|
||||
@@ -217,7 +217,7 @@ inline Type from_script(const ScriptValueP& v, Variable var) {
|
||||
return ScriptRule_##funname(name1, name2).eval(ctx); \
|
||||
} \
|
||||
more \
|
||||
ScriptValueP ScriptRule_##funname::do_eval(Context& ctx, bool) const
|
||||
ScriptValueP ScriptRule_##funname::eval(Context& ctx, bool) const
|
||||
|
||||
#define SCRIPT_RULE_2_DEPENDENCIES(name) \
|
||||
ScriptValueP ScriptRule_##name::dependencies(Context& ctx, const Dependency& dep) const
|
||||
|
||||
@@ -88,7 +88,7 @@ ScriptType Script::type() const {
|
||||
String Script::typeName() const {
|
||||
return _("function");
|
||||
}
|
||||
ScriptValueP Script::do_eval(Context& ctx, bool openScope) const {
|
||||
ScriptValueP Script::eval(Context& ctx, bool openScope) const {
|
||||
return ctx.eval(*this, openScope);
|
||||
}
|
||||
ScriptValueP Script::dependencies(Context& ctx, const Dependency& dep) const {
|
||||
|
||||
@@ -163,11 +163,11 @@ void init_script_variables();
|
||||
* The script is itself a ScriptValue
|
||||
*/
|
||||
class Script : public ScriptValue {
|
||||
public:
|
||||
public:
|
||||
|
||||
virtual ScriptType type() const;
|
||||
virtual String typeName() const;
|
||||
virtual ScriptValueP dependencies(Context& ctx, const Dependency&) const;
|
||||
ScriptType type() const override;
|
||||
String typeName() const override;
|
||||
ScriptValueP dependencies(Context& ctx, const Dependency&) const override;
|
||||
|
||||
/// Add a jump instruction, later comeFrom should be called on the returned value
|
||||
unsigned int addInstruction(InstructionType t);
|
||||
@@ -196,10 +196,9 @@ class Script : public ScriptValue {
|
||||
/// Output an instruction in a human readable format
|
||||
String dumpInstr(unsigned int pos, Instruction i) const;
|
||||
|
||||
protected:
|
||||
virtual ScriptValueP do_eval(Context& ctx, bool openScope) const;
|
||||
ScriptValueP eval(Context& ctx, bool openScope = true) const override;
|
||||
|
||||
private:
|
||||
private:
|
||||
/// Data of the instructions that make up this script
|
||||
vector<Instruction> instructions;
|
||||
/// Constant values that can be referred to from the script
|
||||
|
||||
@@ -20,12 +20,12 @@ void parse_enum(const String&,Direction&);
|
||||
// ----------------------------------------------------------------------------- : Store
|
||||
|
||||
void store(const ScriptValueP& val, String& var) { var = val->toString(); }
|
||||
void store(const ScriptValueP& val, int& var) { var = *val; }
|
||||
void store(const ScriptValueP& val, double& var) { var = *val; }
|
||||
void store(const ScriptValueP& val, bool& var) { var = *val; }
|
||||
void store(const ScriptValueP& val, Color& var) { var = *val; }
|
||||
void store(const ScriptValueP& val, Defaultable<String>& var) { var.assign(*val); }
|
||||
void store(const ScriptValueP& val, Defaultable<Color>& var) { var.assign(*val); }
|
||||
void store(const ScriptValueP& val, int& var) { var = val->toInt(); }
|
||||
void store(const ScriptValueP& val, double& var) { var = val->toDouble(); }
|
||||
void store(const ScriptValueP& val, bool& var) { var = val->toBool(); }
|
||||
void store(const ScriptValueP& val, Color& var) { var = val->toColor(); }
|
||||
void store(const ScriptValueP& val, Defaultable<String>& var) { var.assign(val->toString()); }
|
||||
void store(const ScriptValueP& val, Defaultable<Color>& var) { var.assign(val->toColor()); }
|
||||
void store(const ScriptValueP& val, Alignment& var) { var = from_string(val->toString()); }
|
||||
void store(const ScriptValueP& val, Direction& var) { parse_enum(val->toString(),var); }
|
||||
|
||||
|
||||
+128
-125
@@ -61,56 +61,22 @@ template <typename T> inline String to_code(const intrusive_ptr<T>& p) {
|
||||
|
||||
// ----------------------------------------------------------------------------- : Errors
|
||||
|
||||
/// A delayed error message.
|
||||
/** Only when trying to use the object will the error be thrown.
|
||||
* This can be 'caught' by the "or else" construct
|
||||
*/
|
||||
class ScriptDelayedError : public ScriptValue {
|
||||
public:
|
||||
inline ScriptDelayedError(const ScriptError& error) : error(error) {}
|
||||
|
||||
virtual ScriptType type() const;// { return SCRIPT_ERROR; }
|
||||
|
||||
// all of these throw
|
||||
virtual String typeName() const;
|
||||
virtual operator String() const;
|
||||
virtual operator double() const;
|
||||
virtual operator int() const;
|
||||
virtual operator bool() const;
|
||||
virtual operator Color() const;
|
||||
virtual int itemCount() const;
|
||||
virtual CompareWhat compareAs(String&, void const*&) const;
|
||||
// these can propagate the error
|
||||
virtual ScriptValueP getMember(const String& name) const;
|
||||
virtual ScriptValueP dependencyMember(const String& name, const Dependency&) const;
|
||||
virtual ScriptValueP dependencies(Context&, const Dependency&) const;
|
||||
virtual ScriptValueP makeIterator(const ScriptValueP& thisP) const;
|
||||
|
||||
protected:
|
||||
virtual ScriptValueP do_eval(Context&, bool openScope) const;
|
||||
|
||||
private:
|
||||
ScriptError error; // the error message
|
||||
};
|
||||
|
||||
ScriptValueP delay_error(const ScriptError& error);
|
||||
inline ScriptValueP delay_error(const String& m) {
|
||||
return make_intrusive<ScriptDelayedError>(ScriptError(m));
|
||||
}
|
||||
inline ScriptValueP delay_error(const ScriptError& error) {
|
||||
return make_intrusive<ScriptDelayedError>(error);
|
||||
return delay_error(ScriptError(m));
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : Iterators
|
||||
|
||||
// Iterator over a collection
|
||||
struct ScriptIterator : public ScriptValue {
|
||||
virtual ScriptType type() const;// { return SCRIPT_ITERATOR; }
|
||||
virtual String typeName() const;// { return "iterator"; }
|
||||
virtual CompareWhat compareAs(String&, void const*&) const; // { return COMPARE_NO; }
|
||||
ScriptType type() const override;
|
||||
String typeName() const override;
|
||||
CompareWhat compareAs(String&, void const*&) const override;
|
||||
|
||||
/// Return the next item for this iterator, or ScriptValueP() if there is no such item
|
||||
virtual ScriptValueP next(ScriptValueP* key_out = nullptr) = 0;
|
||||
virtual ScriptValueP makeIterator(const ScriptValueP& thisP) const;
|
||||
ScriptValueP next(ScriptValueP* key_out = nullptr) override = 0;
|
||||
ScriptValueP makeIterator(const ScriptValueP& thisP) const override;
|
||||
};
|
||||
|
||||
// make an iterator over a range
|
||||
@@ -121,18 +87,18 @@ ScriptValueP rangeIterator(int start, int end);
|
||||
ScriptValueP to_script(int);
|
||||
|
||||
class ScriptCollectionBase : public ScriptValue {
|
||||
public:
|
||||
virtual ScriptType type() const { return SCRIPT_COLLECTION; }
|
||||
virtual String typeName() const { return _TYPE_("collection"); }
|
||||
virtual String toCode() const;
|
||||
public:
|
||||
ScriptType type() const override { return SCRIPT_COLLECTION; }
|
||||
String typeName() const override { return _TYPE_("collection"); }
|
||||
String toCode() const override;
|
||||
};
|
||||
|
||||
// Iterator over a collection
|
||||
template <typename Collection>
|
||||
class ScriptCollectionIterator : public ScriptIterator {
|
||||
public:
|
||||
public:
|
||||
ScriptCollectionIterator(const Collection* col) : pos(0), col(col) {}
|
||||
virtual ScriptValueP next(ScriptValueP* key_out) {
|
||||
ScriptValueP next(ScriptValueP* key_out) override {
|
||||
if (pos < col->size()) {
|
||||
if (key_out) *key_out = to_script((int)pos);
|
||||
return to_script(col->at(pos++));
|
||||
@@ -140,34 +106,38 @@ class ScriptCollectionIterator : public ScriptIterator {
|
||||
return ScriptValueP();
|
||||
}
|
||||
}
|
||||
private:
|
||||
private:
|
||||
size_t pos;
|
||||
const Collection* col;
|
||||
};
|
||||
|
||||
/// Script value containing a collection
|
||||
/// Script value containing a collection (vector like)
|
||||
template <typename Collection>
|
||||
class ScriptCollection : public ScriptCollectionBase {
|
||||
public:
|
||||
public:
|
||||
inline ScriptCollection(const Collection* v) : value(v) {}
|
||||
virtual String typeName() const { return _TYPE_1_("collection of", type_name(*value->begin())); }
|
||||
virtual ScriptValueP getIndex(int index) const {
|
||||
String typeName() const override {
|
||||
return _TYPE_1_("collection of", type_name(*value->begin()));
|
||||
}
|
||||
ScriptValueP getIndex(int index) const override {
|
||||
if (index >= 0 && index < (int)value->size()) {
|
||||
return to_script(value->at(index));
|
||||
} else {
|
||||
return ScriptValue::getIndex(index);
|
||||
}
|
||||
}
|
||||
virtual ScriptValueP makeIterator(const ScriptValueP& thisP) const {
|
||||
ScriptValueP makeIterator(const ScriptValueP& thisP) const override {
|
||||
return make_intrusive<ScriptCollectionIterator<Collection>>(value);
|
||||
}
|
||||
virtual int itemCount() const { return (int)value->size(); }
|
||||
int itemCount() const override {
|
||||
return (int)value->size();
|
||||
}
|
||||
/// Collections can be compared by comparing pointers
|
||||
virtual CompareWhat compareAs(String&, void const*& compare_ptr) const {
|
||||
CompareWhat compareAs(String&, void const*& compare_ptr) const override {
|
||||
compare_ptr = value;
|
||||
return COMPARE_AS_POINTER;
|
||||
}
|
||||
private:
|
||||
private:
|
||||
/// Store a pointer to a collection, collections are only ever used for structures owned outside the script
|
||||
const Collection* value;
|
||||
};
|
||||
@@ -197,24 +167,24 @@ ScriptValueP get_member(const IndexMap<K,V>& m, const String& name) {
|
||||
/// Script value containing a map-like collection
|
||||
template <typename Collection>
|
||||
class ScriptMap : public ScriptValue {
|
||||
public:
|
||||
public:
|
||||
inline ScriptMap(const Collection* v) : value(v) {}
|
||||
virtual ScriptType type() const { return SCRIPT_COLLECTION; }
|
||||
virtual String typeName() const { return _TYPE_1_("collection of", type_name(value->begin())); }
|
||||
virtual ScriptValueP getMember(const String& name) const {
|
||||
ScriptType type() const override { return SCRIPT_COLLECTION; }
|
||||
String typeName() const override { return _TYPE_1_("collection of", type_name(value->begin())); }
|
||||
ScriptValueP getMember(const String& name) const override {
|
||||
return get_member(*value, name);
|
||||
}
|
||||
virtual int itemCount() const { return (int)value->size(); }
|
||||
virtual ScriptValueP dependencyMember(const String& name, const Dependency& dep) const {
|
||||
int itemCount() const override { return (int)value->size(); }
|
||||
ScriptValueP dependencyMember(const String& name, const Dependency& dep) const override {
|
||||
mark_dependency_member(*value, name, dep);
|
||||
return getMember(name);
|
||||
}
|
||||
/// Collections can be compared by comparing pointers
|
||||
virtual CompareWhat compareAs(String&, void const*& compare_ptr) const {
|
||||
CompareWhat compareAs(String&, void const*& compare_ptr) const override {
|
||||
compare_ptr = value;
|
||||
return COMPARE_AS_POINTER;
|
||||
}
|
||||
private:
|
||||
private:
|
||||
/// Store a pointer to a collection, collections are only ever used for structures owned outside the script
|
||||
const Collection* value;
|
||||
};
|
||||
@@ -223,7 +193,7 @@ class ScriptMap : public ScriptValue {
|
||||
|
||||
/// Script value containing a custom collection, returned from script functions
|
||||
class ScriptCustomCollection : public ScriptCollectionBase {
|
||||
public:
|
||||
public:
|
||||
ScriptValueP getMember(const String& name) const override;
|
||||
ScriptValueP getIndex(int index) const override;
|
||||
ScriptValueP makeIterator(const ScriptValueP& thisP) const override;
|
||||
@@ -248,19 +218,19 @@ DECLARE_POINTER_TYPE(ScriptCustomCollection);
|
||||
|
||||
/// Script value containing the concatenation of two collections
|
||||
class ScriptConcatCollection : public ScriptCollectionBase {
|
||||
public:
|
||||
public:
|
||||
inline ScriptConcatCollection(ScriptValueP a, ScriptValueP b) : a(a), b(b) {}
|
||||
virtual ScriptValueP getMember(const String& name) const;
|
||||
virtual ScriptValueP getIndex(int index) const;
|
||||
virtual ScriptValueP makeIterator(const ScriptValueP& thisP) const;
|
||||
virtual int itemCount() const { return a->itemCount() + b->itemCount(); }
|
||||
ScriptValueP getMember(const String& name) const override;
|
||||
ScriptValueP getIndex(int index) const override;
|
||||
ScriptValueP makeIterator(const ScriptValueP& thisP) const override;
|
||||
int itemCount() const override { return a->itemCount() + b->itemCount(); }
|
||||
/// Collections can be compared by comparing pointers
|
||||
virtual CompareWhat compareAs(String&, void const*& compare_ptr) const {
|
||||
CompareWhat compareAs(String&, void const*& compare_ptr) const override {
|
||||
compare_ptr = this;
|
||||
return COMPARE_AS_POINTER;
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
ScriptValueP a,b;
|
||||
friend class ScriptConcatCollectionIterator;
|
||||
};
|
||||
@@ -270,24 +240,37 @@ class ScriptConcatCollection : public ScriptCollectionBase {
|
||||
/// Script value containing an object (pointer)
|
||||
template <typename T>
|
||||
class ScriptObject : public ScriptValue {
|
||||
public:
|
||||
public:
|
||||
inline ScriptObject(const T& v) : value(v) {}
|
||||
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 Color() const { ScriptValueP d = getDefault(); return d ? *d : ScriptValue::operator Color(); }
|
||||
virtual String toCode() const { ScriptValueP d = getDefault(); return d ? d->toCode() : to_code(*value); }
|
||||
virtual GeneratedImageP toImage(const ScriptValueP& thisP) const {
|
||||
ScriptType type() const override { ScriptValueP d = getDefault(); return d ? d->type() : SCRIPT_OBJECT; }
|
||||
String typeName() const override { return type_name(*value); }
|
||||
String toString() const override {
|
||||
ScriptValueP d = getDefault(); return d ? d->toString() : ScriptValue::toString();
|
||||
}
|
||||
double toDouble() const override {
|
||||
ScriptValueP d = getDefault(); return d ? d->toDouble() : ScriptValue::toDouble();
|
||||
}
|
||||
int toInt() const override {
|
||||
ScriptValueP d = getDefault(); return d ? d->toInt() : ScriptValue::toInt();
|
||||
}
|
||||
bool toBool() const override {
|
||||
ScriptValueP d = getDefault(); return d ? d->toBool() : ScriptValue::toBool();
|
||||
}
|
||||
Color toColor() const override {
|
||||
ScriptValueP d = getDefault(); return d ? d->toColor() : ScriptValue::toColor();
|
||||
}
|
||||
String toCode() const override {
|
||||
ScriptValueP d = getDefault(); return d ? d->toCode() : to_code(*value);
|
||||
}
|
||||
GeneratedImageP toImage(const ScriptValueP& thisP) const override {
|
||||
ScriptValueP d = getDefault(); return d ? d->toImage(d) : ScriptValue::toImage(thisP);
|
||||
}
|
||||
virtual ScriptValueP getMember(const String& name) const {
|
||||
ScriptValueP getMember(const String& name) const override {
|
||||
#if USE_SCRIPT_PROFILING
|
||||
Timer t;
|
||||
Profiler prof(t, (void*)mangled_name(typeid(T)), _("get member of ") + type_name(*value));
|
||||
#endif
|
||||
// Use reflection to find the member of the object
|
||||
GetMember gm(name);
|
||||
gm.handle(*value);
|
||||
if (gm.result()) return gm.result();
|
||||
@@ -301,22 +284,24 @@ class ScriptObject : public ScriptValue {
|
||||
}
|
||||
}
|
||||
}
|
||||
virtual ScriptValueP getIndex(int index) const { ScriptValueP d = getDefault(); return d ? d->getIndex(index) : ScriptValue::getIndex(index); }
|
||||
virtual ScriptValueP dependencyMember(const String& name, const Dependency& dep) const {
|
||||
ScriptValueP getIndex(int index) const override {
|
||||
ScriptValueP d = getDefault(); return d ? d->getIndex(index) : ScriptValue::getIndex(index);
|
||||
}
|
||||
ScriptValueP dependencyMember(const String& name, const Dependency& dep) const override {
|
||||
mark_dependency_member(*value, name, dep);
|
||||
return getMember(name);
|
||||
}
|
||||
virtual void dependencyThis(const Dependency& dep) {
|
||||
void dependencyThis(const Dependency& dep) override {
|
||||
mark_dependency_value(*value, dep);
|
||||
}
|
||||
virtual ScriptValueP makeIterator(const ScriptValueP& thisP) const {
|
||||
ScriptValueP makeIterator(const ScriptValueP& thisP) const override {
|
||||
ScriptValueP it = make_iterator(*value);
|
||||
if (it) return it;
|
||||
ScriptValueP d = getDefault();
|
||||
if (d) return d->makeIterator(d);
|
||||
return ScriptValue::makeIterator(thisP);
|
||||
}
|
||||
virtual int itemCount() const {
|
||||
int itemCount() const override {
|
||||
int i = item_count(*value);
|
||||
if (i >= 0) return i;
|
||||
ScriptValueP d = getDefault();
|
||||
@@ -324,7 +309,7 @@ class ScriptObject : public ScriptValue {
|
||||
return ScriptValue::itemCount();
|
||||
}
|
||||
/// Objects can be compared by comparing pointers
|
||||
virtual CompareWhat compareAs(String& compare_str, void const*& compare_ptr) const {
|
||||
CompareWhat compareAs(String& compare_str, void const*& compare_ptr) const override {
|
||||
ScriptValueP d = getDefault();
|
||||
if (d) {
|
||||
return d->compareAs(compare_str, compare_ptr);
|
||||
@@ -335,7 +320,7 @@ class ScriptObject : public ScriptValue {
|
||||
}
|
||||
/// Get access to the value
|
||||
inline T getValue() const { return value; }
|
||||
private:
|
||||
private:
|
||||
T value; ///< The object
|
||||
ScriptValueP getDefault() const {
|
||||
GetDefaultMember gdm;
|
||||
@@ -348,12 +333,12 @@ class ScriptObject : public ScriptValue {
|
||||
|
||||
/// A wrapper around a function that gives default arguments
|
||||
class ScriptClosure : public ScriptValue {
|
||||
public:
|
||||
public:
|
||||
ScriptClosure(ScriptValueP fun) : fun(fun) {}
|
||||
|
||||
virtual ScriptType type() const;
|
||||
virtual String typeName() const;
|
||||
virtual ScriptValueP dependencies(Context& ctx, const Dependency& dep) const;
|
||||
ScriptType type() const override;
|
||||
String typeName() const override;
|
||||
ScriptValueP dependencies(Context& ctx, const Dependency& dep) const override;
|
||||
|
||||
/// Add a binding
|
||||
void addBinding(Variable v, const ScriptValueP& value);
|
||||
@@ -363,69 +348,87 @@ class ScriptClosure : public ScriptValue {
|
||||
/// Try to simplify this closure, returns a value if successful
|
||||
ScriptValueP simplify();
|
||||
|
||||
ScriptValueP eval(Context& ctx, bool openScope) const override;
|
||||
|
||||
/// The wrapped function
|
||||
ScriptValueP fun;
|
||||
/// The default argument bindings
|
||||
vector<pair<Variable,ScriptValueP> > bindings;
|
||||
|
||||
protected:
|
||||
virtual ScriptValueP do_eval(Context& ctx, bool openScope) const;
|
||||
|
||||
private:
|
||||
private:
|
||||
/// Apply the bindings in a context
|
||||
void applyBindings(Context& ctx) const;
|
||||
};
|
||||
|
||||
/// Turn a script function into a rule, a.k.a. a delayed closure
|
||||
class ScriptRule : public ScriptValue {
|
||||
public:
|
||||
public:
|
||||
inline ScriptRule(const ScriptValueP& fun) : fun(fun) {}
|
||||
virtual ScriptType type() const;
|
||||
virtual String typeName() const;
|
||||
ScriptType type() const override;
|
||||
String typeName() const override;
|
||||
ScriptValueP eval(Context& ctx, bool openScope) const override;
|
||||
|
||||
protected:
|
||||
virtual ScriptValueP do_eval(Context& ctx, bool openScope) const;
|
||||
|
||||
private:
|
||||
private:
|
||||
ScriptValueP fun;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------- : Creating
|
||||
|
||||
extern ScriptValueP script_nil; ///< The preallocated nil value
|
||||
extern ScriptValueP script_true; ///< The preallocated true value
|
||||
extern ScriptValueP script_false; ///< The preallocated false value
|
||||
extern ScriptValueP dependency_dummy; ///< Dummy value used during dependency analysis
|
||||
|
||||
/// Convert a value to a script value
|
||||
ScriptValueP to_script(int v);
|
||||
inline ScriptValueP to_script(long v) { return to_script((int) v); }
|
||||
ScriptValueP to_script(double v);
|
||||
ScriptValueP to_script(const String& v);
|
||||
ScriptValueP to_script(Color v);
|
||||
ScriptValueP to_script(wxDateTime v);
|
||||
inline ScriptValueP to_script(bool v) { return v ? script_true : script_false; }
|
||||
ScriptValueP to_script(int v);
|
||||
ScriptValueP to_script(double v);
|
||||
ScriptValueP to_script(const String& v);
|
||||
ScriptValueP to_script(Color v);
|
||||
ScriptValueP to_script(wxDateTime v);
|
||||
|
||||
inline ScriptValueP to_script(long v) {
|
||||
return to_script((int) v);
|
||||
}
|
||||
inline ScriptValueP to_script(bool v) {
|
||||
return v ? script_true : script_false;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline ScriptValueP to_script(const vector<T>* v) { return make_intrusive<ScriptCollection<vector<T>>>(v); }
|
||||
inline ScriptValueP to_script(const vector<T>* v) {
|
||||
return make_intrusive<ScriptCollection<vector<T>>>(v);
|
||||
}
|
||||
template <typename K, typename V>
|
||||
inline ScriptValueP to_script(const map<K,V>* v) { return make_intrusive<ScriptMap<map<K,V>>>(v); }
|
||||
inline ScriptValueP to_script(const map<K,V>* v) {
|
||||
return make_intrusive<ScriptMap<map<K,V>>>(v);
|
||||
}
|
||||
template <typename K, typename V>
|
||||
inline ScriptValueP to_script(const IndexMap<K,V>* v) { return make_intrusive<ScriptMap<IndexMap<K,V>>>(v); }
|
||||
inline ScriptValueP to_script(const IndexMap<K,V>* v) {
|
||||
return make_intrusive<ScriptMap<IndexMap<K,V>>>(v);
|
||||
}
|
||||
template <typename T>
|
||||
inline ScriptValueP to_script(const intrusive_ptr<T>& v) { return make_intrusive<ScriptObject<intrusive_ptr<T>>>(v); }
|
||||
inline ScriptValueP to_script(const intrusive_ptr<T>& v) {
|
||||
return make_intrusive<ScriptObject<intrusive_ptr<T>>>(v);
|
||||
}
|
||||
template <typename T>
|
||||
inline ScriptValueP to_script(const Defaultable<T>& v) { return to_script(v()); }
|
||||
inline ScriptValueP to_script(const Defaultable<T>& v) {
|
||||
return to_script(v());
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : Destructing
|
||||
|
||||
/// Convert a value from a script value to a normal value
|
||||
template <typename T> inline T from_script (const ScriptValueP& value) {
|
||||
template <typename T> inline T from_script(const ScriptValueP& value) {
|
||||
ScriptObject<T>* o = dynamic_cast<ScriptObject<T>*>(value.get());
|
||||
if (!o) {
|
||||
throw ScriptErrorConversion(value->typeName(), _TYPE_("object" ));
|
||||
}
|
||||
return o->getValue();
|
||||
}
|
||||
template <> inline ScriptValueP from_script<ScriptValueP>(const ScriptValueP& value) { return value; }
|
||||
template <> inline String from_script<String> (const ScriptValueP& value) { return *value; }
|
||||
template <> inline int from_script<int> (const ScriptValueP& value) { return *value; }
|
||||
template <> inline double from_script<double> (const ScriptValueP& value) { return *value; }
|
||||
template <> inline bool from_script<bool> (const ScriptValueP& value) { return *value; }
|
||||
template <> inline Color from_script<Color> (const ScriptValueP& value) { return *value; }
|
||||
template <> inline wxDateTime from_script<wxDateTime> (const ScriptValueP& value) { return *value; }
|
||||
template <> inline ScriptValueP from_script<ScriptValueP>(const ScriptValueP& value) { return value; }
|
||||
template <> inline String from_script<String> (const ScriptValueP& value) { return value->toString(); }
|
||||
template <> inline int from_script<int> (const ScriptValueP& value) { return value->toInt(); }
|
||||
template <> inline double from_script<double> (const ScriptValueP& value) { return value->toDouble(); }
|
||||
template <> inline bool from_script<bool> (const ScriptValueP& value) { return value->toBool(); }
|
||||
template <> inline Color from_script<Color> (const ScriptValueP& value) { return value->toColor(); }
|
||||
template <> inline wxDateTime from_script<wxDateTime> (const ScriptValueP& value) { return value->toDateTime(); }
|
||||
|
||||
|
||||
+150
-100
@@ -17,18 +17,45 @@
|
||||
// ----------------------------------------------------------------------------- : ScriptValue
|
||||
// Base cases
|
||||
|
||||
ScriptValue::operator String() const { throw ScriptErrorConversion(typeName(), _TYPE_("string" )); }
|
||||
ScriptValue::operator int() const { throw ScriptErrorConversion(typeName(), _TYPE_("integer" )); }
|
||||
ScriptValue::operator bool() const { throw ScriptErrorConversion(typeName(), _TYPE_("boolean" )); }
|
||||
ScriptValue::operator double() const { throw ScriptErrorConversion(typeName(), _TYPE_("double" )); }
|
||||
ScriptValue::operator Color() const { throw ScriptErrorConversion(typeName(), _TYPE_("color" )); }
|
||||
ScriptValue::operator wxDateTime() const { throw ScriptErrorConversion(typeName(), _TYPE_("date" )); }
|
||||
ScriptValueP ScriptValue::do_eval(Context&, bool) const { return delay_error(ScriptErrorConversion(typeName(), _TYPE_("function"))); }
|
||||
ScriptValueP ScriptValue::next(ScriptValueP* key_out) { throw InternalError(_("Can't convert from ")+typeName()+_(" to iterator")); }
|
||||
ScriptValueP ScriptValue::makeIterator(const ScriptValueP&) const { return delay_error(ScriptErrorConversion(typeName(), _TYPE_("collection"))); }
|
||||
int ScriptValue::itemCount() const { throw ScriptErrorConversion(typeName(), _TYPE_("collection")); }
|
||||
GeneratedImageP ScriptValue::toImage(const ScriptValueP&) const { throw ScriptErrorConversion(typeName(), _TYPE_("image" )); }
|
||||
String ScriptValue::toCode() const { return *this; }
|
||||
String ScriptValue::toString() const {
|
||||
throw ScriptErrorConversion(typeName(), _TYPE_("string"));
|
||||
}
|
||||
int ScriptValue::toInt() const {
|
||||
throw ScriptErrorConversion(typeName(), _TYPE_("integer"));
|
||||
}
|
||||
bool ScriptValue::toBool() const {
|
||||
throw ScriptErrorConversion(typeName(), _TYPE_("boolean"));
|
||||
}
|
||||
double ScriptValue::toDouble() const {
|
||||
throw ScriptErrorConversion(typeName(), _TYPE_("double"));
|
||||
}
|
||||
Color ScriptValue::toColor() const {
|
||||
throw ScriptErrorConversion(typeName(), _TYPE_("color"));
|
||||
}
|
||||
wxDateTime ScriptValue::toDateTime() const {
|
||||
throw ScriptErrorConversion(typeName(), _TYPE_("date"));
|
||||
}
|
||||
GeneratedImageP ScriptValue::toImage(const ScriptValueP&) const {
|
||||
throw ScriptErrorConversion(typeName(), _TYPE_("image" ));
|
||||
}
|
||||
String ScriptValue::toCode() const {
|
||||
return toString();
|
||||
}
|
||||
|
||||
ScriptValueP ScriptValue::eval(Context&, bool) const {
|
||||
return delay_error(ScriptErrorConversion(typeName(), _TYPE_("function")));
|
||||
}
|
||||
|
||||
ScriptValueP ScriptValue::next(ScriptValueP* key_out) {
|
||||
throw InternalError(_("Can't convert from ")+typeName()+_(" to iterator"));
|
||||
}
|
||||
ScriptValueP ScriptValue::makeIterator(const ScriptValueP&) const {
|
||||
return delay_error(ScriptErrorConversion(typeName(), _TYPE_("collection")));
|
||||
}
|
||||
int ScriptValue::itemCount() const {
|
||||
throw ScriptErrorConversion(typeName(), _TYPE_("collection"));
|
||||
}
|
||||
|
||||
CompareWhat ScriptValue::compareAs(String& compare_str, void const*& compare_ptr) const {
|
||||
compare_str = toCode();
|
||||
return COMPARE_AS_STRING;
|
||||
@@ -46,13 +73,19 @@ ScriptValueP ScriptValue::getIndex(int index) const {
|
||||
}
|
||||
|
||||
|
||||
ScriptValueP ScriptValue::simplifyClosure(ScriptClosure&) const { return ScriptValueP(); }
|
||||
ScriptValueP ScriptValue::simplifyClosure(ScriptClosure&) const {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ScriptValueP ScriptValue::dependencyMember(const String& name, const Dependency&) const { return dependency_dummy; }
|
||||
ScriptValueP ScriptValue::dependencyMember(const String& name, const Dependency&) const {
|
||||
return dependency_dummy;
|
||||
}
|
||||
ScriptValueP ScriptValue::dependencyName(const ScriptValue& container, const Dependency& dep) const {
|
||||
return container.dependencyMember(toString(),dep);
|
||||
}
|
||||
ScriptValueP ScriptValue::dependencies(Context&, const Dependency&) const { return dependency_dummy; }
|
||||
ScriptValueP ScriptValue::dependencies(Context&, const Dependency&) const {
|
||||
return dependency_dummy;
|
||||
}
|
||||
void ScriptValue::dependencyThis(const Dependency& dep) {}
|
||||
|
||||
bool approx_equal(double a, double b) {
|
||||
@@ -64,12 +97,12 @@ bool equal(const ScriptValueP& a, const ScriptValueP& b) {
|
||||
if (a == b) return true;
|
||||
ScriptType at = a->type(), bt = b->type();
|
||||
if (at == bt && at == SCRIPT_INT) {
|
||||
return (int)*a == (int)*b;
|
||||
return a->toInt() == b->toInt();
|
||||
} else if (at == bt && at == SCRIPT_BOOL) {
|
||||
return (bool)*a == (bool)*b;
|
||||
return a->toBool() == b->toBool();
|
||||
} else if ((at == SCRIPT_INT || at == SCRIPT_DOUBLE) &&
|
||||
(bt == SCRIPT_INT || bt == SCRIPT_DOUBLE)) {
|
||||
return approx_equal( (double)*a, (double)*b);
|
||||
return approx_equal(a->toDouble(), b->toDouble());
|
||||
} else if (at == SCRIPT_COLLECTION && bt == SCRIPT_COLLECTION) {
|
||||
// compare each element
|
||||
if (a->itemCount() != b->itemCount()) return false;
|
||||
@@ -99,22 +132,42 @@ bool equal(const ScriptValueP& a, const ScriptValueP& b) {
|
||||
|
||||
// ----------------------------------------------------------------------------- : Errors
|
||||
|
||||
ScriptType ScriptDelayedError::type() const { return SCRIPT_ERROR; }
|
||||
/// A delayed error message.
|
||||
/** Only when trying to use the object will the error be thrown.
|
||||
* This can be 'caught' by the "or else" construct
|
||||
*/
|
||||
class ScriptDelayedError : public ScriptValue {
|
||||
public:
|
||||
inline ScriptDelayedError(const ScriptError& error) : error(error) {}
|
||||
|
||||
String ScriptDelayedError::typeName() const { throw error; }
|
||||
ScriptDelayedError::operator String() const { throw error; }
|
||||
ScriptDelayedError::operator double() const { throw error; }
|
||||
ScriptDelayedError::operator int() const { throw error; }
|
||||
ScriptDelayedError::operator bool() const { throw error; }
|
||||
ScriptDelayedError::operator Color() const { throw error; }
|
||||
int ScriptDelayedError::itemCount() const { throw error; }
|
||||
CompareWhat ScriptDelayedError::compareAs(String&, void const*&) const { throw error; }
|
||||
ScriptValueP ScriptDelayedError::getMember(const String&) const { return make_intrusive<ScriptDelayedError>(error); }
|
||||
ScriptValueP ScriptDelayedError::dependencyMember(const String&, const Dependency&) const { return make_intrusive<ScriptDelayedError>(error); }
|
||||
ScriptValueP ScriptDelayedError::do_eval(Context&, bool) const { return make_intrusive<ScriptDelayedError>(error); }
|
||||
ScriptValueP ScriptDelayedError::dependencies(Context&, const Dependency&) const { return make_intrusive<ScriptDelayedError>(error); }
|
||||
ScriptValueP ScriptDelayedError::makeIterator(const ScriptValueP& thisP) const { return thisP ? thisP : make_intrusive<ScriptDelayedError>(error); }
|
||||
ScriptType type() const override { return SCRIPT_ERROR; }
|
||||
|
||||
// all of these throw
|
||||
String typeName() const override { throw error; }
|
||||
String toString() const override { throw error; }
|
||||
double toDouble() const override { throw error; }
|
||||
int toInt() const override { throw error; }
|
||||
bool toBool() const override { throw error; }
|
||||
Color toColor() const override { throw error; }
|
||||
wxDateTime toDateTime() const override { throw error; }
|
||||
GeneratedImageP toImage(const ScriptValueP& thisP) const override { throw error; }
|
||||
int itemCount() const override { throw error; }
|
||||
CompareWhat compareAs(String&, void const*&) const override { throw error; }
|
||||
|
||||
// these can propagate the error
|
||||
ScriptValueP getMember(const String& name) const override { return delay_error(error); }
|
||||
ScriptValueP dependencyMember(const String& name, const Dependency&) const override { return delay_error(error); }
|
||||
ScriptValueP dependencies(Context&, const Dependency&) const override { return delay_error(error); }
|
||||
ScriptValueP makeIterator(const ScriptValueP&) const override { return delay_error(error); }
|
||||
ScriptValueP eval(Context&, bool openScope) const override { return delay_error(error); }
|
||||
|
||||
private:
|
||||
ScriptError error; // the error message
|
||||
};
|
||||
|
||||
ScriptValueP delay_error(const ScriptError& error) {
|
||||
return make_intrusive<ScriptDelayedError>(error);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : Iterators
|
||||
|
||||
@@ -125,11 +178,12 @@ ScriptValueP ScriptIterator::makeIterator(const ScriptValueP& thisP) const { ret
|
||||
|
||||
// Iterator over a range of integers
|
||||
class ScriptRangeIterator : public ScriptIterator {
|
||||
public:
|
||||
public:
|
||||
// Construct a range iterator with the given bounds (inclusive)
|
||||
ScriptRangeIterator(int start, int end)
|
||||
: pos(start), start(start), end(end) {}
|
||||
virtual ScriptValueP next(ScriptValueP* key_out) {
|
||||
: pos(start), start(start), end(end)
|
||||
{}
|
||||
ScriptValueP next(ScriptValueP* key_out) override {
|
||||
if (pos <= end) {
|
||||
if (key_out) *key_out = to_script(pos-start);
|
||||
return to_script(pos++);
|
||||
@@ -137,7 +191,7 @@ class ScriptRangeIterator : public ScriptIterator {
|
||||
return ScriptValueP();
|
||||
}
|
||||
}
|
||||
private:
|
||||
private:
|
||||
int pos, start, end;
|
||||
};
|
||||
|
||||
@@ -151,20 +205,20 @@ ScriptValueP rangeIterator(int start, int end) {
|
||||
|
||||
// Integer values
|
||||
class ScriptInt : public ScriptValue {
|
||||
public:
|
||||
public:
|
||||
ScriptInt(int v) : value(v) {}
|
||||
virtual ScriptType type() const { return SCRIPT_INT; }
|
||||
virtual String typeName() const { return _TYPE_("integer"); }
|
||||
virtual operator String() const { return String() << value; }
|
||||
virtual operator double() const { return value; }
|
||||
virtual operator int() const { return value; }
|
||||
protected:
|
||||
ScriptType type() const override { return SCRIPT_INT; }
|
||||
String typeName() const override { return _TYPE_("integer"); }
|
||||
String toString() const override { return String() << value; }
|
||||
double toDouble() const override { return value; }
|
||||
int toInt() const override { return value; }
|
||||
protected:
|
||||
#ifdef USE_POOL_ALLOCATOR
|
||||
virtual void destroy() {
|
||||
boost::singleton_pool<ScriptValue, sizeof(ScriptInt)>::free(this);
|
||||
}
|
||||
#endif
|
||||
private:
|
||||
private:
|
||||
int value;
|
||||
};
|
||||
|
||||
@@ -196,37 +250,35 @@ ScriptValueP to_script(int v) {
|
||||
|
||||
// Boolean values
|
||||
class ScriptBool : public ScriptValue {
|
||||
public:
|
||||
public:
|
||||
ScriptBool(bool v) : value(v) {}
|
||||
virtual ScriptType type() const { return SCRIPT_BOOL; }
|
||||
virtual String typeName() const { return _TYPE_("boolean"); }
|
||||
virtual operator String() const { return value ? _("true") : _("false"); }
|
||||
ScriptType type() const override { return SCRIPT_BOOL; }
|
||||
String typeName() const override { return _TYPE_("boolean"); }
|
||||
String toString() const override { return value ? _("true") : _("false"); }
|
||||
bool toBool() const override { return value; }
|
||||
// bools don't autoconvert to int
|
||||
virtual operator bool() const { return value; }
|
||||
private:
|
||||
private:
|
||||
bool value;
|
||||
};
|
||||
|
||||
// use integers to represent true/false
|
||||
/* NOTE: previous versions used ScriptInts as booleans, this gives problems
|
||||
* when we use a pool allocator for them, because the pool is destroyed before these globals.
|
||||
*/
|
||||
ScriptValueP script_true (new ScriptBool(true));
|
||||
ScriptValueP script_false(new ScriptBool(false));
|
||||
|
||||
|
||||
// ----------------------------------------------------------------------------- : Doubles
|
||||
|
||||
// Double values
|
||||
class ScriptDouble : public ScriptValue {
|
||||
public:
|
||||
public:
|
||||
ScriptDouble(double v) : value(v) {}
|
||||
virtual ScriptType type() const { return SCRIPT_DOUBLE; }
|
||||
virtual String typeName() const { return _TYPE_("double"); }
|
||||
virtual operator String() const { return String() << value; }
|
||||
virtual operator double() const { return value; }
|
||||
virtual operator int() const { return (int)value; }
|
||||
private:
|
||||
ScriptType type() const override { return SCRIPT_DOUBLE; }
|
||||
String typeName() const override { return _TYPE_("double"); }
|
||||
String toString() const override { return String() << value; }
|
||||
double toDouble() const override { return value; }
|
||||
int toInt() const override { return (int)value; }
|
||||
private:
|
||||
double value;
|
||||
};
|
||||
|
||||
@@ -238,12 +290,12 @@ ScriptValueP to_script(double v) {
|
||||
|
||||
// String values
|
||||
class ScriptString : public ScriptValue {
|
||||
public:
|
||||
public:
|
||||
ScriptString(const String& v) : value(v) {}
|
||||
virtual ScriptType type() const { return SCRIPT_STRING; }
|
||||
virtual String typeName() const { return _TYPE_("string") + _(" (\"") + (value.size() < 30 ? value : value.substr(0,30) + _("...")) + _("\")"); }
|
||||
virtual operator String() const { return value; }
|
||||
virtual operator double() const {
|
||||
ScriptType type() const override { return SCRIPT_STRING; }
|
||||
String typeName() const override { return _TYPE_("string") + _(" (\"") + (value.size() < 30 ? value : value.substr(0,30) + _("...")) + _("\")"); }
|
||||
String toString() const override { return value; }
|
||||
double toDouble() const override {
|
||||
double d;
|
||||
if (value.ToDouble(&d)) {
|
||||
return d;
|
||||
@@ -251,7 +303,7 @@ class ScriptString : public ScriptValue {
|
||||
throw ScriptErrorConversion(value, typeName(), _TYPE_("double"));
|
||||
}
|
||||
}
|
||||
virtual operator int() const {
|
||||
int toInt() const override {
|
||||
long l;
|
||||
if (value.ToLong(&l)) {
|
||||
return l;
|
||||
@@ -259,7 +311,7 @@ class ScriptString : public ScriptValue {
|
||||
throw ScriptErrorConversion(value, typeName(), _TYPE_("integer"));
|
||||
}
|
||||
}
|
||||
virtual operator bool() const {
|
||||
bool toBool() const override {
|
||||
if (value == _("yes") || value == _("true")) {
|
||||
return true;
|
||||
} else if (value == _("no") || value == _("false") || value.empty()) {
|
||||
@@ -268,14 +320,14 @@ class ScriptString : public ScriptValue {
|
||||
throw ScriptErrorConversion(value, typeName(), _TYPE_("boolean"));
|
||||
}
|
||||
}
|
||||
virtual operator Color() const {
|
||||
Color toColor() const override {
|
||||
Color c = parse_color(value);
|
||||
if (!c.Ok()) {
|
||||
throw ScriptErrorConversion(value, typeName(), _TYPE_("color"));
|
||||
}
|
||||
return c;
|
||||
}
|
||||
virtual operator wxDateTime() const {
|
||||
wxDateTime toDateTime() const override {
|
||||
wxDateTime date;
|
||||
String::const_iterator end;
|
||||
if (!date.ParseDateTime(value,&end) || end != value.end()) {
|
||||
@@ -283,15 +335,15 @@ class ScriptString : public ScriptValue {
|
||||
}
|
||||
return date;
|
||||
}
|
||||
virtual GeneratedImageP toImage(const ScriptValueP&) const {
|
||||
GeneratedImageP toImage(const ScriptValueP&) const override {
|
||||
if (value.empty()) {
|
||||
return make_intrusive<BlankImage>();
|
||||
} else {
|
||||
return make_intrusive<PackagedImage>(value);
|
||||
}
|
||||
}
|
||||
virtual int itemCount() const { return (int)value.size(); }
|
||||
virtual ScriptValueP getMember(const String& name) const {
|
||||
int itemCount() const override { return (int)value.size(); }
|
||||
ScriptValueP getMember(const String& name) const override {
|
||||
// get member returns characters
|
||||
long index;
|
||||
if (name.ToLong(&index) && index >= 0 && (size_t)index < value.size()) {
|
||||
@@ -300,7 +352,7 @@ class ScriptString : public ScriptValue {
|
||||
return delay_error(_ERROR_2_("has no member value", value, name));
|
||||
}
|
||||
}
|
||||
private:
|
||||
private:
|
||||
String value;
|
||||
};
|
||||
|
||||
@@ -315,11 +367,11 @@ ScriptValueP to_script(const String& v) {
|
||||
class ScriptColor : public ScriptValue {
|
||||
public:
|
||||
ScriptColor(const Color& v) : value(v) {}
|
||||
virtual ScriptType type() const { return SCRIPT_COLOR; }
|
||||
virtual String typeName() const { return _TYPE_("color"); }
|
||||
virtual operator Color() const { return value; }
|
||||
ScriptType type() const override { return SCRIPT_COLOR; }
|
||||
String typeName() const override { return _TYPE_("color"); }
|
||||
Color toColor() const override { return value; }
|
||||
// colors don't auto convert to int, use to_int to force
|
||||
virtual operator String() const {
|
||||
String toString() const override {
|
||||
return format_color(value);
|
||||
}
|
||||
private:
|
||||
@@ -335,15 +387,15 @@ ScriptValueP to_script(Color v) {
|
||||
|
||||
// wxDateTime values
|
||||
class ScriptDateTime : public ScriptValue {
|
||||
public:
|
||||
public:
|
||||
ScriptDateTime(const wxDateTime& v) : value(v) {}
|
||||
virtual ScriptType type() const { return SCRIPT_DATETIME; }
|
||||
virtual String typeName() const { return _TYPE_("date"); }
|
||||
virtual operator wxDateTime() const { return value; }
|
||||
virtual operator String() const {
|
||||
ScriptType type() const override { return SCRIPT_DATETIME; }
|
||||
String typeName() const override { return _TYPE_("date"); }
|
||||
wxDateTime toDateTime() const override { return value; }
|
||||
String toString() const override {
|
||||
return value.Format(_("%Y-%m-%d %H:%M:%S"));
|
||||
}
|
||||
private:
|
||||
private:
|
||||
wxDateTime value;
|
||||
};
|
||||
|
||||
@@ -359,27 +411,25 @@ class ScriptNil : public ScriptValue {
|
||||
public:
|
||||
ScriptType type() const override { return SCRIPT_NIL; }
|
||||
String typeName() const override { return _TYPE_("nil"); }
|
||||
operator String() const override { return String(); }
|
||||
operator double() const override { return 0.0; }
|
||||
operator int() const override { return 0; }
|
||||
operator bool() const override { return false; }
|
||||
operator Color() const override { return wxTransparentColour; }
|
||||
String toString() const override { return String(); }
|
||||
double toDouble() const override { return 0.0; }
|
||||
int toInt() const override { return 0; }
|
||||
bool toBool() const override { return false; }
|
||||
Color toColor() const override { return wxTransparentColour; }
|
||||
GeneratedImageP toImage(const ScriptValueP&) const {
|
||||
return make_intrusive<BlankImage>();
|
||||
}
|
||||
String toCode() const override {
|
||||
return "nil";
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual ScriptValueP do_eval(Context& ctx, bool) const {
|
||||
ScriptValueP eval(Context& ctx, bool) const override {
|
||||
// nil(input) == input
|
||||
return ctx.getVariable(SCRIPT_VAR_input);
|
||||
}
|
||||
};
|
||||
|
||||
/// The preallocated nil value
|
||||
ScriptValueP script_nil(new ScriptNil);
|
||||
ScriptValueP script_nil = make_intrusive<ScriptNil>();
|
||||
|
||||
// ----------------------------------------------------------------------------- : Collection base
|
||||
|
||||
@@ -401,10 +451,10 @@ String ScriptCollectionBase::toCode() const {
|
||||
|
||||
// Iterator over a custom collection
|
||||
class ScriptCustomCollectionIterator : public ScriptIterator {
|
||||
public:
|
||||
public:
|
||||
ScriptCustomCollectionIterator(ScriptCustomCollection const* col, ScriptValueP const& col_owned)
|
||||
: col(col), col_owned(col_owned), pos(0), it(col->key_value.begin()) {}
|
||||
virtual ScriptValueP next(ScriptValueP* key_out) {
|
||||
ScriptValueP next(ScriptValueP* key_out) override {
|
||||
if (pos < col->value.size()) {
|
||||
if (key_out) *key_out = to_script((int)pos);
|
||||
return col->value.at(pos++);
|
||||
@@ -445,10 +495,10 @@ ScriptValueP ScriptCustomCollection::makeIterator(const ScriptValueP& thisP) con
|
||||
|
||||
// Iterator over a concatenated collection
|
||||
class ScriptConcatCollectionIterator : public ScriptIterator {
|
||||
public:
|
||||
public:
|
||||
ScriptConcatCollectionIterator(const ScriptValueP& itA, const ScriptValueP& itB)
|
||||
: itA(itA), itB(itB) {}
|
||||
virtual ScriptValueP next(ScriptValueP* key_out) {
|
||||
ScriptValueP next(ScriptValueP* key_out) override {
|
||||
if (itA) {
|
||||
ScriptValueP v = itA->next(key_out);
|
||||
if (v) return v;
|
||||
@@ -457,7 +507,7 @@ class ScriptConcatCollectionIterator : public ScriptIterator {
|
||||
// TODO: somehow fix up the keys
|
||||
return itB->next(key_out);
|
||||
}
|
||||
private:
|
||||
private:
|
||||
ScriptValueP itA, itB;
|
||||
};
|
||||
|
||||
@@ -475,7 +525,7 @@ ScriptValueP ScriptConcatCollection::getMember(const String& name) const {
|
||||
}
|
||||
ScriptValueP ScriptConcatCollection::getIndex(int index) const {
|
||||
int itemsInA = a->itemCount();
|
||||
if (index < itemsInA) {
|
||||
if (index < itemsInA) {
|
||||
return a->getIndex(index);
|
||||
} else {
|
||||
return b->getIndex(index - itemsInA);
|
||||
@@ -508,7 +558,7 @@ ScriptValueP ScriptClosure::simplify() {
|
||||
return fun->simplifyClosure(*this);
|
||||
}
|
||||
|
||||
ScriptValueP ScriptClosure::do_eval(Context& ctx, bool openScope) const {
|
||||
ScriptValueP ScriptClosure::eval(Context& ctx, bool openScope) const {
|
||||
unique_ptr<LocalScope> scope = openScope ? make_unique<LocalScope>(ctx) : nullptr;
|
||||
applyBindings(ctx);
|
||||
return fun->eval(ctx, openScope);
|
||||
@@ -529,7 +579,7 @@ void ScriptClosure::applyBindings(Context& ctx) const {
|
||||
|
||||
|
||||
ScriptType ScriptRule::type() const { return SCRIPT_FUNCTION; }
|
||||
String ScriptRule::typeName() const { return fun->typeName() + _(" rule"); }
|
||||
ScriptValueP ScriptRule::do_eval(Context& ctx, bool openScope) const {
|
||||
String ScriptRule::typeName() const { return fun->typeName() + _("_rule"); }
|
||||
ScriptValueP ScriptRule::eval(Context& ctx, bool openScope) const {
|
||||
return ctx.makeClosure(fun);
|
||||
}
|
||||
|
||||
+12
-30
@@ -46,7 +46,7 @@ enum CompareWhat
|
||||
/// A value that can be handled by the scripting engine.
|
||||
/// Actual values are derived types
|
||||
class ScriptValue : public IntrusivePtrBaseWithDelete {
|
||||
public:
|
||||
public:
|
||||
virtual ~ScriptValue() {}
|
||||
|
||||
/// Information on the type of this value
|
||||
@@ -58,31 +58,23 @@ class ScriptValue : public IntrusivePtrBaseWithDelete {
|
||||
virtual CompareWhat compareAs(String& compare_str, void const*& compare_ptr) const;
|
||||
|
||||
/// Convert this value to a string
|
||||
virtual operator String() const;
|
||||
virtual String toString() const;
|
||||
/// Convert this value to a double
|
||||
virtual operator double() const;
|
||||
virtual double toDouble() const;
|
||||
/// Convert this value to an integer
|
||||
virtual operator int() const;
|
||||
virtual int toInt() const;
|
||||
/// Convert this value to a boolean
|
||||
virtual operator bool() const;
|
||||
virtual bool toBool() const;
|
||||
/// Convert this value to a color
|
||||
virtual operator Color() const;
|
||||
virtual Color toColor() const;
|
||||
/// Convert this value to a wxDateTime
|
||||
virtual operator wxDateTime() const;
|
||||
virtual wxDateTime toDateTime() const;
|
||||
/// Convert this value to an image
|
||||
virtual GeneratedImageP toImage(const ScriptValueP& thisP) const;
|
||||
|
||||
/// Script code to generate this value
|
||||
virtual String toCode() const;
|
||||
|
||||
/// Explicit overload to convert to a string
|
||||
/** This is sometimes necessary, because wxString has an int constructor,
|
||||
* which confuses gcc. */
|
||||
inline String toString() const { return *this; }
|
||||
/// Explicit overload to convert to a wxDateTime
|
||||
/** Overload resolution is sometimes confused by other conversions */
|
||||
inline wxDateTime toDateTime() const { return *this; }
|
||||
/// Convert this value to an image
|
||||
virtual GeneratedImageP toImage(const ScriptValueP& thisP) const;
|
||||
|
||||
/// Get a member variable from this value
|
||||
virtual ScriptValueP getMember(const String& name) const;
|
||||
|
||||
@@ -96,18 +88,16 @@ class ScriptValue : public IntrusivePtrBaseWithDelete {
|
||||
virtual ScriptValueP dependencyName(const ScriptValue& container, const Dependency&) const;
|
||||
|
||||
/// Evaluate this value (if it is a function)
|
||||
ScriptValueP eval(Context& ctx, bool openScope = true) const {
|
||||
return do_eval(ctx, openScope);
|
||||
}
|
||||
virtual ScriptValueP eval(Context& ctx, bool openScope = true) const;
|
||||
/// Mark the scripts that this function depends on
|
||||
/** Return value is an abstract version of the return value of eval */
|
||||
virtual ScriptValueP dependencies(Context&, const Dependency&) const;
|
||||
/// Simplify/optimize a default argument closure of this function.
|
||||
/** Should return a simplification of the closure or null to keep the closure.
|
||||
/** Should return a simplification of the closure or nullptr to keep the closure.
|
||||
* Alternatively, the closure may be modified in place.
|
||||
*/
|
||||
virtual ScriptValueP simplifyClosure(ScriptClosure&) const;
|
||||
|
||||
|
||||
/// Return an iterator for the current collection, an iterator is a value that has next()
|
||||
/** thisP is a shared_ptr for this collection, needed for the iterator to take ownership of it.
|
||||
* It can be null if the iterator always lives shorter than the collection.
|
||||
@@ -120,16 +110,8 @@ class ScriptValue : public IntrusivePtrBaseWithDelete {
|
||||
virtual int itemCount() const;
|
||||
/// Get a member at the given index
|
||||
virtual ScriptValueP getIndex(int index) const;
|
||||
|
||||
protected:
|
||||
virtual ScriptValueP do_eval(Context& ctx, bool openScope) const;
|
||||
};
|
||||
|
||||
extern ScriptValueP script_nil; ///< The preallocated nil value
|
||||
extern ScriptValueP script_true; ///< The preallocated true value
|
||||
extern ScriptValueP script_false; ///< The preallocated false value
|
||||
extern ScriptValueP dependency_dummy; ///< Dummy value used during dependency analysis
|
||||
|
||||
/// compare script values for equallity
|
||||
bool equal(const ScriptValueP& a, const ScriptValueP& b);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user