mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-10 21:06:59 -04:00
Added 'filter' support to position function; Made sure sort script can depend on the value of the field itself.
Cleaned up some things, why is a blank image not thread safe? git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@548 0fc631ac-6414-0410-93d0-97cfa31319b6
This commit is contained in:
@@ -37,6 +37,10 @@ Field::Field()
|
||||
|
||||
Field::~Field() {}
|
||||
|
||||
void Field::initDependencies(Context& ctx, const Dependency& dep) const {
|
||||
sort_script.initDependencies(ctx, dep);
|
||||
}
|
||||
|
||||
IMPLEMENT_REFLECTION(Field) {
|
||||
REFLECT_IF_NOT_READING {
|
||||
String type = typeName();
|
||||
@@ -215,6 +219,18 @@ bool Value::equals(const Value* that) {
|
||||
return this == that;
|
||||
}
|
||||
|
||||
bool Value::update(Context& ctx) {
|
||||
updateAge();
|
||||
updateSortValue(ctx);
|
||||
return false;
|
||||
}
|
||||
void Value::updateAge() {
|
||||
last_script_update.update();
|
||||
}
|
||||
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(field);
|
||||
|
||||
+12
-12
@@ -68,9 +68,7 @@ class Field : public IntrusivePtrVirtualBase {
|
||||
virtual String typeName() const = 0;
|
||||
|
||||
/// Add the given dependency to the dependet_scripts list for the variables this field depends on
|
||||
inline virtual void initDependencies(Context& ctx, const Dependency& dep) const {
|
||||
sort_script.initDependencies(ctx, dep);
|
||||
}
|
||||
virtual void initDependencies(Context& ctx, const Dependency& dep) const;
|
||||
|
||||
private:
|
||||
DECLARE_REFLECTION_VIRTUAL();
|
||||
@@ -186,7 +184,7 @@ class Value : public IntrusivePtrVirtualBase {
|
||||
|
||||
const FieldP fieldP; ///< Field this value is for, should have the right type!
|
||||
Age last_script_update; ///< When where the scripts last updated? (by calling update)
|
||||
ScriptValueP sortValue; ///< How this should be sorted.
|
||||
String sort_value; ///< How this should be sorted.
|
||||
|
||||
/// Get a copy of this value
|
||||
virtual ValueP clone() const = 0;
|
||||
@@ -194,11 +192,7 @@ class Value : public IntrusivePtrVirtualBase {
|
||||
/// Convert this value to a string for use in tables
|
||||
virtual String toString() const = 0;
|
||||
/// Apply scripts to this value, return true if the value has changed
|
||||
inline virtual bool update(Context& ctx) {
|
||||
sortValue = fieldP->sort_script.invoke(ctx);
|
||||
last_script_update.update();
|
||||
return false;
|
||||
}
|
||||
virtual bool update(Context& ctx);
|
||||
/// This value has been updated by an action
|
||||
/** Does nothing for most Values, only FakeValues can update underlying data */
|
||||
virtual void onAction(Action& a, bool undone) {}
|
||||
@@ -208,11 +202,17 @@ class Value : public IntrusivePtrVirtualBase {
|
||||
*/
|
||||
virtual bool equals(const Value* that);
|
||||
|
||||
/// Get the sort key for this value.
|
||||
inline String getSortKey () const {
|
||||
return sortValue == script_nil ? *sortValue : toString();
|
||||
/// Get the key to use for sorting this value
|
||||
inline String getSortKey() const {
|
||||
return fieldP->sort_script ? sort_value : toString();
|
||||
}
|
||||
|
||||
protected:
|
||||
/// update() split into two functions;.
|
||||
/** Derived classes should put their stuff in between if they need the age in scripts */
|
||||
void updateAge();
|
||||
void updateSortValue(Context& ctx);
|
||||
|
||||
private:
|
||||
DECLARE_REFLECTION_VIRTUAL();
|
||||
};
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
|
||||
#include <data/field/choice.hpp>
|
||||
#include <util/io/package.hpp>
|
||||
#include <wx/spinctrl.h>
|
||||
#include <wx/imaglist.h>
|
||||
|
||||
DECLARE_TYPEOF_COLLECTION(ChoiceField::ChoiceP);
|
||||
@@ -312,9 +311,10 @@ String ChoiceValue::toString() const {
|
||||
return value();
|
||||
}
|
||||
bool ChoiceValue::update(Context& ctx) {
|
||||
bool change = field().default_script.invokeOnDefault(ctx, value)
|
||||
| field(). script.invokeOn(ctx, value);
|
||||
Value::update(ctx);
|
||||
return field().default_script.invokeOnDefault(ctx, value)
|
||||
| field(). script.invokeOn(ctx, value);
|
||||
return change;
|
||||
}
|
||||
|
||||
IMPLEMENT_REFLECTION_NAMELESS(ChoiceValue) {
|
||||
|
||||
@@ -91,9 +91,10 @@ String ColorValue::toString() const {
|
||||
return _("<color>");
|
||||
}
|
||||
bool ColorValue::update(Context& ctx) {
|
||||
bool change = field().default_script.invokeOnDefault(ctx, value)
|
||||
| field(). script.invokeOn(ctx, value);
|
||||
Value::update(ctx);
|
||||
return field().default_script.invokeOnDefault(ctx, value)
|
||||
| field(). script.invokeOn(ctx, value);
|
||||
return change;
|
||||
}
|
||||
|
||||
IMPLEMENT_REFLECTION_NAMELESS(ColorValue) {
|
||||
|
||||
@@ -66,9 +66,10 @@ String InfoValue::toString() const {
|
||||
return value;
|
||||
}
|
||||
bool InfoValue::update(Context& ctx) {
|
||||
Value::update(ctx);
|
||||
if (value.empty()) value = field().name;
|
||||
return field().script.invokeOn(ctx, value);
|
||||
bool change = field().script.invokeOn(ctx, value);
|
||||
Value::update(ctx);
|
||||
return change;
|
||||
}
|
||||
|
||||
IMPLEMENT_REFLECTION_NAMELESS(InfoValue) {
|
||||
|
||||
@@ -127,12 +127,13 @@ String TextValue::toString() const {
|
||||
return untag_hide_sep(value());
|
||||
}
|
||||
bool TextValue::update(Context& ctx) {
|
||||
Value::update(ctx);
|
||||
updateAge();
|
||||
WITH_DYNAMIC_ARG(last_update_age, last_update.get());
|
||||
WITH_DYNAMIC_ARG(value_being_updated, this);
|
||||
bool change = field().default_script.invokeOnDefault(ctx, value)
|
||||
| field(). script.invokeOn(ctx, value);
|
||||
if (change) last_update.update();
|
||||
updateSortValue(ctx);
|
||||
return change;
|
||||
}
|
||||
|
||||
|
||||
+25
-5
@@ -208,23 +208,43 @@ void reflect_set_info_get_member(GetMember& tag, const IndexMap<FieldP, ValueP>&
|
||||
REFLECT_NAMELESS(data);
|
||||
}
|
||||
|
||||
int Set::positionOfCard(const CardP& card, const ScriptValueP& order_by) {
|
||||
int Set::positionOfCard(const CardP& card, const ScriptValueP& order_by, const ScriptValueP& filter) {
|
||||
// TODO : Lock the map?
|
||||
assert(order_by);
|
||||
OrderCacheP& order = order_cache[order_by];
|
||||
OrderCacheP& order = order_cache[make_pair(order_by,filter)];
|
||||
if (!order) {
|
||||
// 1. make a list of the order value for each card
|
||||
vector<String> values; values.reserve(cards.size());
|
||||
vector<int> keep; if(filter) keep.reserve(cards.size());
|
||||
FOR_EACH_CONST(c, cards) {
|
||||
values.push_back(*order_by->eval(getContext(c)));
|
||||
Context& ctx = getContext(c);
|
||||
values.push_back(*order_by->eval(ctx));
|
||||
if (filter) {
|
||||
keep.push_back(*filter->eval(ctx));
|
||||
}
|
||||
}
|
||||
// 2. initialize order cache
|
||||
order = new_intrusive2<OrderCache<CardP> >(cards, values);
|
||||
// 3. initialize order cache
|
||||
order = new_intrusive3<OrderCache<CardP> >(cards, values, filter ? &keep : nullptr);
|
||||
}
|
||||
return order->find(card);
|
||||
}
|
||||
int Set::numberOfCards(const ScriptValueP& filter) {
|
||||
if (!filter) return (int)cards.size();
|
||||
map<ScriptValueP,int>::const_iterator it = filter_cache.find(filter);
|
||||
if (it !=filter_cache.end()) {
|
||||
return it->second;
|
||||
} else {
|
||||
int n = 0;
|
||||
FOR_EACH_CONST(c, cards) {
|
||||
if (*filter->eval(getContext(c))) ++n;
|
||||
}
|
||||
filter_cache.insert(make_pair(filter,n));
|
||||
return n;
|
||||
}
|
||||
}
|
||||
void Set::clearOrderCache() {
|
||||
order_cache.clear();
|
||||
filter_cache.clear();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : SetView
|
||||
|
||||
+5
-2
@@ -106,7 +106,9 @@ class Set : public Packaged {
|
||||
}
|
||||
|
||||
/// Find the position of a card in this set, when the card list is sorted using the given cirterium
|
||||
int positionOfCard(const CardP& card, const ScriptValueP& order_by);
|
||||
int positionOfCard(const CardP& card, const ScriptValueP& order_by, const ScriptValueP& filter);
|
||||
/// Find the number of cards that match the given filter
|
||||
int numberOfCards(const ScriptValueP& filter);
|
||||
/// Clear the order_cache used by positionOfCard
|
||||
void clearOrderCache();
|
||||
|
||||
@@ -122,7 +124,8 @@ class Set : public Packaged {
|
||||
/// Object for executing scripts from the thumbnail thread
|
||||
scoped_ptr<SetScriptContext> thumbnail_script_context;
|
||||
/// Cache of cards ordered by some criterion
|
||||
map<ScriptValueP,OrderCacheP> order_cache;
|
||||
map<pair<ScriptValueP,ScriptValueP>,OrderCacheP> order_cache;
|
||||
map<ScriptValueP,int> filter_cache;
|
||||
};
|
||||
|
||||
inline String type_name(const Set&) {
|
||||
|
||||
Reference in New Issue
Block a user