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:
twanvl
2008-05-16 20:51:16 +00:00
parent b0c0d8e97c
commit 1b516e781f
16 changed files with 115 additions and 44 deletions
+23
View File
@@ -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) {
+9
View File
@@ -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 (...) {
+12
View File
@@ -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;
+8 -1
View File
@@ -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
View File
@@ -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;
};
};
+5 -2
View File
@@ -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
+2
View File
@@ -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);
+6 -4
View File
@@ -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
View File
@@ -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);
}
+2 -1
View File
@@ -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,