mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-10 13:06:59 -04:00
Script support for AColors. All colors in script related code are now AColor.
git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@852 0fc631ac-6414-0410-93d0-97cfa31319b6
This commit is contained in:
@@ -29,6 +29,9 @@ void instrBinary (BinaryInstructionType i, ScriptValueP& a, const ScriptValueP&
|
||||
// Perform a ternary simple instruction, store the result in a (not in *a)
|
||||
void instrTernary(TernaryInstructionType i, ScriptValueP& a, const ScriptValueP& b, const ScriptValueP& c);
|
||||
|
||||
// Perform a quaternary simple instruction, store the result in a (not in *a)
|
||||
void instrQuaternary(QuaternaryInstructionType i, ScriptValueP& a, const ScriptValueP& b, const ScriptValueP& c, const ScriptValueP& d);
|
||||
|
||||
|
||||
ScriptValueP Context::eval(const Script& script, bool useScope) {
|
||||
size_t stack_size = stack.size();
|
||||
@@ -172,6 +175,16 @@ ScriptValueP Context::eval(const Script& script, bool useScope) {
|
||||
ScriptValueP b = stack.back(); stack.pop_back();
|
||||
ScriptValueP& a = stack.back();
|
||||
instrTernary(i.instr3, a, b, c);
|
||||
// cout << "\t\t-> " << (String)*stack.back() << endl;
|
||||
break;
|
||||
}
|
||||
// Simple instruction: quaternary
|
||||
case I_QUATERNARY: {
|
||||
ScriptValueP d = stack.back(); stack.pop_back();
|
||||
ScriptValueP c = stack.back(); stack.pop_back();
|
||||
ScriptValueP b = stack.back(); stack.pop_back();
|
||||
ScriptValueP& a = stack.back();
|
||||
instrQuaternary(i.instr4, a, b, c, d);
|
||||
// cout << "\t\t-> " << (String)*stack.back() << endl;
|
||||
break;
|
||||
}
|
||||
@@ -370,6 +383,16 @@ void instrTernary(TernaryInstructionType i, ScriptValueP& a, const ScriptValueP&
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : Simple instructions : quaternary
|
||||
|
||||
void instrQuaternary(QuaternaryInstructionType i, ScriptValueP& a, const ScriptValueP& b, const ScriptValueP& c, const ScriptValueP& d) {
|
||||
switch (i) {
|
||||
case I_RGBA:
|
||||
a = to_script(AColor((int)*a, (int)*b, (int)*c, (int)*d));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : Simple instructions : object
|
||||
|
||||
void Context::makeObject(size_t n) {
|
||||
|
||||
@@ -319,6 +319,15 @@ ScriptValueP Context::dependencies(const Dependency& dep, const Script& script)
|
||||
a = dependency_dummy;
|
||||
break;
|
||||
}
|
||||
// Simple instruction: quaternary
|
||||
case I_QUATERNARY: {
|
||||
ScriptValueP d = stack.back(); stack.pop_back();
|
||||
ScriptValueP c = stack.back(); stack.pop_back();
|
||||
ScriptValueP b = stack.back(); stack.pop_back();
|
||||
ScriptValueP& a = stack.back();
|
||||
a = dependency_dummy;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (...) {
|
||||
|
||||
@@ -511,6 +511,18 @@ void parseExpr(TokenIterator& input, Script& script, Precedence minPrec) {
|
||||
parseOper(input, script, PREC_ALL); // b
|
||||
expectToken(input, _(")"));
|
||||
script.addInstruction(I_TERNARY, I_RGB);
|
||||
} else if (token == _("rgba")) {
|
||||
// rgba(r, g, b, a)
|
||||
expectToken(input, _("("));
|
||||
parseOper(input, script, PREC_ALL); // r
|
||||
expectToken(input, _(","));
|
||||
parseOper(input, script, PREC_ALL); // g
|
||||
expectToken(input, _(","));
|
||||
parseOper(input, script, PREC_ALL); // b
|
||||
expectToken(input, _(","));
|
||||
parseOper(input, script, PREC_ALL); // a
|
||||
expectToken(input, _(")"));
|
||||
script.addInstruction(I_QUATERNARY, I_RGBA);
|
||||
} else if (token == _("min") || token == _("max")) {
|
||||
// min(x,y,z,...)
|
||||
unsigned int op = token == _("min") ? I_MIN : I_MAX;
|
||||
|
||||
@@ -187,6 +187,11 @@ String Script::dumpInstr(unsigned int pos, Instruction i) const {
|
||||
case I_RGB: ret += _("rgb"); break;
|
||||
}
|
||||
break;
|
||||
case I_QUATERNARY: ret += _("quaternary\t");
|
||||
switch (i.instr3) {
|
||||
case I_RGBA: ret += _("rgba"); break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
// arg
|
||||
switch (i.instr) {
|
||||
@@ -227,7 +232,9 @@ const Instruction* Script::backtraceSkip(const Instruction* instr, int to_skip)
|
||||
case I_BINARY:
|
||||
to_skip += 1; break; // nett stack effect 1-2 == -1
|
||||
case I_TERNARY:
|
||||
to_skip += 2; break; // nett stack effect 1-3 == -1
|
||||
to_skip += 2; break; // nett stack effect 1-3 == -2
|
||||
case I_QUATERNARY:
|
||||
to_skip += 3; break; // nett stack effect 1-4 == -3
|
||||
case I_CALL:
|
||||
to_skip += instr->data; // arguments of call
|
||||
break;
|
||||
|
||||
+12
-5
@@ -41,6 +41,7 @@ enum InstructionType
|
||||
, I_UNARY = -4 ///< pop 1 value, apply a function, push the result
|
||||
, I_BINARY = -3 ///< pop 2 values, apply a function, push the result
|
||||
, I_TERNARY = -2 ///< pop 3 values, apply a function, push the result
|
||||
, I_QUATERNARY = -1 ///< pop 4 values, apply a function, push the result
|
||||
};
|
||||
|
||||
/// Types of unary instructions (taking one argument from the stack)
|
||||
@@ -82,17 +83,23 @@ enum TernaryInstructionType
|
||||
{ I_RGB ///< pop r,g,b, push a color value
|
||||
};
|
||||
|
||||
/// Types of quaternary instructions (taking four arguments from the stack)
|
||||
enum QuaternaryInstructionType
|
||||
{ I_RGBA ///< pop r,g,b,a, push an acolor value
|
||||
};
|
||||
|
||||
/// An instruction in a script, consists of the opcode and data
|
||||
/** If the opcode is one of I_UNARY,I_BINARY,I_TERNARY,
|
||||
/** If the opcode is one of I_UNARY,I_BINARY,I_TERNARY,I_QUATERNARY,
|
||||
* Then the instr? member gives the actual instruction to perform
|
||||
*/
|
||||
struct Instruction {
|
||||
InstructionType instr : 4;
|
||||
union {
|
||||
unsigned int data : 28;
|
||||
UnaryInstructionType instr1 : 28;
|
||||
BinaryInstructionType instr2 : 28;
|
||||
TernaryInstructionType instr3 : 28;
|
||||
unsigned int data : 28;
|
||||
UnaryInstructionType instr1 : 28;
|
||||
BinaryInstructionType instr2 : 28;
|
||||
TernaryInstructionType instr3 : 28;
|
||||
QuaternaryInstructionType instr4 : 28;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <script/parser.hpp>
|
||||
#include <script/script.hpp>
|
||||
#include <script/value.hpp>
|
||||
#include <gfx/color.hpp>
|
||||
|
||||
Alignment from_string(const String&);
|
||||
|
||||
@@ -23,9 +24,11 @@ void store(const ScriptValueP& val, String& var) { var = val->toStr
|
||||
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 = static_cast<int>(*val); }
|
||||
void store(const ScriptValueP& val, Color& var) { var = *val; }
|
||||
void store(const ScriptValueP& val, Color& var) { var = (AColor)*val; }
|
||||
void store(const ScriptValueP& val, AColor& 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, Defaultable<Color>& var) { var.assign((AColor)*val); }
|
||||
void store(const ScriptValueP& val, Defaultable<AColor>& var) { var.assign(*val); }
|
||||
void store(const ScriptValueP& val, Alignment& var) { var = from_string(val->toString()); }
|
||||
|
||||
// ----------------------------------------------------------------------------- : OptionalScript
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <script/parser.hpp>
|
||||
#include <script/to_value.hpp>
|
||||
|
||||
class AColor;
|
||||
DECLARE_POINTER_TYPE(Script);
|
||||
|
||||
// ----------------------------------------------------------------------------- : Store
|
||||
@@ -28,6 +29,7 @@ void store(const ScriptValueP& val, int& var);
|
||||
void store(const ScriptValueP& val, double& var);
|
||||
void store(const ScriptValueP& val, bool& var);
|
||||
void store(const ScriptValueP& val, Color& var);
|
||||
void store(const ScriptValueP& val, AColor& var);
|
||||
void store(const ScriptValueP& val, Defaultable<String>& var);
|
||||
void store(const ScriptValueP& val, Defaultable<Color>& var);
|
||||
void store(const ScriptValueP& val, Alignment& var);
|
||||
|
||||
@@ -56,7 +56,7 @@ class ScriptDelayedError : public ScriptValue {
|
||||
virtual operator String() const;
|
||||
virtual operator double() const;
|
||||
virtual operator int() const;
|
||||
virtual operator Color() const;
|
||||
virtual operator AColor() const;
|
||||
virtual int itemCount() const;
|
||||
virtual const void* comparePointer() const;
|
||||
// these can propagate the error
|
||||
@@ -207,7 +207,7 @@ class ScriptObject : public ScriptValue {
|
||||
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 Color() const { ScriptValueP d = getDefault(); return d ? *d : ScriptValue::operator Color(); }
|
||||
virtual operator AColor() const { ScriptValueP d = getDefault(); return d ? *d : ScriptValue::operator AColor(); }
|
||||
virtual ScriptValueP getMember(const String& name) const {
|
||||
GetMember gm(name);
|
||||
gm.handle(*value);
|
||||
@@ -254,7 +254,8 @@ class ScriptObject : public ScriptValue {
|
||||
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(const Color& v);
|
||||
ScriptValueP to_script(Color v);
|
||||
ScriptValueP to_script(AColor 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 new_intrusive1<ScriptCollection<vector<T> > >(v); }
|
||||
@@ -282,7 +283,8 @@ template <> inline String from_script<String> (const ScriptValueP& va
|
||||
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 Color from_script<Color> (const ScriptValueP& value) { return (AColor)*value; }
|
||||
template <> inline AColor from_script<AColor> (const ScriptValueP& value) { return *value; }
|
||||
|
||||
// ----------------------------------------------------------------------------- : EOF
|
||||
#endif
|
||||
|
||||
+18
-21
@@ -18,7 +18,7 @@
|
||||
ScriptValue::operator String() const { throw ScriptError(_ERROR_2_("can't convert", typeName(), _TYPE_("string" ))); }
|
||||
ScriptValue::operator int() const { throw ScriptError(_ERROR_2_("can't convert", typeName(), _TYPE_("integer" ))); }
|
||||
ScriptValue::operator double() const { throw ScriptError(_ERROR_2_("can't convert", typeName(), _TYPE_("double" ))); }
|
||||
ScriptValue::operator Color() const { throw ScriptError(_ERROR_2_("can't convert", typeName(), _TYPE_("color" ))); }
|
||||
ScriptValue::operator AColor() const { throw ScriptError(_ERROR_2_("can't convert", typeName(), _TYPE_("color" ))); }
|
||||
ScriptValueP ScriptValue::eval(Context&) const { return delayError(_ERROR_2_("can't convert", typeName(), _TYPE_("function"))); }
|
||||
ScriptValueP ScriptValue::getMember(const String& name) const { return delayError(_ERROR_2_("has no member", typeName(), name)); }
|
||||
ScriptValueP ScriptValue::next() { throw InternalError(_("Can't convert from ")+typeName()+_(" to iterator")); }
|
||||
@@ -38,7 +38,7 @@ 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 Color() const { throw error; }
|
||||
ScriptDelayedError::operator AColor() const { throw error; }
|
||||
int ScriptDelayedError::itemCount() const { throw error; }
|
||||
const void* ScriptDelayedError::comparePointer() const { throw error; }
|
||||
ScriptValueP ScriptDelayedError::getMember(const String&) const { return new_intrusive1<ScriptDelayedError>(error); }
|
||||
@@ -191,18 +191,12 @@ class ScriptString : public ScriptValue {
|
||||
throw ScriptError(_ERROR_3_("can't convert value", value, typeName(), _TYPE_("integer")));
|
||||
}
|
||||
}
|
||||
virtual operator Color() const {
|
||||
UInt r,g,b;
|
||||
if (wxSscanf(value.c_str(),_("rgb(%u,%u,%u)"),&r,&g,&b)) {
|
||||
return Color(r, g, b);
|
||||
} else {
|
||||
// color from database?
|
||||
Color c(value);
|
||||
if (!c.Ok()) {
|
||||
throw ScriptError(_ERROR_3_("can't convert value", value, typeName(), _TYPE_("color")));
|
||||
}
|
||||
return c;
|
||||
virtual operator AColor() const {
|
||||
AColor c = parse_acolor(value);
|
||||
if (!c.Ok()) {
|
||||
throw ScriptError(_ERROR_3_("can't convert value", value, typeName(), _TYPE_("color")));
|
||||
}
|
||||
return c;
|
||||
}
|
||||
virtual int itemCount() const { return (int)value.size(); }
|
||||
virtual ScriptValueP getMember(const String& name) const {
|
||||
@@ -225,23 +219,26 @@ ScriptValueP to_script(const String& v) {
|
||||
|
||||
// ----------------------------------------------------------------------------- : Color
|
||||
|
||||
// Color values
|
||||
class ScriptColor : public ScriptValue {
|
||||
// AColor values
|
||||
class ScriptAColor : public ScriptValue {
|
||||
public:
|
||||
ScriptColor(const Color& v) : value(v) {}
|
||||
ScriptAColor(const AColor& v) : value(v) {}
|
||||
virtual ScriptType type() const { return SCRIPT_COLOR; }
|
||||
virtual String typeName() const { return _TYPE_("color"); }
|
||||
virtual operator Color() const { return value; }
|
||||
virtual operator AColor() const { return value; }
|
||||
virtual operator int() const { return (value.Red() + value.Blue() + value.Green()) / 3; }
|
||||
virtual operator String() const {
|
||||
return String::Format(_("rgb(%u,%u,%u)"), value.Red(), value.Green(), value.Blue());
|
||||
return format_acolor(value);
|
||||
}
|
||||
private:
|
||||
Color value;
|
||||
AColor value;
|
||||
};
|
||||
|
||||
ScriptValueP to_script(const Color& v) {
|
||||
return new_intrusive1<ScriptColor>(v);
|
||||
ScriptValueP to_script(Color v) {
|
||||
return new_intrusive1<ScriptAColor>(v);
|
||||
}
|
||||
ScriptValueP to_script(AColor v) {
|
||||
return new_intrusive1<ScriptAColor>(v);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
// ----------------------------------------------------------------------------- : Includes
|
||||
|
||||
#include <util/prec.hpp>
|
||||
#include <gfx/color.hpp>
|
||||
class Context;
|
||||
class Dependency;
|
||||
|
||||
@@ -55,7 +56,7 @@ class ScriptValue : public IntrusivePtrBaseWithDelete {
|
||||
/// Convert this value to a boolean
|
||||
inline operator bool() const { return (int)*this; }
|
||||
/// Convert this value to a color
|
||||
virtual operator Color() const;
|
||||
virtual operator AColor() const;
|
||||
|
||||
/// Explicit overload to convert to a string
|
||||
/** This is sometimes necessary, because wxString has an int constructor,
|
||||
|
||||
Reference in New Issue
Block a user