diff --git a/src/data/game.hpp b/src/data/game.hpp index 04f9fa89..37e39264 100644 --- a/src/data/game.hpp +++ b/src/data/game.hpp @@ -58,6 +58,7 @@ class Game : public Packaged { Dependencies dependent_scripts_cards; ///< scripts that depend on the card list Dependencies dependent_scripts_keywords; ///< scripts that depend on the keywords + Dependencies dependent_scripts_stylesheet; ///< scripts that depend on the card's stylesheet bool dependencies_initialized; ///< are the script dependencies comming from this game all initialized? /// Loads the game with a particular name, for example "magic" diff --git a/src/data/stylesheet.cpp b/src/data/stylesheet.cpp index c05abd2a..47d4527b 100644 --- a/src/data/stylesheet.cpp +++ b/src/data/stylesheet.cpp @@ -88,6 +88,11 @@ StyleP StyleSheet::styleFor(const FieldP& field) { } +void mark_dependency_value(const StyleSheet& stylesheet, const Dependency& dep) { + stylesheet.game->dependent_scripts_stylesheet.add(dep); +} + + IMPLEMENT_REFLECTION(StyleSheet) { // < 0.3.0 didn't use card_ prefix REFLECT_ALIAS(300, "width", "card width"); diff --git a/src/data/stylesheet.hpp b/src/data/stylesheet.hpp index 48e22ec7..66eec289 100644 --- a/src/data/stylesheet.hpp +++ b/src/data/stylesheet.hpp @@ -77,5 +77,7 @@ inline String type_name(const StyleSheet&) { return _TYPE_("stylesheet"); } +void mark_dependency_value(const StyleSheet& value, const Dependency& dep); + // ----------------------------------------------------------------------------- : EOF #endif diff --git a/src/script/dependency.cpp b/src/script/dependency.cpp index 7b22c3ef..9fceb8f6 100644 --- a/src/script/dependency.cpp +++ b/src/script/dependency.cpp @@ -269,6 +269,7 @@ ScriptValueP Context::dependencies(const Dependency& dep, const Script& script) if (!value) { value = new_intrusive1(variable_to_string((Variable)i.data)); // no errors here } + value->dependencyThis(dep); stack.push_back(value); break; } diff --git a/src/script/dependency.hpp b/src/script/dependency.hpp index 27c79df3..320353ef 100644 --- a/src/script/dependency.hpp +++ b/src/script/dependency.hpp @@ -18,7 +18,7 @@ enum DependencyType { DEP_CARD_FIELD ///< dependency of a script in a "card" field , DEP_CARDS_FIELD ///< dependency of a script in a "card" field for all cards , DEP_SET_FIELD ///< dependency of a script in a "set" field -, DEP_STYLE ///< dependency of a script in a "style" property, data gives the stylesheet +, DEP_CARD_STYLE ///< dependency of a script in a "style" property, data gives the stylesheet , DEP_EXTRA_CARD_FIELD ///< dependency of a script in an extra stylesheet specific card field , DEP_CARD_COPY_DEP ///< copy the dependencies from a card field , DEP_SET_COPY_DEP ///< copy the dependencies from a set field diff --git a/src/script/script_manager.cpp b/src/script/script_manager.cpp index 63d79a00..86d49d72 100644 --- a/src/script/script_manager.cpp +++ b/src/script/script_manager.cpp @@ -134,7 +134,7 @@ void SetScriptManager::initDependencies(Context& ctx, StyleSheet& stylesheet) { } // find dependencies of choice images and other style stuff FOR_EACH(s, stylesheet.card_style) { - s->initDependencies(ctx, Dependency(DEP_STYLE, s->fieldP->index, &stylesheet)); + s->initDependencies(ctx, Dependency(DEP_CARD_STYLE, s->fieldP->index, &stylesheet)); // are there dependencies of this style on other style properties? Dependency test(DEP_DUMMY, false); s->checkContentDependencies(ctx, test); @@ -219,6 +219,13 @@ void SetScriptManager::onAction(const Action& action, bool undone) { updateAllDependend(set.game->dependent_scripts_keywords); return; } + TYPE_CASE(action, ChangeCardStyleAction) { + updateAllDependend(set.game->dependent_scripts_stylesheet, action.card); + } + TYPE_CASE_(action, ChangeSetStyleAction) { + updateAllDependend(set.game->dependent_scripts_stylesheet); + return; + } } void SetScriptManager::updateStyles(const CardP& card, bool only_content_dependent) { @@ -310,14 +317,15 @@ void SetScriptManager::updateAll() { #endif } -void SetScriptManager::updateAllDependend(const vector& dependent_scripts) { +void SetScriptManager::updateAllDependend(const vector& dependent_scripts, const CardP& card) { deque to_update; Age starting_age; - alsoUpdate(to_update, dependent_scripts, CardP()); + alsoUpdate(to_update, dependent_scripts, card); updateRecursive(to_update, starting_age); } void SetScriptManager::updateRecursive(deque& to_update, Age starting_age) { + if (to_update.empty()) return; set.clearOrderCache(); // clear caches before evaluating a round of scripts while (!to_update.empty()) { updateToUpdate(to_update.front(), to_update, starting_age); @@ -373,7 +381,7 @@ void SetScriptManager::alsoUpdate(deque& to_update, const vector(d.data); diff --git a/src/script/script_manager.hpp b/src/script/script_manager.hpp index fd3d5584..0269675e 100644 --- a/src/script/script_manager.hpp +++ b/src/script/script_manager.hpp @@ -84,7 +84,7 @@ class SetScriptManager : public SetScriptContext, public ActionListener { /** if the value changes any dependend values are updated as well */ void updateValue(Value& value, const CardP& card); // Update all values with a specific dependency - void updateAllDependend(const vector& dependent_scripts); + void updateAllDependend(const vector& dependent_scripts, const CardP& card = CardP()); // Something that needs to be updated struct ToUpdate { diff --git a/src/script/to_value.hpp b/src/script/to_value.hpp index 360ae88c..4a5aa7cb 100644 --- a/src/script/to_value.hpp +++ b/src/script/to_value.hpp @@ -33,6 +33,10 @@ ScriptValueP make_iterator(const T& v) { template void mark_dependency_member(const T& value, const String& name, const Dependency& dep) {} +/// Mark a dependency on an object, can be overloaded +template +void mark_dependency_value(const T& value, const Dependency& dep) {} + /// Type name of an object, for error messages template inline String type_name(const T&) { return _TYPE_("object"); @@ -276,6 +280,9 @@ class ScriptObject : public ScriptValue { mark_dependency_member(*value, name, dep); return getMember(name); } + virtual void dependencyThis(const Dependency& dep) { + mark_dependency_value(*value, dep); + } virtual ScriptValueP makeIterator(const ScriptValueP& thisP) const { ScriptValueP it = make_iterator(*value); if (it) return it; diff --git a/src/script/value.cpp b/src/script/value.cpp index 5ef4d894..f4d96613 100644 --- a/src/script/value.cpp +++ b/src/script/value.cpp @@ -54,6 +54,7 @@ ScriptValueP ScriptValue::dependencyName(const ScriptValue& container, const Dep return container.dependencyMember(toString(),dep); } ScriptValueP ScriptValue::dependencies(Context&, const Dependency&) const { return dependency_dummy; } +void ScriptValue::dependencyThis(const Dependency& dep) {} bool approx_equal(double a, double b) { return a == b || fabs(a - b) < 1e-14; diff --git a/src/script/value.hpp b/src/script/value.hpp index a527cb08..b8a4e67a 100644 --- a/src/script/value.hpp +++ b/src/script/value.hpp @@ -80,6 +80,9 @@ class ScriptValue : public IntrusivePtrBaseWithDelete { /// Get a member variable from this value virtual ScriptValueP getMember(const String& name) const; + + /// Signal that a script depends on this value itself + virtual void dependencyThis(const Dependency& dep); /// Signal that a script depends on a member of this value /** It is the abstract version of getMember*/ virtual ScriptValueP dependencyMember(const String& name, const Dependency&) const;