mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-12 21:47:00 -04:00
Support for extra card fields in stylesheets;
Fixed some bugs: - Missing choice images can crash mse. - The wrong style is used for making preview choice images on style panel. FOR_EACH(x, *y.z) should now work without parentheses on linux as well. git-svn-id: svn://svn.code.sf.net/p/magicseteditor/code/trunk@389 0fc631ac-6414-0410-93d0-97cfa31319b6
This commit is contained in:
@@ -34,6 +34,9 @@ class Card : public IntrusivePtrVirtualBase {
|
|||||||
/// The values on the fields of the card.
|
/// The values on the fields of the card.
|
||||||
/** The indices should correspond to the card_fields in the Game */
|
/** The indices should correspond to the card_fields in the Game */
|
||||||
IndexMap<FieldP, ValueP> data;
|
IndexMap<FieldP, ValueP> data;
|
||||||
|
/// The values on the extra fields of the card.
|
||||||
|
/** The indices should correspond to the extra_card_fields in the StyleSheet */
|
||||||
|
IndexMap<FieldP, ValueP> extra_data;
|
||||||
/// Notes for this card
|
/// Notes for this card
|
||||||
String notes;
|
String notes;
|
||||||
/// Alternative style to use for this card
|
/// Alternative style to use for this card
|
||||||
|
|||||||
+1
-1
@@ -53,7 +53,7 @@ Context& Set::getContext(const CardP& card) {
|
|||||||
assert(wxThread::IsMain());
|
assert(wxThread::IsMain());
|
||||||
return script_manager->getContext(card);
|
return script_manager->getContext(card);
|
||||||
}
|
}
|
||||||
void Set::updateFor(const CardP& card) {
|
void Set::updateStyles(const CardP& card) {
|
||||||
script_manager->updateStyles(card);
|
script_manager->updateStyles(card);
|
||||||
}
|
}
|
||||||
void Set::updateDelayed() {
|
void Set::updateDelayed() {
|
||||||
|
|||||||
+2
-2
@@ -66,8 +66,8 @@ class Set : public Packaged {
|
|||||||
/// A context for performing scripts on a particular card
|
/// A context for performing scripts on a particular card
|
||||||
/** Should only be used from the main thread! */
|
/** Should only be used from the main thread! */
|
||||||
Context& getContext(const CardP& card);
|
Context& getContext(const CardP& card);
|
||||||
/// Update styles for a card
|
/// Update styles and extra_card_fields for a card
|
||||||
void updateFor(const CardP& card);
|
void updateStyles(const CardP& card);
|
||||||
/// Update scripts that were delayed
|
/// Update scripts that were delayed
|
||||||
void updateDelayed();
|
void updateDelayed();
|
||||||
/// A context for performing scripts
|
/// A context for performing scripts
|
||||||
|
|||||||
+19
-5
@@ -12,6 +12,7 @@
|
|||||||
#include <util/io/package_manager.hpp>
|
#include <util/io/package_manager.hpp>
|
||||||
|
|
||||||
DECLARE_TYPEOF_COLLECTION(StyleSheet*);
|
DECLARE_TYPEOF_COLLECTION(StyleSheet*);
|
||||||
|
DECLARE_TYPEOF_COLLECTION(FieldP);
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : StyleSheet
|
// ----------------------------------------------------------------------------- : StyleSheet
|
||||||
|
|
||||||
@@ -62,22 +63,35 @@ IMPLEMENT_REFLECTION(StyleSheet) {
|
|||||||
|
|
||||||
REFLECT(game);
|
REFLECT(game);
|
||||||
REFLECT_BASE(Packaged);
|
REFLECT_BASE(Packaged);
|
||||||
REFLECT(init_script);
|
|
||||||
REFLECT(card_width);
|
REFLECT(card_width);
|
||||||
REFLECT(card_height);
|
REFLECT(card_height);
|
||||||
REFLECT(card_dpi);
|
REFLECT(card_dpi);
|
||||||
REFLECT(card_background);
|
REFLECT(card_background);
|
||||||
|
REFLECT(init_script);
|
||||||
|
// styling
|
||||||
|
REFLECT(styling_fields);
|
||||||
|
REFLECT_IF_READING styling_style.init(styling_fields);
|
||||||
|
REFLECT(styling_style);
|
||||||
|
// style of game fields
|
||||||
if (game) {
|
if (game) {
|
||||||
REFLECT_IF_READING {
|
REFLECT_IF_READING {
|
||||||
card_style.init(game->card_fields);
|
card_style.init(game->card_fields);
|
||||||
set_info_style.cloneFrom(game->default_set_style);
|
set_info_style.cloneFrom(game->default_set_style);
|
||||||
}
|
}
|
||||||
REFLECT(card_style);
|
|
||||||
REFLECT(set_info_style);
|
REFLECT(set_info_style);
|
||||||
|
REFLECT(card_style);
|
||||||
}
|
}
|
||||||
REFLECT(styling_fields);
|
// extra card fields
|
||||||
REFLECT_IF_READING styling_style.init(styling_fields);
|
REFLECT(extra_card_fields);
|
||||||
REFLECT(styling_style);
|
REFLECT_IF_READING {
|
||||||
|
if (extra_card_style.init(extra_card_fields)) {
|
||||||
|
// make sure the extra_card_fields are not editable and savable
|
||||||
|
FOR_EACH(f, extra_card_fields) {
|
||||||
|
f->editable = f->save_value = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
REFLECT(extra_card_style);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -38,7 +38,10 @@ class StyleSheet : public Packaged {
|
|||||||
/// The styling for set info fields
|
/// The styling for set info fields
|
||||||
/** The indices should correspond to the set_fields in the Game */
|
/** The indices should correspond to the set_fields in the Game */
|
||||||
IndexMap<FieldP, StyleP> set_info_style;
|
IndexMap<FieldP, StyleP> set_info_style;
|
||||||
/// Extra fields for styling
|
/// Extra card fields for boxes and borders
|
||||||
|
vector<FieldP> extra_card_fields;
|
||||||
|
IndexMap<FieldP, StyleP> extra_card_style;
|
||||||
|
/// Extra fields for styling options
|
||||||
vector<FieldP> styling_fields;
|
vector<FieldP> styling_fields;
|
||||||
/// The styling for the extra set fields
|
/// The styling for the extra set fields
|
||||||
/** The indices should correspond to the styling_fields */
|
/** The indices should correspond to the styling_fields */
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ GraphData::GraphData(const GraphDataPre& d)
|
|||||||
}
|
}
|
||||||
} else if (a->order) {
|
} else if (a->order) {
|
||||||
// specific group order
|
// specific group order
|
||||||
FOR_EACH_CONST(gn, (*(a->order))) {
|
FOR_EACH_CONST(gn, *a->order) {
|
||||||
UInt count = counts[gn];
|
UInt count = counts[gn];
|
||||||
a->groups.push_back(GraphGroup(gn, count));
|
a->groups.push_back(GraphGroup(gn, count));
|
||||||
a->max = max(a->max, count);
|
a->max = max(a->max, count);
|
||||||
|
|||||||
@@ -192,7 +192,7 @@ StylingEditor::StylingEditor(Window* parent, int id, long style)
|
|||||||
{}
|
{}
|
||||||
|
|
||||||
void StylingEditor::showStylesheet(const StyleSheetP& stylesheet) {
|
void StylingEditor::showStylesheet(const StyleSheetP& stylesheet) {
|
||||||
setStyles(set->stylesheet, stylesheet->styling_style);
|
setStyles(stylesheet, stylesheet->styling_style);
|
||||||
setData(set->stylingDataFor(*stylesheet));
|
setData(set->stylingDataFor(*stylesheet));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,11 +10,11 @@
|
|||||||
// ----------------------------------------------------------------------------- : Includes
|
// ----------------------------------------------------------------------------- : Includes
|
||||||
|
|
||||||
#include <util/prec.hpp>
|
#include <util/prec.hpp>
|
||||||
#include <wx/spinctrl.h>
|
|
||||||
|
|
||||||
class ImageSlicePreview;
|
class ImageSlicePreview;
|
||||||
class ImageSliceSelector;
|
class ImageSliceSelector;
|
||||||
class wxSpinEvent;
|
class wxSpinEvent;
|
||||||
|
class wxSpinCtrl;
|
||||||
DECLARE_POINTER_TYPE(AlphaMask);
|
DECLARE_POINTER_TYPE(AlphaMask);
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : ImageSlice
|
// ----------------------------------------------------------------------------- : ImageSlice
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include <gui/thumbnail_thread.hpp>
|
#include <gui/thumbnail_thread.hpp>
|
||||||
#include <util/platform.hpp>
|
#include <util/platform.hpp>
|
||||||
|
#include <util/error.hpp>
|
||||||
#include <wx/thread.h>
|
#include <wx/thread.h>
|
||||||
|
|
||||||
typedef pair<ThumbnailRequestP,Image> pair_ThumbnailRequestP_Image;
|
typedef pair<ThumbnailRequestP,Image> pair_ThumbnailRequestP_Image;
|
||||||
@@ -71,7 +72,13 @@ wxThread::ExitCode ThumbnailThreadWorker::Entry() {
|
|||||||
parent->open_requests.pop_front();
|
parent->open_requests.pop_front();
|
||||||
}
|
}
|
||||||
// perform request
|
// perform request
|
||||||
Image img = current->generate();
|
Image img;
|
||||||
|
try {
|
||||||
|
img = current->generate();
|
||||||
|
} catch (const Error& e) {
|
||||||
|
handle_error(e, false, false);
|
||||||
|
} catch (...) {
|
||||||
|
}
|
||||||
// store in cache
|
// store in cache
|
||||||
if (img.Ok()) {
|
if (img.Ok()) {
|
||||||
String filename = image_cache_dir() + safe_filename(current->cache_name) + _(".png");
|
String filename = image_cache_dir() + safe_filename(current->cache_name) + _(".png");
|
||||||
|
|||||||
@@ -196,8 +196,13 @@ bool TextValueEditor::onChar(wxKeyEvent& ev) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
#ifdef __WXMSW__
|
||||||
|
if (ev.GetKeyCode() >= _(' ') && ev.GetKeyCode() == (int)ev.GetRawKeyCode()) {
|
||||||
|
// This check is need, otherwise pressing a key, say "0" on the numpad produces "a0"
|
||||||
|
// (don't ask me why)
|
||||||
|
#else
|
||||||
if (ev.GetKeyCode() >= _(' ') /*&& ev.GetKeyCode() == (int)ev.GetRawKeyCode()*/) {
|
if (ev.GetKeyCode() >= _(' ') /*&& ev.GetKeyCode() == (int)ev.GetRawKeyCode()*/) {
|
||||||
// if (ev.GetKeyCode() >= _(' ') && ev.GetKeyCode() == (int)ev.GetRawKeyCode()) {
|
#endif
|
||||||
// TODO: Find a more correct way to determine normal characters,
|
// TODO: Find a more correct way to determine normal characters,
|
||||||
// this might not work for internationalized input.
|
// this might not work for internationalized input.
|
||||||
// It might also not be portable!
|
// It might also not be portable!
|
||||||
|
|||||||
+3
-3
@@ -2506,6 +2506,9 @@
|
|||||||
<Filter
|
<Filter
|
||||||
Name="base"
|
Name="base"
|
||||||
Filter="">
|
Filter="">
|
||||||
|
<File
|
||||||
|
RelativePath=".\script\dependency.hpp">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\script\script.cpp">
|
RelativePath=".\script\script.cpp">
|
||||||
</File>
|
</File>
|
||||||
@@ -2534,9 +2537,6 @@
|
|||||||
<File
|
<File
|
||||||
RelativePath=".\script\dependency.cpp">
|
RelativePath=".\script\dependency.cpp">
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath=".\script\dependency.hpp">
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath=".\script\parser.cpp">
|
RelativePath=".\script\parser.cpp">
|
||||||
</File>
|
</File>
|
||||||
|
|||||||
+31
-12
@@ -41,10 +41,14 @@ void DataViewer::draw(RotatedDC& dc, const Color& background) {
|
|||||||
clearDC(dc.getDC(), background);
|
clearDC(dc.getDC(), background);
|
||||||
// update style scripts
|
// update style scripts
|
||||||
try {
|
try {
|
||||||
Context& ctx = getContext();
|
if (card) {
|
||||||
FOR_EACH(v, viewers) {
|
set->updateStyles(card);
|
||||||
if (v->getStyle()->update(ctx)) {
|
} else {
|
||||||
v->getStyle()->tellListeners();
|
Context& ctx = getContext();
|
||||||
|
FOR_EACH(v, viewers) {
|
||||||
|
if (v->getStyle()->update(ctx)) {
|
||||||
|
v->getStyle()->tellListeners();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (const Error& e) {
|
} catch (const Error& e) {
|
||||||
@@ -91,8 +95,9 @@ void DataViewer::setCard(const CardP& card, bool refresh) {
|
|||||||
assert(set);
|
assert(set);
|
||||||
this->card = card;
|
this->card = card;
|
||||||
stylesheet = new_stylesheet;
|
stylesheet = new_stylesheet;
|
||||||
setStyles(stylesheet, stylesheet->card_style);
|
setStyles(stylesheet, stylesheet->card_style, &stylesheet->extra_card_style);
|
||||||
setData(card->data);
|
card->extra_data.init(stylesheet->extra_card_fields); // make sure extra_data is initialized
|
||||||
|
setData(card->data, &card->extra_data);
|
||||||
onChangeSize();
|
onChangeSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,7 +116,7 @@ struct CompareViewer {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void DataViewer::setStyles(const StyleSheetP& stylesheet, IndexMap<FieldP,StyleP>& styles) {
|
void DataViewer::setStyles(const StyleSheetP& stylesheet, IndexMap<FieldP,StyleP>& styles, IndexMap<FieldP,StyleP>* extra_styles) {
|
||||||
if (!viewers.empty() && styles.contains(viewers.front()->getStyle())) {
|
if (!viewers.empty() && styles.contains(viewers.front()->getStyle())) {
|
||||||
// already using these styles
|
// already using these styles
|
||||||
return;
|
return;
|
||||||
@@ -119,6 +124,13 @@ void DataViewer::setStyles(const StyleSheetP& stylesheet, IndexMap<FieldP,StyleP
|
|||||||
this->stylesheet = stylesheet;
|
this->stylesheet = stylesheet;
|
||||||
// create viewers
|
// create viewers
|
||||||
viewers.clear();
|
viewers.clear();
|
||||||
|
addStyles(styles);
|
||||||
|
if (extra_styles) addStyles(*extra_styles);
|
||||||
|
// sort viewers by z-index of style
|
||||||
|
stable_sort(viewers.begin(), viewers.end(), CompareViewer());
|
||||||
|
onInit();
|
||||||
|
}
|
||||||
|
void DataViewer::addStyles(IndexMap<FieldP,StyleP>& styles) {
|
||||||
FOR_EACH(s, styles) {
|
FOR_EACH(s, styles) {
|
||||||
if ((s->visible || s->visible.isScripted()) &&
|
if ((s->visible || s->visible.isScripted()) &&
|
||||||
nativeLook() || (
|
nativeLook() || (
|
||||||
@@ -129,14 +141,21 @@ void DataViewer::setStyles(const StyleSheetP& stylesheet, IndexMap<FieldP,StyleP
|
|||||||
if (viewer) viewers.push_back(viewer);
|
if (viewer) viewers.push_back(viewer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// sort viewers by z-index of style
|
|
||||||
stable_sort(viewers.begin(), viewers.end(), CompareViewer());
|
|
||||||
onInit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DataViewer::setData(IndexMap<FieldP,ValueP>& values) {
|
void DataViewer::setData(IndexMap<FieldP,ValueP>& values, IndexMap<FieldP,ValueP>* extra_values) {
|
||||||
FOR_EACH(v, viewers) {
|
FOR_EACH(v, viewers) {
|
||||||
v->setValue(values[v->getField()]);
|
// is this field contained in values?
|
||||||
|
ValueP val = values.tryGet(v->getField());
|
||||||
|
if (val) {
|
||||||
|
v->setValue(val);
|
||||||
|
} else {
|
||||||
|
// if it is not in values it should be in extra values
|
||||||
|
assert(extra_values);
|
||||||
|
val = extra_values->tryGet(v->getField());
|
||||||
|
assert(val);
|
||||||
|
v->setValue(val);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
onChange();
|
onChange();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,11 +72,14 @@ class DataViewer : public SetView {
|
|||||||
virtual void onChangeSet();
|
virtual void onChangeSet();
|
||||||
|
|
||||||
// --------------------------------------------------- : The viewers
|
// --------------------------------------------------- : The viewers
|
||||||
|
private:
|
||||||
|
/// Create some viewers for the given styles
|
||||||
|
void addStyles(IndexMap<FieldP,StyleP>& styles);
|
||||||
protected:
|
protected:
|
||||||
/// Set the styles for the data to be shown, recreating the viewers
|
/// Set the styles for the data to be shown, recreating the viewers
|
||||||
void setStyles(const StyleSheetP& stylesheet, IndexMap<FieldP,StyleP>& styles);
|
void setStyles(const StyleSheetP& stylesheet, IndexMap<FieldP,StyleP>& styles, IndexMap<FieldP,StyleP>* extra_styles = nullptr);
|
||||||
/// Set the data to be shown in the viewers, refresh them
|
/// Set the data to be shown in the viewers, refresh them
|
||||||
void setData(IndexMap<FieldP,ValueP>& values);
|
void setData(IndexMap<FieldP,ValueP>& values, IndexMap<FieldP,ValueP>* extra_values = nullptr);
|
||||||
|
|
||||||
/// Create a viewer for the given style.
|
/// Create a viewer for the given style.
|
||||||
/** Can be overloaded to create a ValueEditor instead */
|
/** Can be overloaded to create a ValueEditor instead */
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ enum DependencyType
|
|||||||
, DEP_CARDS_FIELD ///< dependency of a script in a "card" field for all cards
|
, 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_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_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_CARD_COPY_DEP ///< copy the dependencies from a card field
|
||||||
, DEP_SET_COPY_DEP ///< copy the dependencies from a set field
|
, DEP_SET_COPY_DEP ///< copy the dependencies from a set field
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -123,6 +123,10 @@ void SetScriptManager::initDependencies(Context& ctx, Game& game) {
|
|||||||
void SetScriptManager::initDependencies(Context& ctx, StyleSheet& stylesheet) {
|
void SetScriptManager::initDependencies(Context& ctx, StyleSheet& stylesheet) {
|
||||||
if (stylesheet.dependencies_initialized) return;
|
if (stylesheet.dependencies_initialized) return;
|
||||||
stylesheet.dependencies_initialized = true;
|
stylesheet.dependencies_initialized = true;
|
||||||
|
// find dependencies of extra card fields
|
||||||
|
/*FOR_EACH(f, stylesheet.extra_card_fields) {
|
||||||
|
f->initDependencies(ctx, Dependency(DEP_EXTRA_CARD_FIELD, f->index, &stylesheet));
|
||||||
|
}*/
|
||||||
// find dependencies of choice images and other style stuff
|
// find dependencies of choice images and other style stuff
|
||||||
FOR_EACH(s, stylesheet.card_style) {
|
FOR_EACH(s, stylesheet.card_style) {
|
||||||
s->initDependencies(ctx, Dependency(DEP_STYLE, s->fieldP->index, &stylesheet));
|
s->initDependencies(ctx, Dependency(DEP_STYLE, s->fieldP->index, &stylesheet));
|
||||||
@@ -188,11 +192,20 @@ void SetScriptManager::onAction(const Action& action, bool undone) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SetScriptManager::updateStyles(const CardP& card) {
|
void SetScriptManager::updateStyles(const CardP& card) {
|
||||||
// lastUpdatedCard = card;
|
assert(card);
|
||||||
const StyleSheet& stylesheet = set.stylesheetFor(card);
|
const StyleSheet& stylesheet = set.stylesheetFor(card);
|
||||||
Context& ctx = getContext(card);
|
Context& ctx = getContext(card);
|
||||||
|
// update extra card fields
|
||||||
|
card->extra_data.init(stylesheet.extra_card_fields);
|
||||||
|
FOR_EACH(v, card->extra_data) {
|
||||||
|
v->update(ctx);
|
||||||
|
}
|
||||||
// update all styles
|
// update all styles
|
||||||
FOR_EACH_CONST(s, stylesheet.card_style) {
|
updateStyles(ctx, stylesheet.card_style);
|
||||||
|
updateStyles(ctx, stylesheet.extra_card_style);
|
||||||
|
}
|
||||||
|
void SetScriptManager::updateStyles(Context& ctx, const IndexMap<FieldP,StyleP>& styles) {
|
||||||
|
FOR_EACH_CONST(s, styles) {
|
||||||
if (s->update(ctx)) {
|
if (s->update(ctx)) {
|
||||||
// style has changed, tell listeners
|
// style has changed, tell listeners
|
||||||
s->tellListeners();
|
s->tellListeners();
|
||||||
@@ -313,6 +326,17 @@ void SetScriptManager::alsoUpdate(deque<ToUpdate>& to_update, const vector<Depen
|
|||||||
ScriptStyleEvent change(stylesheet, style.get());
|
ScriptStyleEvent change(stylesheet, style.get());
|
||||||
set.actions.tellListeners(change, false);
|
set.actions.tellListeners(change, false);
|
||||||
break;
|
break;
|
||||||
|
/*} case DEP_EXTRA_CARD_FIELD: {
|
||||||
|
// Not needed, extra card fields are handled in updateStyles()
|
||||||
|
if (card) {
|
||||||
|
StyleSheet* stylesheet = reinterpret_cast<StyleSheet*>(d.data);
|
||||||
|
StyleSheet* stylesheet_card = &set.stylesheetFor(card);
|
||||||
|
if (stylesheet == stylesheet_card) {
|
||||||
|
ValueP value = card->extra_data.at(d.index);
|
||||||
|
to_update.push_back(ToUpdate(value.get(), card));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;*/
|
||||||
} case DEP_CARD_COPY_DEP: {
|
} case DEP_CARD_COPY_DEP: {
|
||||||
// propagate dependencies from another field
|
// propagate dependencies from another field
|
||||||
FieldP f = set.game->card_fields[d.index];
|
FieldP f = set.game->card_fields[d.index];
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ class Value;
|
|||||||
DECLARE_POINTER_TYPE(Game);
|
DECLARE_POINTER_TYPE(Game);
|
||||||
DECLARE_POINTER_TYPE(StyleSheet);
|
DECLARE_POINTER_TYPE(StyleSheet);
|
||||||
DECLARE_POINTER_TYPE(Card);
|
DECLARE_POINTER_TYPE(Card);
|
||||||
|
DECLARE_POINTER_TYPE(Field);
|
||||||
|
DECLARE_POINTER_TYPE(Style);
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------- : SetScriptContext
|
// ----------------------------------------------------------------------------- : SetScriptContext
|
||||||
|
|
||||||
@@ -76,6 +78,8 @@ class SetScriptManager : public SetScriptContext, public ActionListener {
|
|||||||
void initDependencies(Context&, Game&);
|
void initDependencies(Context&, Game&);
|
||||||
void initDependencies(Context&, StyleSheet&);
|
void initDependencies(Context&, StyleSheet&);
|
||||||
|
|
||||||
|
/// Update a map of styles
|
||||||
|
void updateStyles(Context& ctx, const IndexMap<FieldP,StyleP>& styles);
|
||||||
/// Updates scripts, starting at some value
|
/// Updates scripts, starting at some value
|
||||||
/** if the value changes any dependend values are updated as well */
|
/** if the value changes any dependend values are updated as well */
|
||||||
void updateValue(Value& value, const CardP& card);
|
void updateValue(Value& value, const CardP& card);
|
||||||
|
|||||||
+3
-1
@@ -55,10 +55,12 @@ vector<String> previous_errors;
|
|||||||
String pending_errors;
|
String pending_errors;
|
||||||
String pending_warnings;
|
String pending_warnings;
|
||||||
DECLARE_TYPEOF_COLLECTION(String);
|
DECLARE_TYPEOF_COLLECTION(String);
|
||||||
|
wxCriticalSection crit_error_handling;
|
||||||
|
|
||||||
void handle_error(const String& e, bool allow_duplicate = true, bool now = true) {
|
void handle_error(const String& e, bool allow_duplicate = true, bool now = true) {
|
||||||
|
// Thread safety
|
||||||
|
wxCriticalSectionLocker lock(crit_error_handling);
|
||||||
// Check duplicates
|
// Check duplicates
|
||||||
// TODO: thread safety
|
|
||||||
if (!allow_duplicate) {
|
if (!allow_duplicate) {
|
||||||
FOR_EACH(pe, previous_errors) {
|
FOR_EACH(pe, previous_errors) {
|
||||||
if (e == pe) return;
|
if (e == pe) return;
|
||||||
|
|||||||
@@ -26,12 +26,12 @@
|
|||||||
#define DECLARE_TYPEOF_COLLECTION(T)
|
#define DECLARE_TYPEOF_COLLECTION(T)
|
||||||
|
|
||||||
#define TYPEOF(Value) __typeof(Value)
|
#define TYPEOF(Value) __typeof(Value)
|
||||||
#define TYPEOF_IT(Value) __typeof(Value.begin())
|
#define TYPEOF_IT(Value) __typeof((Value).begin())
|
||||||
#define TYPEOF_CIT(Value) __typeof(Value.begin())
|
#define TYPEOF_CIT(Value) __typeof((Value).begin())
|
||||||
#define TYPEOF_RIT(Value) __typeof(Value.rbegin())
|
#define TYPEOF_RIT(Value) __typeof((Value).rbegin())
|
||||||
#define TYPEOF_CRIT(Value) __typeof(Value.rbegin())
|
#define TYPEOF_CRIT(Value) __typeof((Value).rbegin())
|
||||||
#define TYPEOF_REF(Value) __typeof(*Value.begin())&
|
#define TYPEOF_REF(Value) __typeof(*(Value).begin())&
|
||||||
#define TYPEOF_CREF(Value) __typeof(*Value.begin())&
|
#define TYPEOF_CREF(Value) __typeof(*(Value).begin())&
|
||||||
|
|
||||||
#else
|
#else
|
||||||
/// Helper for typeof tricks
|
/// Helper for typeof tricks
|
||||||
|
|||||||
+11
-2
@@ -43,8 +43,8 @@ class IndexMap : private vector<Value> {
|
|||||||
|
|
||||||
/// Initialize this map with default values given a list of keys
|
/// Initialize this map with default values given a list of keys
|
||||||
/** has no effect if already initialized with the given keys */
|
/** has no effect if already initialized with the given keys */
|
||||||
void init(const vector<Key>& keys) {
|
bool init(const vector<Key>& keys) {
|
||||||
if (this->size() == keys.size()) return;
|
if (this->size() == keys.size() && (this->empty() || get_key(this->front()) == keys.front())) return false;
|
||||||
this->reserve(keys.size());
|
this->reserve(keys.size());
|
||||||
for(typename vector<Key>::const_iterator it = keys.begin() ; it != keys.end() ; ++it) {
|
for(typename vector<Key>::const_iterator it = keys.begin() ; it != keys.end() ; ++it) {
|
||||||
const Key& key = *it;
|
const Key& key = *it;
|
||||||
@@ -52,6 +52,7 @@ class IndexMap : private vector<Value> {
|
|||||||
if (key->index >= this->size()) this->resize(key->index + 1);
|
if (key->index >= this->size()) this->resize(key->index + 1);
|
||||||
init_object(key, (*this)[key->index]);
|
init_object(key, (*this)[key->index]);
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
/// Initialize this map with cloned values from another list
|
/// Initialize this map with cloned values from another list
|
||||||
void cloneFrom(const IndexMap<Key,Value>& values) {
|
void cloneFrom(const IndexMap<Key,Value>& values) {
|
||||||
@@ -75,6 +76,14 @@ class IndexMap : private vector<Value> {
|
|||||||
assert(this->size() > key->index);
|
assert(this->size() > key->index);
|
||||||
return at(key->index);
|
return at(key->index);
|
||||||
}
|
}
|
||||||
|
/// Retrieve a value given its key, if it matches
|
||||||
|
inline Value tryGet (const Key& key) {
|
||||||
|
assert(key);
|
||||||
|
if (this->size() <= key->index) return Value();
|
||||||
|
Value v = at(key->index);
|
||||||
|
if (get_key(v) != key) return Value();
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
/// Is a value contained in this index map?
|
/// Is a value contained in this index map?
|
||||||
inline bool contains(const Value& value) const {
|
inline bool contains(const Value& value) const {
|
||||||
|
|||||||
Reference in New Issue
Block a user