Commit fa1a5d24 authored by twanvl's avatar twanvl

cleanup:

 * move functionality of AnyField into Field
 * move functionality of AnyValue into Value
 * remove AnyField/AnyValue
parent 61898c08
......@@ -39,7 +39,7 @@ void ValueAction::isOnCard(Card* card) {
// ----------------------------------------------------------------------------- : Simple
/// Swap the value in a Value object with a new one
inline void swap_value(AnyValue& a, AnyValue ::ValueType& b) { swap(a.value, b); }
inline void swap_value(Value& a, ScriptValueP& b) { swap(a.value, b); }
/// A ValueAction that swaps between old and new values
template <typename T, bool ALLOW_MERGE>
......@@ -71,7 +71,7 @@ class SimpleValueAction : public ValueAction {
typename T::ValueType new_value;
};
ValueAction* value_action(const AnyValueP& value, const ScriptValueP& new_value) { return new SimpleValueAction<AnyValue, false>(value, new_value); }
ValueAction* value_action(const ValueP& value, const ScriptValueP& new_value) { return new SimpleValueAction<Value,false>(value, new_value); }
// ----------------------------------------------------------------------------- : MultipleChoice
......
......@@ -25,9 +25,8 @@ class LocalFileName;
DECLARE_POINTER_TYPE(Set);
DECLARE_POINTER_TYPE(Value);
DECLARE_POINTER_TYPE(Style);
DECLARE_POINTER_TYPE(AnyValue);
typedef AnyValue TextValue;
typedef AnyValueP TextValueP;
typedef Value TextValue;
typedef ValueP TextValueP;
DECLARE_POINTER_TYPE(MultipleChoiceValue);
// ----------------------------------------------------------------------------- : ValueAction (based class)
......@@ -54,7 +53,7 @@ class ValueAction : public Action {
// ----------------------------------------------------------------------------- : Simple
/// Action that updates a Value to a new value
ValueAction* value_action(const AnyValueP& value, const ScriptValueP& new_value);
ValueAction* value_action(const ValueP& value, const ScriptValueP& new_value);
ValueAction* value_action(const MultipleChoiceValueP& value, const ScriptValueP& new_value, const String& last_change);
// ----------------------------------------------------------------------------- : MultipleChoice
......
......@@ -35,12 +35,16 @@ Field::Field()
, card_list_visible(false)
, card_list_allow (true)
, card_list_align (ALIGN_LEFT)
, default_name (_("Default"))
, initial (script_default_nil)
{}
Field::~Field() {}
void Field::initDependencies(Context& ctx, const Dependency& dep) const {
sort_script.initDependencies(ctx, dep);
script .initDependencies(ctx, dep);
default_script.initDependencies(ctx, dep);
sort_script .initDependencies(ctx, dep);
}
IMPLEMENT_REFLECTION(Field) {
......@@ -62,8 +66,13 @@ IMPLEMENT_REFLECTION(Field) {
REFLECT(card_list_visible);
REFLECT(card_list_allow);
REFLECT(card_list_name);
REFLECT(sort_script);
REFLECT_N("card_list_alignment", card_list_align);
REFLECT(script);
REFLECT_N("default", default_script);
REFLECT(sort_script);
REFLECT(default_name);
WITH_DYNAMIC_ARG(field_for_reading, this);
REFLECT(initial);
}
void Field::after_reading(Version ver) {
......@@ -265,47 +274,7 @@ StyleListener::~StyleListener() {
}
// ----------------------------------------------------------------------------- : Value
IMPLEMENT_DYNAMIC_ARG(Value*, value_being_updated, nullptr);
Value::~Value() {}
IMPLEMENT_REFLECTION_NAMELESS(Value) {
}
bool Value::equals(const Value* that) {
return this == that;
}
bool Value::update(Context& ctx, const Action*) {
updateSortValue(ctx);
return false;
}
void Value::updateSortValue(Context& ctx) {
sort_value = fieldP->sort_script.invoke(ctx)->toString();
}
void init_object(const FieldP& field, ValueP& value) {
if (!value)
value = field->newValue();
}
template <> ValueP read_new<Value>(Reader&) {
throw InternalError(_("IndexMap contains nullptr ValueP the application should have crashed already"));
}
void mark_dependency_member(const IndexMap<FieldP,ValueP>& value, const String& name, const Dependency& dep) {
IndexMap<FieldP,ValueP>::const_iterator it = value.find(name);
if (it != value.end()) {
(*it)->fieldP->dependent_scripts.add(dep);
}
}
// ----------------------------------------------------------------------------- : AnyValue : reflecting ScriptValues
// ----------------------------------------------------------------------------- : Value : reflecting ScriptValues
// TODO: move this to a more sensible location
DECLARE_DYNAMIC_ARG(Field const*, field_for_reading);
......@@ -381,46 +350,33 @@ void Writer::handle(ScriptValueP const& value) {
handle(value->toCode());
}
// ----------------------------------------------------------------------------- : AnyField
AnyField::AnyField()
: default_name(_("Default"))
, initial(script_default_nil)
{}
void AnyField::initDependencies(Context& ctx, const Dependency& dep) const {
Field ::initDependencies(ctx, dep);
script .initDependencies(ctx, dep);
default_script.initDependencies(ctx, dep);
}
IMPLEMENT_REFLECTION(AnyField) {
REFLECT_BASE(Field);
REFLECT(script);
REFLECT_N("default", default_script);
REFLECT(default_name);
WITH_DYNAMIC_ARG(field_for_reading, this);
REFLECT(initial);
}
// ----------------------------------------------------------------------------- : Value
// ----------------------------------------------------------------------------- : AnyValue
IMPLEMENT_DYNAMIC_ARG(Value*, value_being_updated, nullptr);
AnyValue::AnyValue(AnyFieldP const& field)
: Value(field), value(field->initial)
Value::Value(const FieldP& field)
: fieldP(field), value(field->initial)
{
assert(value);
}
AnyValue::AnyValue(AnyFieldP const& field, ScriptValueP const& value)
: Value(field), value(value)
Value::Value(const FieldP& field, const ScriptValueP& value)
: fieldP(field), value(value)
{
assert(value);
}
ValueP AnyValue::clone() const {
return intrusive(new AnyValue(*this));
Value::~Value() {}
ValueP Value::clone() const {
return intrusive(new Value(*this));
}
String AnyValue::toFriendlyString() const {
bool Value::equals(const Value* that) {
return this == that;
}
String Value::toFriendlyString() const {
try {
return value->toFriendlyString();
} catch (...) {
......@@ -428,26 +384,49 @@ String AnyValue::toFriendlyString() const {
}
}
bool AnyValue::update(Context& ctx, const Action* act) {
bool Value::update(Context& ctx, const Action* act) {
WITH_DYNAMIC_ARG(last_update_age, last_modified.get()); // TODO: this is redundant, since it can be got from value_being_updated
WITH_DYNAMIC_ARG(value_being_updated, this);
bool change = false;
if (ScriptDefault const* dv = dynamic_cast<ScriptDefault*>(value.get())) {
ScriptValueP dvv = dv->un_default;
change = field().default_script.invokeOn(ctx, dvv);
change |= field().script.invokeOn(ctx, dvv);
change = fieldP->default_script.invokeOn(ctx, dvv);
change |= fieldP->script.invokeOn(ctx, dvv);
if (change) value = make_default(dvv);
} else {
change = field().script.invokeOn(ctx, value);
change = fieldP->script.invokeOn(ctx, value);
}
change |= Value::update(ctx, act);
updateSortValue(ctx);
return change;
}
void Value::updateSortValue(Context& ctx) {
sort_value = fieldP->sort_script.invoke(ctx)->toString();
}
IMPLEMENT_REFLECTION_NAMELESS(AnyValue) {
IMPLEMENT_REFLECTION_NAMELESS(Value) {
if (reflector.isWriting() && !fieldP->save_value) return;
if (reflector.isWriting() && is_default(value)) return;
WITH_DYNAMIC_ARG(field_for_reading, fieldP.get());
REFLECT_NAMELESS(value);
}
void init_object(const FieldP& field, ValueP& value) {
if (!value) {
value = field->newValue();
}
}
template <> ValueP read_new<Value>(Reader&) {
throw InternalError(_("IndexMap contains nullptr ValueP the application should have crashed already"));
}
void mark_dependency_member(const IndexMap<FieldP,ValueP>& value, const String& name, const Dependency& dep) {
IndexMap<FieldP,ValueP>::const_iterator it = value.find(name);
if (it != value.end()) {
(*it)->fieldP->dependent_scripts.add(dep);
}
}
......@@ -42,24 +42,28 @@ class Field : public IntrusivePtrVirtualBase {
Field();
virtual ~Field();
size_t index; ///< Used by IndexMap
String name; ///< Name of the field, for refering to it from scripts and files
String caption; ///< Caption for NativeLookEditor
String description; ///< Description, used in status bar
String icon_filename; ///< Filename for an icon (for list of fields)
bool editable; ///< Can values of this field be edited?
bool save_value; ///< Should values of this field be written to files? Can be false for script generated fields.
bool show_statistics; ///< Should this field appear as a group by choice in the statistics panel?
int position_hint; ///< Position in the statistics list
bool identifying; ///< Does this field give Card::identification()?
int card_list_column; ///< What column to use in the card list?
UInt card_list_width; ///< Width of the card list column (pixels).
bool card_list_visible;///< Is this field shown in the card list?
bool card_list_allow; ///< Is this field allowed to appear in the card list?
String card_list_name; ///< Alternate name to use in card list.
Alignment card_list_align; ///< Alignment of the card list colummn.
OptionalScript sort_script; ///< The script to use when sorting this, if not the value.
Dependencies dependent_scripts; ///< Scripts that depend on values of this field
size_t index; ///< Used by IndexMap
String name; ///< Name of the field, for refering to it from scripts and files
String caption; ///< Caption for NativeLookEditor
String description; ///< Description, used in status bar
String icon_filename; ///< Filename for an icon (for list of fields)
bool editable; ///< Can values of this field be edited?
bool save_value; ///< Should values of this field be written to files? Can be false for script generated fields.
bool show_statistics; ///< Should this field appear as a group by choice in the statistics panel?
int position_hint; ///< Position in the statistics list
bool identifying; ///< Does this field give Card::identification()?
int card_list_column; ///< What column to use in the card list?
UInt card_list_width; ///< Width of the card list column (pixels).
bool card_list_visible; ///< Is this field shown in the card list?
bool card_list_allow; ///< Is this field allowed to appear in the card list?
String card_list_name; ///< Alternate name to use in card list.
Alignment card_list_align; ///< Alignment of the card list colummn.
OptionalScript script; ///< Script to apply to all values
OptionalScript default_script; ///< Script that generates the default value, can be empty if there is no default
OptionalScript sort_script; ///< The script to use when sorting this, if not the value.
String default_name; ///< Name of the 'default' choice
ScriptValueP initial; ///< Initial value of a new value
Dependencies dependent_scripts; ///< Scripts that depend on values of this field
/// Creates a new Value corresponding to this Field
virtual ValueP newValue() = 0;
......@@ -99,16 +103,16 @@ class Style : public IntrusivePtrVirtualBase {
Style(const FieldP&);
virtual ~Style();
const FieldP fieldP; ///< Field this style is for, should have the right type!
const FieldP fieldP; ///< Field this style is for, should have the right type!
int z_index; ///< Stacking of values of this field, higher = on top
int tab_index; ///< Tab order in editor
Scriptable<double> left, top; ///< Position of this field
Scriptable<double> width, height; ///< Position of this field
Scriptable<double> right, bottom; ///< Position of this field
Scriptable<Degrees> angle; ///< Rotation of the box
Scriptable<bool> visible; ///< Is this field visible?
CachedScriptableMask mask; ///< Mask image
int z_index; ///< Stacking of values of this field, higher = on top
int tab_index; ///< Tab order in editor
Scriptable<double> left, top; ///< Position of this field
Scriptable<double> width, height; ///< Position of this field
Scriptable<double> right, bottom; ///< Position of this field
Scriptable<Degrees> angle; ///< Rotation of the box
Scriptable<bool> visible; ///< Is this field visible?
CachedScriptableMask mask; ///< Mask image
enum AutomaticSide {
AUTO_UNKNOWN = 0x00,
......@@ -216,19 +220,24 @@ class StyleListener : public IntrusivePtrVirtualBase {
/// A specific value 'in' a Field.
class Value : public IntrusivePtrVirtualBase {
public:
inline Value(const FieldP& field) : fieldP(field) {}
Value(const FieldP& field);
Value(const FieldP& field, ScriptValueP const& value);
virtual ~Value();
const FieldP fieldP; ///< Field this value is for, should have the right type!
Age last_modified; ///< When was the value last modified? Note: this also goes up on undo.
///< This variable is used by ScriptManager. It will be incremented by each round of script updates.
String sort_value; ///< How this should be sorted.
const FieldP fieldP; ///< Field this value is for, should have the right type!
Age last_modified; ///< When was the value last modified? Note: this also goes up on undo.
///< This variable is used by ScriptManager. It will be incremented by each round of script updates.
String sort_value; ///< How this should be sorted.
ScriptValueP value; ///< The value, never null
typedef ScriptValueP ValueType;
inline Field& field() const { return *fieldP; }
/// Get a copy of this value
virtual ValueP clone() const = 0;
virtual ValueP clone() const;
/// Convert this value to a string, should be human readable, so no <tags>
virtual String toFriendlyString() const = 0;
virtual String toFriendlyString() const;
/// Apply scripts to this value, return true if the value has changed
/** Optionally, the action that causes the update is also passed.
*/
......@@ -315,48 +324,5 @@ inline String type_name(const Value&) {
void mark_dependency_member(const IndexMap<FieldP,ValueP>& value, const String& name, const Dependency& dep);
// ----------------------------------------------------------------------------- : Value (new style)
/// Base class for fields whos values can be scripted
// TODO: merge into Field
class AnyField : public Field {
public:
AnyField();
OptionalScript script; ///< Script to apply to all values
OptionalScript default_script; ///< Script that generates the default value, can be empty if there is no default
String default_name; ///< Name of the 'default' choice
ScriptValueP initial; ///< Initial choice of a new value, if not set the first choice is used
DECLARE_REFLECTION_VIRTUAL();
virtual void initDependencies(Context&, const Dependency&) const;
};
DECLARE_POINTER_TYPE(AnyField)
/// A Value object that can hold something of 'any' type
// TODO: merge into Value
class AnyValue : public Value {
public:
AnyValue(AnyFieldP const& field);
AnyValue(AnyFieldP const& field, ScriptValueP const& value);
/// The actual value
typedef ScriptValueP ValueType;
ScriptValueP value; // never null
virtual ValueP clone() const;
virtual String toFriendlyString() const;
virtual bool update(Context& ctx, const Action* = nullptr);
// Convenience functions
inline void operator = (ScriptValueP const& value) {
this->value = value;
}
DECLARE_HAS_FIELD(Any)
DECLARE_REFLECTION_VIRTUAL();
};
DECLARE_POINTER_TYPE(AnyValue)
// ----------------------------------------------------------------------------- : EOF
#endif
......@@ -21,7 +21,7 @@ BooleanField::BooleanField() {
IMPLEMENT_FIELD_TYPE(Boolean, "boolean");
IMPLEMENT_REFLECTION(BooleanField) {
REFLECT_BASE(AnyField); // NOTE: don't reflect as a ChoiceField, because we don't want to add extra choices
REFLECT_BASE(Field); // NOTE: don't reflect as a ChoiceField, because we don't want to add extra choices
}
// ----------------------------------------------------------------------------- : BooleanStyle
......
......@@ -25,14 +25,14 @@ ChoiceField::ChoiceField()
IMPLEMENT_FIELD_TYPE(Choice, "choice");
IMPLEMENT_REFLECTION(ChoiceField) {
REFLECT_BASE(AnyField);
REFLECT_BASE(Field);
REFLECT_N("choices", choices->choices);
REFLECT(choice_colors);
REFLECT(choice_colors_cardlist);
}
void ChoiceField::after_reading(Version ver) {
AnyField::after_reading(ver);
Field::after_reading(ver);
choices->initIds();
if(initial == script_default_nil && !dynamic_cast<MultipleChoiceField*>(this)) {
initial = make_default(to_script(choices->choiceName(0)));
......
......@@ -24,7 +24,7 @@ DECLARE_POINTER_TYPE(ChoiceField);
DECLARE_POINTER_TYPE(ChoiceStyle);
/// A field that contains a list of choices
class ChoiceField : public AnyField {
class ChoiceField : public Field {
public:
ChoiceField();
DECLARE_FIELD_TYPE();
......@@ -160,8 +160,8 @@ class ChoiceStyle : public Style {
// ----------------------------------------------------------------------------- : ChoiceValue
typedef AnyValue ChoiceValue;
typedef AnyValueP ChoiceValueP;
typedef Value ChoiceValue;
typedef ValueP ChoiceValueP;
// ----------------------------------------------------------------------------- : EOF
#endif
......@@ -21,7 +21,7 @@ ColorField::ColorField()
IMPLEMENT_FIELD_TYPE(Color, "color");
IMPLEMENT_REFLECTION(ColorField) {
REFLECT_BASE(AnyField);
REFLECT_BASE(Field);
REFLECT(allow_custom);
REFLECT(choices);
}
......
......@@ -21,7 +21,7 @@ DECLARE_POINTER_TYPE(ColorField);
DECLARE_POINTER_TYPE(ColorStyle);
/// A field for color values, it contains a list of choices for colors
class ColorField : public AnyField {
class ColorField : public Field {
public:
ColorField();
DECLARE_FIELD_TYPE();
......@@ -62,8 +62,8 @@ class ColorStyle : public Style {
// ----------------------------------------------------------------------------- : ColorValue
typedef AnyValue ColorValue;
typedef AnyValueP ColorValueP;
typedef Value ColorValue;
typedef ValueP ColorValueP;
// ----------------------------------------------------------------------------- : EOF
#endif
......@@ -20,7 +20,7 @@ DECLARE_POINTER_TYPE(ImageField);
DECLARE_POINTER_TYPE(ImageStyle);
/// A field for image values
class ImageField : public AnyField {
class ImageField : public Field {
public:
// no extra data
DECLARE_FIELD_TYPE();
......@@ -41,8 +41,8 @@ class ImageStyle : public Style {
// ----------------------------------------------------------------------------- : ImageValue
typedef AnyValue ImageValue;
typedef AnyValueP ImageValueP;
typedef Value ImageValue;
typedef ValueP ImageValueP;
// ----------------------------------------------------------------------------- : EOF
#endif
......@@ -15,11 +15,11 @@
IMPLEMENT_FIELD_TYPE(Info, "info");
IMPLEMENT_REFLECTION(InfoField) {
REFLECT_BASE(AnyField);
REFLECT_BASE(Field);
}
void InfoField::after_reading(Version ver) {
AnyField::after_reading(ver);
Field::after_reading(ver);
if (initial == script_default_nil) initial = to_script(caption);
initial = make_default(initial);
}
......
......@@ -23,7 +23,7 @@ DECLARE_POINTER_TYPE(InfoStyle);
/// A field for informational values.
/** These values are not editable, they are just headers, icons, labels, etc.
*/
class InfoField : public AnyField {
class InfoField : public Field {
public:
InfoField() { editable = false; }
DECLARE_FIELD_TYPE();
......@@ -50,8 +50,8 @@ class InfoStyle : public Style {
// ----------------------------------------------------------------------------- : InfoValue
typedef AnyValue InfoValue;
typedef AnyValueP InfoValueP;
typedef Value InfoValue;
typedef ValueP InfoValueP;
// ----------------------------------------------------------------------------- : EOF
#endif
......@@ -15,7 +15,7 @@
IMPLEMENT_FIELD_TYPE(PackageChoice, "package choice");
IMPLEMENT_REFLECTION(PackageChoiceField) {
REFLECT_BASE(AnyField);
REFLECT_BASE(Field);
REFLECT(match);
REFLECT(required);
REFLECT(empty_name);
......
......@@ -22,7 +22,7 @@ DECLARE_POINTER_TYPE(PackageChoiceField);
DECLARE_POINTER_TYPE(PackageChoiceStyle);
/// A field for PackageChoice values, it contains a list of choices for PackageChoices
class PackageChoiceField : public AnyField {
class PackageChoiceField : public Field {
public:
PackageChoiceField() : required(true), empty_name(_("none")) {}
DECLARE_FIELD_TYPE();
......@@ -47,8 +47,8 @@ class PackageChoiceStyle : public Style {
// ----------------------------------------------------------------------------- : PackageChoiceValue
typedef AnyValue PackageChoiceValue;
typedef AnyValueP PackageChoiceValueP;
typedef Value PackageChoiceValue;
typedef ValueP PackageChoiceValueP;
// ----------------------------------------------------------------------------- : EOF
#endif
......@@ -23,7 +23,7 @@ DECLARE_POINTER_TYPE(SymbolField);
DECLARE_POINTER_TYPE(SymbolStyle);
/// A field for image values
class SymbolField : public AnyField {
class SymbolField : public Field {
public:
DECLARE_FIELD_TYPE();
......@@ -62,8 +62,8 @@ class SymbolVariation : public IntrusivePtrBase<SymbolVariation> {
// ----------------------------------------------------------------------------- : SymbolValue
typedef AnyValue SymbolValue;
typedef AnyValueP SymbolValueP;
typedef Value SymbolValue;
typedef ValueP SymbolValueP;
// A file that refers to a symbol
class LocalSymbolFile : public ScriptValue {
......
......@@ -21,7 +21,7 @@ IMPLEMENT_FIELD_TYPE(Text, "text");
IMPLEMENT_REFLECTION(TextField) {
REFLECT_BASE(AnyField);
REFLECT_BASE(Field);
REFLECT(multi_line);
}
......
......@@ -26,7 +26,7 @@ DECLARE_POINTER_TYPE(TextField);
DECLARE_POINTER_TYPE(TextStyle);
/// A field for values containing tagged text
class TextField : public AnyField {
class TextField : public Field {
public:
TextField();
DECLARE_FIELD_TYPE();
......@@ -74,8 +74,8 @@ class TextStyle : public Style {
// ----------------------------------------------------------------------------- : TextValue
typedef AnyValue TextValue;
typedef AnyValueP TextValueP;
typedef Value TextValue;
typedef ValueP TextValueP;
// ----------------------------------------------------------------------------- : TextValue
......
......@@ -123,7 +123,7 @@ void read_mse1_card(Set& set, wxFileInputStream& f, wxTextInputStream& file) {
} case 'C': case 'D': { // image filename
LocalFileName image_file = set.newFileName(_("image"),_("")); // a new unique name in the package
if (wxCopyFile(line, set.nameOut(image_file), true)) {
card->value<ImageValue>(_("image")) = script_local_image_file(image_file);
card->value<ImageValue>(_("image")).value = script_local_image_file(image_file);
}
break;
} case 'E': { // super type
......
......@@ -252,7 +252,7 @@ void SymbolWindow::onFileStore(wxCommandEvent& ev) {
if (performer) {
SymbolValueP value = static_pointer_cast<SymbolValue>(performer->value);
Package& package = performer->getLocalPackage();
LocalFileName new_filename = package.newFileName(value->field().name,_(".mse-symbol")); // a new unique name in the package
LocalFileName new_filename = package.newFileName(value->fieldP->name,_(".mse-symbol")); // a new unique name in the package
OutputStreamP stream = package.openOut(new_filename);
Writer writer(*stream, file_version_symbol);
writer.handle(control->getSymbol());
......
......@@ -35,14 +35,9 @@ SCRIPT_FUNCTION(new_card) {
if (value_it == new_card->data.end()) {
throw ScriptError(format_string(_("Card doesn't have a field named '%s'"),name));
}
// set it
Value* value = value_it->get();
// set the value
if (AnyValue* avalue = dynamic_cast<AnyValue*>(value)) {
avalue->value = v;
} else
{
throw ScriptError(format_string(_("Can not set value '%s', it is not of the right type"),name));
}
value->value = v;
}
SCRIPT_RETURN(new_card);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment