Commit 5aadb4ed authored by twanvl's avatar twanvl

Choice images recomputed less often;

Implemented GraphType for choosing different layouts on the stats panel;
Added option to define order of graph groups;
Added busy cursor when loading recent file;
Parentheses in FOR_EACH macro
parent 5657dff3
...@@ -164,6 +164,7 @@ ChoiceStyle::ChoiceStyle(const ChoiceFieldP& field) ...@@ -164,6 +164,7 @@ ChoiceStyle::ChoiceStyle(const ChoiceFieldP& field)
: Style(field) : Style(field)
, popup_style(POPUP_DROPDOWN) , popup_style(POPUP_DROPDOWN)
, render_style(RENDER_TEXT) , render_style(RENDER_TEXT)
, choice_images_initialized(false)
, combine(COMBINE_NORMAL) , combine(COMBINE_NORMAL)
, alignment(ALIGN_STRETCH) , alignment(ALIGN_STRETCH)
, angle(0) , angle(0)
...@@ -179,10 +180,14 @@ bool ChoiceStyle::update(Context& ctx) { ...@@ -179,10 +180,14 @@ bool ChoiceStyle::update(Context& ctx) {
// Don't update the choice images, leave that to invalidate() // Don't update the choice images, leave that to invalidate()
bool change = Style ::update(ctx) bool change = Style ::update(ctx)
| mask_filename.update(ctx); | mask_filename.update(ctx);
FOR_EACH(ci, choice_images) { if (!choice_images_initialized) {
if (ci.second.update(ctx)) { // we only want to do this once because it is rather slow, other updates are handled by dependencies
change = true; choice_images_initialized = true;
// TODO : remove this thumbnail FOR_EACH(ci, choice_images) {
if (ci.second.update(ctx)) {
change = true;
// TODO : remove this thumbnail
}
} }
} }
return change; return change;
......
...@@ -133,6 +133,7 @@ class ChoiceStyle : public Style { ...@@ -133,6 +133,7 @@ class ChoiceStyle : public Style {
ChoiceRenderStyle render_style; ///< Style of rendering ChoiceRenderStyle render_style; ///< Style of rendering
Font font; ///< Font for drawing text (when RENDER_TEXT) Font font; ///< Font for drawing text (when RENDER_TEXT)
map<String,ScriptableImage> choice_images; ///< Images for the various choices (when RENDER_IMAGE) map<String,ScriptableImage> choice_images; ///< Images for the various choices (when RENDER_IMAGE)
bool choice_images_initialized;
Scriptable<String> mask_filename; ///< Filename of an additional mask over the images Scriptable<String> mask_filename; ///< Filename of an additional mask over the images
ImageCombine combine; ///< Combining mode for drawing the images ImageCombine combine; ///< Combining mode for drawing the images
Alignment alignment; ///< Alignment of images Alignment alignment; ///< Alignment of images
......
//+----------------------------------------------------------------------------+
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
//| Copyright: (C) 2001 - 2007 Twan van Laarhoven |
//| License: GNU General Public License 2 or later (see file COPYING) |
//+----------------------------------------------------------------------------+
#ifndef HEADER_DATA_GRAPH_TYPE
#define HEADER_DATA_GRAPH_TYPE
// ----------------------------------------------------------------------------- : Includes
#include <util/prec.hpp>
// ----------------------------------------------------------------------------- : GraphType
/// Types of graphs
enum GraphType
{ GRAPH_TYPE_BAR
, GRAPH_TYPE_PIE
, GRAPH_TYPE_STACK
, GRAPH_TYPE_SCATTER
};
// ----------------------------------------------------------------------------- : EOF
#endif
...@@ -29,10 +29,14 @@ StatsDimension::StatsDimension(const Field& field) ...@@ -29,10 +29,14 @@ StatsDimension::StatsDimension(const Field& field)
, numeric (false) , numeric (false)
, show_empty (false) , show_empty (false)
{ {
// choice colors? // choice field?
const ChoiceField* choice_field = dynamic_cast<const ChoiceField*>(&field); const ChoiceField* choice_field = dynamic_cast<const ChoiceField*>(&field);
if (choice_field) { if (choice_field) {
colors = choice_field->choice_colors; colors = choice_field->choice_colors;
int count = choice_field->choices->lastId();
for (int i = 0 ; i < count ; ++i) {
groups.push_back(choice_field->choices->choiceName(i));
}
} }
// initialize script, card.{field_name} // initialize script, card.{field_name}
Script& s = script.getScript(); Script& s = script.getScript();
...@@ -50,6 +54,7 @@ IMPLEMENT_REFLECTION_NO_GET_MEMBER(StatsDimension) { ...@@ -50,6 +54,7 @@ IMPLEMENT_REFLECTION_NO_GET_MEMBER(StatsDimension) {
REFLECT(numeric); REFLECT(numeric);
REFLECT(show_empty); REFLECT(show_empty);
REFLECT(colors); REFLECT(colors);
REFLECT(groups);
} }
} }
...@@ -69,13 +74,6 @@ StatsCategory::StatsCategory(const StatsDimensionP& dim) ...@@ -69,13 +74,6 @@ StatsCategory::StatsCategory(const StatsDimensionP& dim)
, type(GRAPH_TYPE_BAR) , type(GRAPH_TYPE_BAR)
{} {}
IMPLEMENT_REFLECTION_ENUM(GraphType) {
VALUE_N("bar", GRAPH_TYPE_BAR);
VALUE_N("stack", GRAPH_TYPE_STACK);
VALUE_N("pie", GRAPH_TYPE_PIE);
VALUE_N("scatter", GRAPH_TYPE_SCATTER);
}
IMPLEMENT_REFLECTION_NO_GET_MEMBER(StatsCategory) { IMPLEMENT_REFLECTION_NO_GET_MEMBER(StatsCategory) {
if (!automatic) { if (!automatic) {
REFLECT(name); REFLECT(name);
...@@ -102,4 +100,13 @@ void StatsCategory::find_dimensions(const vector<StatsDimensionP>& available) { ...@@ -102,4 +100,13 @@ void StatsCategory::find_dimensions(const vector<StatsDimensionP>& available) {
dimensions.push_back(dim); dimensions.push_back(dim);
} }
} }
} }
\ No newline at end of file
// ----------------------------------------------------------------------------- : GraphType (from graph_type.hpp)
IMPLEMENT_REFLECTION_ENUM(GraphType) {
VALUE_N("bar", GRAPH_TYPE_BAR);
VALUE_N("pie", GRAPH_TYPE_PIE);
VALUE_N("stack", GRAPH_TYPE_STACK);
VALUE_N("scatter", GRAPH_TYPE_SCATTER);
}
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <util/prec.hpp> #include <util/prec.hpp>
#include <util/reflect.hpp> #include <util/reflect.hpp>
#include <data/graph_type.hpp>
#include <script/scriptable.hpp> #include <script/scriptable.hpp>
class Field; class Field;
...@@ -34,20 +35,13 @@ class StatsDimension : public IntrusivePtrBase<StatsDimension> { ...@@ -34,20 +35,13 @@ class StatsDimension : public IntrusivePtrBase<StatsDimension> {
bool numeric; ///< Are the values numeric? If so, they require special sorting bool numeric; ///< Are the values numeric? If so, they require special sorting
bool show_empty; ///< Should "" be shown? bool show_empty; ///< Should "" be shown?
map<String,Color> colors; ///< Colors for the categories map<String,Color> colors; ///< Colors for the categories
vector<String> groups; ///< Order of the items
DECLARE_REFLECTION(); DECLARE_REFLECTION();
}; };
// ----------------------------------------------------------------------------- : Statistics category // ----------------------------------------------------------------------------- : Statistics category
/// Types of graphs
enum GraphType
{ GRAPH_TYPE_BAR
, GRAPH_TYPE_STACK
, GRAPH_TYPE_PIE
, GRAPH_TYPE_SCATTER
};
/// A category for statistics /// A category for statistics
/** Can be generated automatically based on a dimension */ /** Can be generated automatically based on a dimension */
class StatsCategory : public IntrusivePtrBase<StatsCategory> { class StatsCategory : public IntrusivePtrBase<StatsCategory> {
......
...@@ -17,6 +17,7 @@ DECLARE_TYPEOF_COLLECTION(GraphGroup); ...@@ -17,6 +17,7 @@ DECLARE_TYPEOF_COLLECTION(GraphGroup);
DECLARE_TYPEOF_COLLECTION(GraphP); DECLARE_TYPEOF_COLLECTION(GraphP);
DECLARE_TYPEOF_COLLECTION(int); DECLARE_TYPEOF_COLLECTION(int);
DECLARE_TYPEOF_COLLECTION(vector<int>); DECLARE_TYPEOF_COLLECTION(vector<int>);
DECLARE_TYPEOF_COLLECTION(String);
DECLARE_TYPEOF(map<String COMMA UInt>); DECLARE_TYPEOF(map<String COMMA UInt>);
template <typename T> inline T sgn(T v) { return v < 0 ? -1 : 1; } template <typename T> inline T sgn(T v) { return v < 0 ? -1 : 1; }
...@@ -48,7 +49,7 @@ GraphData::GraphData(const GraphDataPre& d) ...@@ -48,7 +49,7 @@ GraphData::GraphData(const GraphDataPre& d)
FOR_EACH_CONST(e, d.elements) { FOR_EACH_CONST(e, d.elements) {
counts[e->values[i]] += 1; counts[e->values[i]] += 1;
} }
// TODO: allow some ordering in the groups, and allow colors to be passed // TODO: allow some ordering in the groups
if (a->numeric) { if (a->numeric) {
// TODO: start at something other than 0? // TODO: start at something other than 0?
// TODO: support fractions? // TODO: support fractions?
...@@ -75,6 +76,14 @@ GraphData::GraphData(const GraphDataPre& d) ...@@ -75,6 +76,14 @@ GraphData::GraphData(const GraphDataPre& d)
break; break;
} }
} }
} else if (a->order) {
// specific group order
FOR_EACH_CONST(gn, *a->order) {
UInt count = counts[gn];
a->groups.push_back(GraphGroup(gn, count));
a->max = max(a->max, count);
a->total += count;
}
} else { } else {
FOR_EACH(c, counts) { FOR_EACH(c, counts) {
a->groups.push_back(GraphGroup(c.first, c.second)); a->groups.push_back(GraphGroup(c.first, c.second));
...@@ -175,19 +184,16 @@ RealRect bar_graph_bar(const RealRect& rect, int group, int group_count, int sta ...@@ -175,19 +184,16 @@ RealRect bar_graph_bar(const RealRect& rect, int group, int group_count, int sta
double width = width_space / 5 * 4; double width = width_space / 5 * 4;
double space = width_space / 5; double space = width_space / 5;
double step_height = rect.height / max; // multiplier for bar height double step_height = rect.height / max; // multiplier for bar height
double top = rect.bottom() + 1 - start * step_height; int top = rect.bottom() - start * step_height;
double bottom = rect.bottom() - end * step_height; int bottom = rect.bottom() - end * step_height;
RealRect result( if (bottom < top) swap(top,bottom);
bottom += 1;
return RealRect(
rect.x + width_space * group + space / 2, rect.x + width_space * group + space / 2,
top, top,
width, width,
(int)bottom - top bottom - top
); );
if (result.height < 0) {
result.height = -result.height;
result.y -= result.height;
}
return result;
} }
/// Which column of the bar graph with count bars is coordinate x in? /// Which column of the bar graph with count bars is coordinate x in?
int find_bar_graph_column(double width, double x, int count) { int find_bar_graph_column(double width, double x, int count) {
...@@ -251,6 +257,28 @@ void BarGraph2D::draw(RotatedDC& dc, const vector<int>& current, DrawLayer layer ...@@ -251,6 +257,28 @@ void BarGraph2D::draw(RotatedDC& dc, const vector<int>& current, DrawLayer layer
// Bar sizes // Bar sizes
if (layer == LAYER_SELECTION) { if (layer == LAYER_SELECTION) {
// Highlight current column // Highlight current column
Color bg = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
int cur1 = this->axis1 < current.size() ? current[this->axis1] : -1;
int cur2 = this->axis2 < current.size() ? current[this->axis2] : -1;
if (cur1 >= 0) {
// draw that bar
int start = 0;
int j = 0;
FOR_EACH_CONST(g2, axis2.groups) {
int end = start + values[j + axis2.groups.size() * cur1];
if (j == cur2 || cur2 < 0) {
RealRect bar = bar_graph_bar(rect, cur1, count, start, end, axis1.max);
dc.SetBrush(lerp(bg, g2.color, 0.25));
dc.DrawRectangle(bar.move(-5,0,10,0));
dc.SetBrush(lerp(bg, g2.color, 0.5));
dc.DrawRectangle(bar.move(-2,0,4,0));
}
start = end;
++j;
}
} else if (cur2 >= 0) {
// entire row
}
// TODO // TODO
} else if (layer == LAYER_VALUES) { } else if (layer == LAYER_VALUES) {
// Draw bars // Draw bars
...@@ -276,6 +304,7 @@ bool BarGraph2D::findItem(const RealPoint& pos, const RealRect& rect, vector<int ...@@ -276,6 +304,7 @@ bool BarGraph2D::findItem(const RealPoint& pos, const RealRect& rect, vector<int
GraphAxis& axis1 = axis1_data(); // the major axis GraphAxis& axis1 = axis1_data(); // the major axis
int count = (int)axis1.groups.size(); int count = (int)axis1.groups.size();
int col = find_bar_graph_column(rect.width, pos.x - rect.x, count); int col = find_bar_graph_column(rect.width, pos.x - rect.x, count);
if (col < 0) return false;
// row // row
int max_value = (int)axis1.max; int max_value = (int)axis1.max;
int value = (rect.bottom() - pos.y) / rect.height * max_value; int value = (rect.bottom() - pos.y) / rect.height * max_value;
...@@ -503,18 +532,39 @@ void GraphContainer::add(const GraphP& graph) { ...@@ -503,18 +532,39 @@ void GraphContainer::add(const GraphP& graph) {
GraphControl::GraphControl(Window* parent, int id) GraphControl::GraphControl(Window* parent, int id)
: wxControl(parent, id) : wxControl(parent, id)
{ {
//* setLayout(GRAPH_TYPE_BAR);
intrusive_ptr<GraphContainer> combined(new GraphContainer()); }
combined->add(new_intrusive1<GraphValueAxis>(0));
combined->add(new_intrusive2<GraphLabelAxis>(0, HORIZONTAL)); void GraphControl::setLayout(GraphType type) {
//combined->add(new_intrusive1<BarGraph>(0)); if (type == layout) return;
combined->add(new_intrusive2<BarGraph2D>(0,1)); GraphDataP data = graph ? graph->getData() : GraphDataP();
graph = new_intrusive6<GraphWithMargins>(combined, 23,8,7,20, false); switch (type) {
/*/ case GRAPH_TYPE_BAR: {
intrusive_ptr<GraphContainer> combined(new GraphContainer()); intrusive_ptr<GraphContainer> combined(new GraphContainer());
combined->add(new_intrusive1<PieGraph>(0)); combined->add(new_intrusive1<GraphValueAxis>(0));
graph = new_intrusive6<GraphWithMargins>(combined, 20,20,20,20, false); combined->add(new_intrusive2<GraphLabelAxis>(0, HORIZONTAL));
//*/ combined->add(new_intrusive1<BarGraph>(0));
graph = new_intrusive5<GraphWithMargins>(combined, 23,8,7,20);
break;
} case GRAPH_TYPE_PIE: {
intrusive_ptr<GraphContainer> combined(new GraphContainer());
combined->add(new_intrusive1<PieGraph>(0));
graph = new_intrusive5<GraphWithMargins>(combined, 20,20,20,20);
break;
} case GRAPH_TYPE_STACK: {
intrusive_ptr<GraphContainer> combined(new GraphContainer());
combined->add(new_intrusive1<GraphValueAxis>(0));
combined->add(new_intrusive2<GraphLabelAxis>(0, HORIZONTAL));
combined->add(new_intrusive2<BarGraph2D>(0,1));
graph = new_intrusive5<GraphWithMargins>(combined, 23,8,7,20);
break;
} case GRAPH_TYPE_SCATTER: {
// TODO
} default:
graph = GraphP();
}
if (data && graph) graph->setData(data);
layout = type;
} }
void GraphControl::setData(const GraphDataPre& data) { void GraphControl::setData(const GraphDataPre& data) {
...@@ -560,8 +610,8 @@ bool GraphControl::hasSelection(size_t axis) const { ...@@ -560,8 +610,8 @@ bool GraphControl::hasSelection(size_t axis) const {
return axis < current_item.size() && current_item[axis] >= 0; return axis < current_item.size() && current_item[axis] >= 0;
} }
String GraphControl::getSelection(size_t axis) const { String GraphControl::getSelection(size_t axis) const {
if (!graph || axis >= current_item.size() || axis >= graph->getData().axes.size()) return wxEmptyString; if (!graph || axis >= current_item.size() || axis >= graph->getData()->axes.size()) return wxEmptyString;
GraphAxis& a = *graph->getData().axes[axis]; GraphAxis& a = *graph->getData()->axes[axis];
int i = current_item[axis]; int i = current_item[axis];
if (i == -1 || (size_t)i >= a.groups.size()) return wxEmptyString; if (i == -1 || (size_t)i >= a.groups.size()) return wxEmptyString;
return a.groups[current_item[axis]].name; return a.groups[current_item[axis]].name;
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <util/prec.hpp> #include <util/prec.hpp>
#include <util/alignment.hpp> #include <util/alignment.hpp>
#include <util/rotation.hpp> #include <util/rotation.hpp>
#include <data/graph_type.hpp>
DECLARE_POINTER_TYPE(GraphAxis); DECLARE_POINTER_TYPE(GraphAxis);
DECLARE_POINTER_TYPE(GraphElement); DECLARE_POINTER_TYPE(GraphElement);
...@@ -51,13 +52,14 @@ enum AutoColor ...@@ -51,13 +52,14 @@ enum AutoColor
/** The sum of groups.sum = sum of all elements in the data */ /** The sum of groups.sum = sum of all elements in the data */
class GraphAxis : public IntrusivePtrBase<GraphAxis> { class GraphAxis : public IntrusivePtrBase<GraphAxis> {
public: public:
GraphAxis(const String& name, AutoColor auto_color = AUTO_COLOR_EVEN, bool numeric = false, const map<String,Color>* colors = nullptr) GraphAxis(const String& name, AutoColor auto_color = AUTO_COLOR_EVEN, bool numeric = false, const map<String,Color>* colors = nullptr, const vector<String>* order = nullptr)
: name(name) : name(name)
, auto_color(auto_color) , auto_color(auto_color)
, numeric(numeric) , numeric(numeric)
, max(0) , max(0)
, total(0) , total(0)
, colors(colors) , colors(colors)
, order(order)
{} {}
String name; ///< Name/label of this axis String name; ///< Name/label of this axis
...@@ -66,7 +68,8 @@ class GraphAxis : public IntrusivePtrBase<GraphAxis> { ...@@ -66,7 +68,8 @@ class GraphAxis : public IntrusivePtrBase<GraphAxis> {
bool numeric; ///< Numeric axis? bool numeric; ///< Numeric axis?
UInt max; ///< Maximum size of the groups UInt max; ///< Maximum size of the groups
UInt total; ///< Sum of the size of all groups UInt total; ///< Sum of the size of all groups
const map<String,Color>* colors; ///< Colors for each choice (optional const map<String,Color>* colors; ///< Colors for each choice (optional)
const vector<String>* order; ///< Order of the items (optional)
}; };
/// A single data point of a graph /// A single data point of a graph
...@@ -121,7 +124,7 @@ class Graph : public IntrusivePtrVirtualBase { ...@@ -121,7 +124,7 @@ class Graph : public IntrusivePtrVirtualBase {
/// Change the data /// Change the data
virtual void setData(const GraphDataP& d) { data = d; } virtual void setData(const GraphDataP& d) { data = d; }
/// Get the data /// Get the data
inline const GraphData& getData() const { return *data; } inline const GraphDataP& getData() const { return data; }
protected: protected:
/// Data of the graph /// Data of the graph
...@@ -251,7 +254,7 @@ class GraphControl : public wxControl { ...@@ -251,7 +254,7 @@ class GraphControl : public wxControl {
GraphControl(Window* parent, int id); GraphControl(Window* parent, int id);
/// Set the type of graph used, from a number of predefined choices /// Set the type of graph used, from a number of predefined choices
void setLayout(); void setLayout(GraphType type);
/// Update the data in the graph /// Update the data in the graph
void setData(const GraphDataPre& data); void setData(const GraphDataPre& data);
/// Update the data in the graph /// Update the data in the graph
...@@ -265,6 +268,7 @@ class GraphControl : public wxControl { ...@@ -265,6 +268,7 @@ class GraphControl : public wxControl {
private: private:
/// Graph object /// Graph object
GraphP graph; GraphP graph;
GraphType layout; /// < The current layout
/// The selected item per axis, or an empty vector if there is no selection /// The selected item per axis, or an empty vector if there is no selection
/** If the value for an axis is -1, then all groups on that axis are selected */ /** If the value for an axis is -1, then all groups on that axis are selected */
vector<int> current_item; vector<int> current_item;
......
...@@ -150,11 +150,12 @@ void StatsPanel::onCategorySelect() { ...@@ -150,11 +150,12 @@ void StatsPanel::onCategorySelect() {
cat.find_dimensions(set->game->statistics_dimensions); cat.find_dimensions(set->game->statistics_dimensions);
// create axes // create axes
FOR_EACH(dim, cat.dimensions) { FOR_EACH(dim, cat.dimensions) {
d.axes.push_back(new_intrusive4<GraphAxis>( d.axes.push_back(new_intrusive5<GraphAxis>(
dim->name, dim->name,
dim->colors.empty() ? AUTO_COLOR_EVEN : AUTO_COLOR_NO, dim->colors.empty() ? AUTO_COLOR_EVEN : AUTO_COLOR_NO,
dim->numeric, dim->numeric,
&dim->colors &dim->colors,
dim->groups.empty() ? nullptr : &dim->groups
) )
); );
} }
...@@ -176,7 +177,7 @@ void StatsPanel::onCategorySelect() { ...@@ -176,7 +177,7 @@ void StatsPanel::onCategorySelect() {
d.elements.push_back(e); d.elements.push_back(e);
} }
} }
// TODO graph->setLayout(cat.type) graph->setLayout(cat.type);
graph->setData(d); graph->setData(d);
filterCards(); filterCards();
} }
......
...@@ -489,6 +489,7 @@ void SetWindow::onFileReload(wxCommandEvent&) { ...@@ -489,6 +489,7 @@ void SetWindow::onFileReload(wxCommandEvent&) {
} }
void SetWindow::onFileRecent(wxCommandEvent& ev) { void SetWindow::onFileRecent(wxCommandEvent& ev) {
wxBusyCursor busy;
setSet(import_set(settings.recent_sets.at(ev.GetId() - ID_FILE_RECENT))); setSet(import_set(settings.recent_sets.at(ev.GetId() - ID_FILE_RECENT)));
} }
......
...@@ -1798,6 +1798,9 @@ ...@@ -1798,6 +1798,9 @@
<File <File
RelativePath=".\data\font.hpp"> RelativePath=".\data\font.hpp">
</File> </File>
<File
RelativePath=".\data\graph_type.hpp">
</File>
<File <File
RelativePath=".\data\installer.cpp"> RelativePath=".\data\installer.cpp">
</File> </File>
...@@ -3209,10 +3212,10 @@ ...@@ -3209,10 +3212,10 @@
RelativePath="..\conversion-todo.txt"> RelativePath="..\conversion-todo.txt">
</File> </File>
<File <File
RelativePath="..\data\en.mse-locale\locale"> RelativePath="..\data\nl.mse-locale\locale">
</File> </File>
<File <File
RelativePath="..\data\nl.mse-locale\locale"> RelativePath="..\data\en.mse-locale\locale">
</File> </File>
<File <File
RelativePath=".\main.cpp"> RelativePath=".\main.cpp">
......
...@@ -104,8 +104,8 @@ ...@@ -104,8 +104,8 @@
/** Usage: FOR_EACH_IT_T(Type,it,collect) { body-of-loop } /** Usage: FOR_EACH_IT_T(Type,it,collect) { body-of-loop }
*/ */
#define FOR_EACH_IT_T(Type,Iterator,Collection) \ #define FOR_EACH_IT_T(Type,Iterator,Collection) \
for(Type Iterator = Collection.begin() ; \ for(Type Iterator = (Collection).begin() ; \
Iterator != Collection.end() ; \ Iterator != (Collection).end() ; \
++Iterator) ++Iterator)
/// Iterate over a collection whos type must be declared with DECLARE_TYPEOF /// Iterate over a collection whos type must be declared with DECLARE_TYPEOF
...@@ -127,8 +127,8 @@ ...@@ -127,8 +127,8 @@
*/ */
#define FOR_EACH_REVERSE_IT(Iterator,Collection) \ #define FOR_EACH_REVERSE_IT(Iterator,Collection) \
for(TYPEOF_RIT(Collection) \ for(TYPEOF_RIT(Collection) \
Iterator = Collection.rbegin() ; \ Iterator = (Collection).rbegin() ; \
Iterator != Collection.rend() ; \ Iterator != (Collection).rend() ; \
++Iterator) ++Iterator)
// ----------------------------------------------------------------------------- : Looping macros // ----------------------------------------------------------------------------- : Looping macros
...@@ -141,8 +141,8 @@ ...@@ -141,8 +141,8 @@
* To terminate this loop we need an extra bool, which we set to false after the first iteration. * To terminate this loop we need an extra bool, which we set to false after the first iteration.
*/ */
#define FOR_EACH_T(TypeIt,TypeElem,Elem,Collection, begin, end) \ #define FOR_EACH_T(TypeIt,TypeElem,Elem,Collection, begin, end) \
for(std::pair<TypeIt,bool> Elem##_IT(Collection.begin(), true) ; \ for(std::pair<TypeIt,bool> Elem##_IT((Collection).begin(), true) ; \
Elem##_IT.second && Elem##_IT.first != Collection.end() ; \ Elem##_IT.second && Elem##_IT.first != (Collection).end() ; \
++Elem##_IT.first, Elem##_IT.second = !Elem##_IT.second) \ ++Elem##_IT.first, Elem##_IT.second = !Elem##_IT.second) \
for(TypeElem Elem = *Elem##_IT.first ; \ for(TypeElem Elem = *Elem##_IT.first ; \
Elem##_IT.second ; \ Elem##_IT.second ; \
...@@ -183,9 +183,9 @@ ...@@ -183,9 +183,9 @@
*/ */
#define FOR_EACH_2_T(TypeIt1,TypeElem1,Elem1,Coll1,TypeIt2,TypeElem2,Elem2,Coll2) \ #define FOR_EACH_2_T(TypeIt1,TypeElem1,Elem1,Coll1,TypeIt2,TypeElem2,Elem2,Coll2) \
for(std::pair<std::pair<TypeIt1,TypeIt2>, bool> \ for(std::pair<std::pair<TypeIt1,TypeIt2>, bool> \
Elem1##_IT(make_pair(Coll1.begin(), Coll2.begin()), true) ; \ Elem1##_IT(make_pair((Coll1).begin(), (Coll2).begin()), true) ; \
Elem1##_IT.first.first != Coll1.end() && \ Elem1##_IT.first.first != (Coll1).end() && \
Elem1##_IT.first.second != Coll2.end() ; \ Elem1##_IT.first.second != (Coll2).end() ; \
++Elem1##_IT.first.first, ++Elem1##_IT.first.second, \ ++Elem1##_IT.first.first, ++Elem1##_IT.first.second, \
Elem1##_IT.second = true) \ Elem1##_IT.second = true) \
for(TypeElem1 Elem1 = *Elem1##_IT.first.first ; \ for(TypeElem1 Elem1 = *Elem1##_IT.first.first ; \
......
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