Commit d71b9cf6 authored by twanvl's avatar twanvl

Some more data types; dynamic arguments

parent 198c01c4
......@@ -324,7 +324,6 @@ void SinglePointRemoveAction::perform(bool toUndo) {
}
DECLARE_POINTER_TYPE(SinglePointRemoveAction);
DECLARE_TYPEOF_COLLECTION(SinglePointRemoveActionP);
// Remove a set of points from a symbol part.
......
//+----------------------------------------------------------------------------+
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
//| Copyright: (C) 2001 - 2006 Twan van Laarhoven |
//| License: GNU General Public License 2 or later (see file COPYING) |
//+----------------------------------------------------------------------------+
// ----------------------------------------------------------------------------- : Includes
#include <data/card.hpp>
#include <data/game.hpp>
#include <data/field.hpp>
#include <util/error.hpp>
// ----------------------------------------------------------------------------- : Card
IMPLEMENT_DYNAMIC_ARG(Game*, game_for_new_cards, nullptr);
Card::Card() {
if (!game_for_new_cards()) {
throw InternalError(_("game_for_new_cards not set"));
}
data.init(game_for_new_cards()->cardFields);
}
Card::Card(const Game& game) {
data.init(game.cardFields);
}
String Card::identification() const {
return _("TODO");
}
IMPLEMENT_REFLECTION(Card) {
REFLECT(notes);
}
//+----------------------------------------------------------------------------+
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
//| Copyright: (C) 2001 - 2006 Twan van Laarhoven |
//| License: GNU General Public License 2 or later (see file COPYING) |
//+----------------------------------------------------------------------------+
#ifndef HEADER_DATA_CARD
#define HEADER_DATA_CARD
// ----------------------------------------------------------------------------- : Includes
#include <util/string.hpp>
#include <util/reflect.hpp>
#include <util/dynamic_arg.hpp>
class Game;
DECLARE_POINTER_TYPE(Field);
DECLARE_POINTER_TYPE(Value);
DECLARE_POINTER_TYPE(CardStyle);
// ----------------------------------------------------------------------------- : Card
/// Game that is used for cards constructed with the default constructor
DECLARE_DYNAMIC_ARG(Game*, game_for_new_cards);
/// A card from a card Set
class Card {
public:
/// Default constructor, uses game_for_new_cards to make the game
Card();
/// Creates a card using the given game
Card(const Game& game);
/// Get an identification of the card, an identification is something like a name, title, etc.
String identification() const;
private:
/// The values on the fields of the card
/// The indices should correspond to the cardFields in the Game
IndexMap<FieldP, ValueP> data;
/// Notes for this card
String notes;
/// Alternative style to use for this card
/// Optional, if not set use the card style from the set
CardStyleP style;
DECLARE_REFLECTION();
};
// ----------------------------------------------------------------------------- : EOF
#endif
//+----------------------------------------------------------------------------+
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
//| Copyright: (C) 2001 - 2006 Twan van Laarhoven |
//| License: GNU General Public License 2 or later (see file COPYING) |
//+----------------------------------------------------------------------------+
// ----------------------------------------------------------------------------- : Includes
#include <data/field.hpp>
// ----------------------------------------------------------------------------- : Field
// ----------------------------------------------------------------------------- : Value
void initObject(const FieldP& field, ValueP& value) {
value = new_shared<Value>();
}
//+----------------------------------------------------------------------------+
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
//| Copyright: (C) 2001 - 2006 Twan van Laarhoven |
//| License: GNU General Public License 2 or later (see file COPYING) |
//+----------------------------------------------------------------------------+
#ifndef HEADER_DATA_FIELD
#define HEADER_DATA_FIELD
// ----------------------------------------------------------------------------- : Includes
#include <util/prec.hpp>
#ifndef HEADER_DATA_CARD
DECLARE_POINTER_TYPE(Field);
DECLARE_POINTER_TYPE(Value);
#endif
// ----------------------------------------------------------------------------- : Field
class Field {
public:
UInt index; // used by IndexMap
};
class Value {
};
void initObject(const FieldP&, ValueP&);
// ----------------------------------------------------------------------------- : EOF
#endif
//+----------------------------------------------------------------------------+
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
//| Copyright: (C) 2001 - 2006 Twan van Laarhoven |
//| License: GNU General Public License 2 or later (see file COPYING) |
//+----------------------------------------------------------------------------+
// ----------------------------------------------------------------------------- : Includes
#include <data/game.hpp>
// ----------------------------------------------------------------------------- : Game
//+----------------------------------------------------------------------------+
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
//| Copyright: (C) 2001 - 2006 Twan van Laarhoven |
//| License: GNU General Public License 2 or later (see file COPYING) |
//+----------------------------------------------------------------------------+
#ifndef HEADER_DATA_GAME
#define HEADER_DATA_GAME
// ----------------------------------------------------------------------------- : Includes
#include <util/prec.hpp>
#ifndef HEADER_DATA_CARD
DECLARE_POINTER_TYPE(Field);
#endif
// ----------------------------------------------------------------------------- : Game
class Game {
public:
String fullName;
String iconFilename;
vector<FieldP> setFields;
vector<FieldP> cardFields;
};
// ----------------------------------------------------------------------------- : EOF
#endif
//+----------------------------------------------------------------------------+
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
//| Copyright: (C) 2001 - 2006 Twan van Laarhoven |
//| License: GNU General Public License 2 or later (see file COPYING) |
//+----------------------------------------------------------------------------+
// ----------------------------------------------------------------------------- : Includes
#include <data/set.hpp>
#include <data/card.hpp>
// ----------------------------------------------------------------------------- : Set
IMPLEMENT_REFLECTION(Set) {
WITH_DYNAMIC_ARG(game_for_new_cards, game.get()) {
REFLECT_N("card", cards);
}
}
// ----------------------------------------------------------------------------- : SetView
SetView::SetView() {}
SetView::~SetView() {
if (set) set->actions.removeListener(this);
}
void SetView::setSet(const SetP& newSet) {
// no longer listening to old set
if (set) set->actions.removeListener(this);
set = newSet;
// start listening to new set
if (set) set->actions.addListener(this);
onChangeSet();
}
//+----------------------------------------------------------------------------+
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
//| Copyright: (C) 2001 - 2006 Twan van Laarhoven |
//| License: GNU General Public License 2 or later (see file COPYING) |
//+----------------------------------------------------------------------------+
#ifndef HEADER_DATA_SET
#define HEADER_DATA_SET
// ----------------------------------------------------------------------------- : Includes
#include <util/prec.hpp>
#include <util/reflect.hpp>
#include <util/action_stack.hpp>
DECLARE_POINTER_TYPE(Card);
DECLARE_POINTER_TYPE(Set);
DECLARE_POINTER_TYPE(Game);
// ----------------------------------------------------------------------------- : Set
/// A set of cards
class Set {
public:
/// The game this set uses
GameP game;
/// The cards in the set
vector<CardP> cards;
/// Actions performed on this set and the cards in it
ActionStack actions;
DECLARE_REFLECTION();
};
// ----------------------------------------------------------------------------- : SetView
/// A 'view' of a Set, is notified when the Set is updated
/** To listen to events, derived classes should override onAction(const Action&)
*/
class SetView : public ActionListener {
public:
SetView();
~SetView();
/// Get the set that is currently being viewed
inline SetP getSet() { return set; }
/// Change the set that is being viewed
void setSet(const SetP& set);
protected:
/// The set that is currently being viewed, should not be modified directly!
SetP set;
/// Called when another set is being viewn (using setSet)
virtual void onChangeSet() {}
};
// ----------------------------------------------------------------------------- : EOF
#endif
......@@ -163,21 +163,15 @@ IMPLEMENT_REFLECTION(Symbol) {
SymbolView::SymbolView() {}
SymbolView::SymbolView(SymbolP symbol)
: symbol(symbol)
{
if (symbol) symbol->actions.addListener(this);
}
SymbolView::~SymbolView() {
if (symbol) symbol->actions.removeListener(this);
}
void SymbolView::setSymbol(SymbolP newSymbol) {
void SymbolView::setSymbol(const SymbolP& newSymbol) {
// no longer listening to old symbol
if (symbol) symbol->actions.removeListener(this);
symbol = newSymbol;
// start listening to new symbol
if (symbol) symbol->actions.addListener(this);
onSymbolChange();
onChangeSymbol();
}
......@@ -17,8 +17,6 @@
DECLARE_POINTER_TYPE(ControlPoint);
DECLARE_POINTER_TYPE(SymbolPart);
DECLARE_POINTER_TYPE(Symbol);
DECLARE_TYPEOF_COLLECTION(ControlPointP);
DECLARE_TYPEOF_COLLECTION(SymbolPartP);
// ----------------------------------------------------------------------------- : ControlPoint
......@@ -168,23 +166,24 @@ class Symbol {
// ----------------------------------------------------------------------------- : SymbolView
/// A 'view' of a symbol, is notified when the symbol is updated
/** To listen to events, derived classes should override onAction(const Action&)
*/
class SymbolView : public ActionListener {
public:
SymbolView();
SymbolView(SymbolP symbol);
~SymbolView();
/// Get the symbol that is currently being viewed
inline SymbolP getSymbol() { return symbol; }
/// Change the symbol that is being viewed
void setSymbol(SymbolP symbol);
void setSymbol(const SymbolP& symbol);
protected:
/// The symbol that is currently being viewed, should not be modified directly!
SymbolP symbol;
/// Called when the associated symbol is changed, but not when it is initially set!
virtual void onSymbolChange() {}
/// Called when another symbol is being viewn (using setSymbol)
virtual void onChangeSymbol() {}
};
......
......@@ -24,7 +24,7 @@ SymbolControl::SymbolControl(SymbolWindow* parent, int id, const SymbolP& symbol
, SymbolViewer(symbol)
, parent(parent)
{
switchEditor(new_shared2<SymbolSelectEditor>(this, false));
onChangeSymbol();
}
void SymbolControl::switchEditor(const SymbolEditorBaseP& e) {
......@@ -34,7 +34,7 @@ void SymbolControl::switchEditor(const SymbolEditorBaseP& e) {
Refresh(false);
}
void SymbolControl::onSymbolChange() {
void SymbolControl::onChangeSymbol() {
selectedParts.clear();
switchEditor(new_shared2<SymbolSelectEditor>(this, false));
Refresh(false);
......
......@@ -26,7 +26,7 @@ class SymbolControl : public wxControl, public SymbolViewer {
public:
SymbolControl(SymbolWindow* parent, int id, const SymbolP& symbol);
virtual void onSymbolChange();
virtual void onChangeSymbol();
virtual void onAction(const Action&);
......
......@@ -43,9 +43,9 @@ class SymbolEditorBase {
// --------------------------------------------------- : UI
/// Init extra toolbar items and menus needed for this panel
/// Init extra toolbar items and menus needed for this editor
virtual void initUI(wxToolBar* tb, wxMenuBar* mb) {}
/// Destroy the extra items added by initUI
/// Destroy the extra items added by initUI.
virtual void destroyUI(wxToolBar* tb, wxMenuBar* mb) {}
/// Update the UI by enabling/disabling items
virtual void onUpdateUI(wxUpdateUIEvent& ev) {}
......
......@@ -16,7 +16,6 @@
SymbolPartList::SymbolPartList(Window* parent, int id, SymbolP symbol)
: wxListCtrl(parent, id, wxDefaultPosition, wxDefaultSize,
wxLC_REPORT | wxLC_NO_HEADER | wxLC_VIRTUAL | wxLC_EDIT_LABELS)
, SymbolView(symbol)
{
// Create image list
wxImageList* images = new wxImageList(16,16);
......@@ -30,12 +29,13 @@ SymbolPartList::SymbolPartList(Window* parent, int id, SymbolP symbol)
AssignImageList(images, wxIMAGE_LIST_SMALL);
// create columns
InsertColumn(0, _("Name"));
update();
// view symbol
setSymbol(symbol);
}
// ----------------------------------------------------------------------------- : View events
void SymbolPartList::onSymbolChange() {
void SymbolPartList::onChangeSymbol() {
update();
}
......
......@@ -36,7 +36,7 @@ class SymbolPartList : public wxListCtrl, public SymbolView {
void selectParts(const set<SymbolPartP>& sel);
/// Another symbol is being viewed
void onSymbolChange();
void onChangeSymbol();
/// Event handler for changes to the symbol
virtual void onAction(const Action& a);
......
......@@ -12,9 +12,10 @@
SymbolViewer::SymbolViewer(const SymbolP& symbol, double borderRadius)
: borderRadius(borderRadius)
, SymbolView(symbol)
, rotation(0, RealRect(0,0,500,500))
{}
{
setSymbol(symbol);
}
// ----------------------------------------------------------------------------- : Drawing
......
......@@ -15,34 +15,6 @@
#include <wx/filename.h>
#include <wx/wfstream.h>
// ----------------------------------------------------------------------------- : Window ids
enum SymIDs
{ idFileNew = wxID_NEW
, idFileOpen = wxID_OPEN
, idFileSave = wxID_SAVE
, idFileSaveAs = wxID_SAVEAS
, idFileStore = 0
, idFileExit = wxID_EXIT
, idExtraTools = 1000
, idExtraToolsMax = idExtraTools + 500
, idEditUndo = wxID_UNDO
, idEditRedo = wxID_REDO
, idEditDuplicate = 1100 // idExtraTools + 100
, idModeSelect = idFileStore + 1
, idModeRotate
, idModePoints
, idModeShapes
, idModePaint
, idModeMax
, idPartList
, idControl
};
// ------------------------------------------------------------------------------------------------ : Default symbol
// A default symbol part, a square, moved by d
......@@ -218,17 +190,17 @@ void SymbolWindow::onExtraTool(wxCommandEvent& ev) {
void SymbolWindow::onUpdateUI(wxUpdateUIEvent& ev) {
switch(ev.GetId()) {
// file menu
case idFileStore: {
case ID_FILE_STORE: {
// ev.Enable(value);
break;
// undo/redo
} case idEditUndo: {
} case ID_EDIT_UNDO: {
ev.Enable(control->getSymbol()->actions.canUndo());
String label = control->getSymbol()->actions.undoName();
ev.SetText(label + _("\tCtrl+Z"));
GetToolBar()->SetToolShortHelp(ID_EDIT_UNDO, label);
break;
} case idEditRedo: {
} case ID_EDIT_REDO: {
ev.Enable(control->getSymbol()->actions.canRedo());
String label = control->getSymbol()->actions.redoName();
ev.SetText(label + _("\tF4"));
......
......@@ -320,28 +320,22 @@
RelativePath=".\gui\util.hpp">
</File>
<Filter
Name="main"
Name="set"
Filter="">
<File
RelativePath=".\gui\main\panel.hpp">
RelativePath=".\gui\set\panel.hpp">
</File>
<File
RelativePath=".\gui\main\window.cpp">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)/$(InputName)1.obj"/>
</FileConfiguration>
<FileConfiguration
Name="Release Unicode|Win32">
<Tool
Name="VCCLCompilerTool"
ObjectFile="$(IntDir)/$(InputName)1.obj"/>
</FileConfiguration>
RelativePath=".\gui\set\stats_panel.cpp">
</File>
<File
RelativePath=".\gui\set\stats_panel.hpp">
</File>
<File
RelativePath=".\gui\set\window.cpp">
</File>
<File
RelativePath=".\gui\main\window.hpp">
RelativePath=".\gui\set\window.hpp">
</File>
</Filter>
<Filter
......@@ -534,21 +528,33 @@
<Filter
Name="data"
Filter="">
<File
RelativePath=".\data\card.cpp">
</File>
<File
RelativePath=".\data\card.hpp">
</File>
<File
RelativePath=".\data\card_style.hpp">
</File>
<File
RelativePath=".\data\field.cpp">
</File>
<File
RelativePath=".\data\field.hpp">
</File>
<File
RelativePath=".\data\game.cpp">
</File>
<File
RelativePath=".\data\game.hpp">
</File>
<File
RelativePath=".\data\locale.hpp">
</File>
<File
RelativePath=".\data\set.cpp">
</File>
<File
RelativePath=".\data\set.hpp">
</File>
......@@ -632,6 +638,9 @@
<File
RelativePath=".\util\action_stack.hpp">
</File>
<File
RelativePath=".\util\dynamic_arg.hpp">
</File>
<File
RelativePath=".\util\error.cpp">
</File>
......
//+----------------------------------------------------------------------------+
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
//| Copyright: (C) 2001 - 2006 Twan van Laarhoven |
//| License: GNU General Public License 2 or later (see file COPYING) |
//+----------------------------------------------------------------------------+
#ifndef HEADER_UTIL_DYNAMIC_ARG
#define HEADER_UTIL_DYNAMIC_ARG
/** @file util/dynamic_arg.hpp
*
* @brief Support for 'dynamicly scopped' arguments.
* This header
*/
// ----------------------------------------------------------------------------- : Includes
#include <util/prec.hpp>
// ----------------------------------------------------------------------------- : Dynamic argument
#ifdef _MSC_VER
# define THREAD_LOCAL __declspec(thread)
#else
# define THREAD_LOCAL __thread
#endif
/// Declare a dynamic argument.
/** The value of the argument can be got with: name()
* To change the value use WITH_DYNAMIC_ARG(name, newValue) { ... }
* To be used in a header file. Use IMPLEMENT_DYN_ARG in a source file
*/
#define DECLARE_DYNAMIC_ARG(Type, name) \
extern THREAD_LOCAL Type name##_private; \
inline Type name() { return name##_private; } \
class name##_changer { \
public: \
inline name##_changer(Type const& newValue) \
: oldValue(name##_private) { \
name##_private = newValue; \
} \
inline ~name##_changer() { \
name##_private = oldValue; \
} \
inline operator bool() { return true; } \
private: \
Type oldValue; \
}
/// Implementation of a dynamic argument
#define IMPLEMENT_DYNAMIC_ARG(Type, name, initial) \
THREAD_LOCAL Type name##_private = initial;
/// Locally change the value of a dynamic argument
/** Usage:
* @code
* // here name() == old value
* WITH_DYNAMIC_ARG(name, newValue) {
* // here name() == newValue
* }
* // here name() == old value
* @endcode
*/
#define WITH_DYNAMIC_ARG(name, value) \
if (name##_changer(value))
// ----------------------------------------------------------------------------- : EOF
#endif
......@@ -41,8 +41,10 @@
#define TYPEOF_CIT(Value) TypeOf<typeid(Value)>::const_iterator
/// The type of a reverse iterator
#define TYPEOF_RIT(Value) TypeOf<typeid(Value)>::reverse_iterator
/// The type of a value
/// The type of a reference
#define TYPEOF_REF(Value) TypeOf<typeid(Value)>::reference
/// The type of a const reference
#define TYPEOF_CREF(Value) TypeOf<typeid(Value)>::const_reference
/// Declare typeof magic for a specific type
#define DECLARE_TYPEOF(T) \
......@@ -52,6 +54,7 @@
typedef T::const_iterator const_iterator; \
typedef T::reverse_iterator reverse_iterator; \
typedef T::reference reference; \
typedef T::const_reference const_reference; \
}
/// Declare typeof magic for a specific type that doesn't support reverse iterators
#define DECLARE_TYPEOF_NO_REV(T) \
......@@ -60,6 +63,7 @@
typedef T::iterator iterator; \
typedef T::const_iterator const_iterator; \
typedef T::reference reference; \
typedef T::const_reference const_reference; \
}
/// Declare typeof magic for a specific type, using const iterators
#define DECLARE_TYPEOF_CONST(T) \
......@@ -67,8 +71,9 @@
typedef T type; \
typedef T::const_iterator iterator; \
typedef T::const_iterator const_iterator; \
typedef T::const_reverse_iterator reverse_iterator; \
typedef T::reverse_iterator reverse_iterator; \
typedef T::const_reference reference; \
typedef T::const_reference const_reference; \
}
......@@ -134,6 +139,13 @@
#define FOR_EACH(Elem,Collection) \
FOR_EACH_T(TYPEOF_IT(Collection), TYPEOF_REF(Collection), Elem, Collection)
/// Iterate over a collection whos type must be declared with DECLARE_TYPEOF
/** Uses a const iterator
* Usage: FOR_EACH_CONST(e,collect) { body-of-loop }
*/
#define FOR_EACH_CONST(Elem,Collection) \
FOR_EACH_T(TYPEOF_CIT(Collection), TYPEOF_CREF(Collection), Elem, Collection)
/// Iterate over a collection whos type must be declared with DECLARE_TYPEOF
/** Iterates using a reverse_iterator
* Usage: FOR_EACH_REVERSE(e,collect) { body-of-loop }
......
......@@ -16,7 +16,7 @@
/// A kind of map of K->V, with the following properties:
/** - K must have a unique member ->index of type UInt
* - There must exist a function initObject(K, V&)
* that stores a new V object for a given key in v
* that stores a new V object for a given key in the reference
* - O(1) inserts and lookups
*/
template <typename Key, typename Value>
......@@ -35,10 +35,10 @@ class IndexMap : private vector<Value> {
void init(const vector<Key>& keys) {
if (!this->empty()) return;
this->reserve(keys.size());
FOR_EACH(it, keys) {
Key& k = *it;
if (k->index >= this->size()) this->resize(k->index + 1);
initObject(k, (*this)[k->index]);
FOR_EACH_CONST(key, keys) {
assert(key);
if (key->index >= this->size()) this->resize(key->index + 1);
initObject(key, (*this)[key->index]);
}
}
......
......@@ -9,7 +9,7 @@
/** @file util/prec.hpp
*
* Precompiled header, and aliasses for common types
* @brief Precompiled header, and aliasses for common types
*/
// ----------------------------------------------------------------------------- : Compiler specific
......
......@@ -20,7 +20,8 @@
// ----------------------------------------------------------------------------- : Declaring reflection
/// Declare that a class supports reflection
/// Reflection allows the member variables of a class to be inspected at runtime.
/** Reflection allows the member variables of a class to be inspected at runtime.
*/
#define DECLARE_REFLECTION() \
protected: \
template<class Tag> void reflect_impl(Tag& tag); \
......
......@@ -14,6 +14,7 @@
// ----------------------------------------------------------------------------- : Includes
#include <util/for_each.hpp>
#include <boost/shared_ptr.hpp>
using namespace boost;
......@@ -22,7 +23,8 @@ using namespace boost;
/// Declares the type TypeP as a shared_ptr<Type>
#define DECLARE_POINTER_TYPE(Type) \
class Type; \
typedef shared_ptr<Type> Type##P
typedef shared_ptr<Type> Type##P; \
DECLARE_TYPEOF_COLLECTION(Type##P)
// ----------------------------------------------------------------------------- : Creating
......
......@@ -14,6 +14,7 @@
// ----------------------------------------------------------------------------- : Includes
#include "prec.hpp"
#include "for_each.hpp"
#include <ctype.h>
#include <boost/preprocessor/cat.hpp>
......
......@@ -7,6 +7,11 @@
#ifndef HEADER_UTIL_WINDOW_ID
#define HEADER_UTIL_WINDOW_ID
/** @file util/window_id.hpp
*
* @brief Enumerations of all window ids used.
*/
// ----------------------------------------------------------------------------- : Includes
// ----------------------------------------------------------------------------- : Menu ids
......
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