Commit 17762eca authored by twanvl's avatar twanvl

Added version number to files; IndexMap now works with GetMember

parent cff3bab1
...@@ -50,4 +50,13 @@ IMPLEMENT_REFLECTION(Game) { ...@@ -50,4 +50,13 @@ IMPLEMENT_REFLECTION(Game) {
void Game::validate() { void Game::validate() {
// a default for the full name // a default for the full name
if (full_name.empty()) full_name = name(); if (full_name.empty()) full_name = name();
} }
\ No newline at end of file
// special behaviour of reading/writing GamePs: only read/write the name
void Reader::handle(GameP& game) {
game = Game::byName(value);
}
void Writer::handle(const GameP& game) {
handle(game->name());
}
...@@ -7,7 +7,9 @@ ...@@ -7,7 +7,9 @@
// ----------------------------------------------------------------------------- : Includes // ----------------------------------------------------------------------------- : Includes
#include <data/set.hpp> #include <data/set.hpp>
#include <data/game.hpp>
#include <data/card.hpp> #include <data/card.hpp>
#include <data/field.hpp>
#include <script/value.hpp> #include <script/value.hpp>
// ----------------------------------------------------------------------------- : Set // ----------------------------------------------------------------------------- : Set
...@@ -21,9 +23,15 @@ Set::Set() {} ...@@ -21,9 +23,15 @@ Set::Set() {}
String Set::typeName() const { return _("set"); } String Set::typeName() const { return _("set"); }
IMPLEMENT_REFLECTION(Set) { IMPLEMENT_REFLECTION(Set) {
REFLECT(game);
if (data.empty() && game) {
data.init(game->set_fields);
}
REFLECT_N("set_info", data);
WITH_DYNAMIC_ARG(game_for_new_cards, game.get()) { WITH_DYNAMIC_ARG(game_for_new_cards, game.get()) {
REFLECT(cards); REFLECT(cards);
} }
REFLECT(apprentice_code);
} }
......
...@@ -18,6 +18,8 @@ DECLARE_POINTER_TYPE(Card); ...@@ -18,6 +18,8 @@ DECLARE_POINTER_TYPE(Card);
DECLARE_POINTER_TYPE(Set); DECLARE_POINTER_TYPE(Set);
DECLARE_POINTER_TYPE(Game); DECLARE_POINTER_TYPE(Game);
DECLARE_POINTER_TYPE(Stylesheet); DECLARE_POINTER_TYPE(Stylesheet);
DECLARE_POINTER_TYPE(Field);
DECLARE_POINTER_TYPE(Value);
// ----------------------------------------------------------------------------- : Set // ----------------------------------------------------------------------------- : Set
...@@ -33,8 +35,13 @@ class Set : public Packaged { ...@@ -33,8 +35,13 @@ class Set : public Packaged {
GameP game; GameP game;
/// The default stylesheet /// The default stylesheet
StylesheetP stylesheet; StylesheetP stylesheet;
/// The values on the fields of the set
/** The indices should correspond to the set_fields in the Game */
IndexMap<FieldP, ValueP> data;
/// The cards in the set /// The cards in the set
vector<CardP> cards; vector<CardP> cards;
/// Code to use for apprentice (Magic only)
String apprentice_code;
/// Actions performed on this set and the cards in it /// Actions performed on this set and the cards in it
ActionStack actions; ActionStack actions;
......
...@@ -819,9 +819,6 @@ ...@@ -819,9 +819,6 @@
<File <File
RelativePath=".\util\string.hpp"> RelativePath=".\util\string.hpp">
</File> </File>
<File
RelativePath=".\util\version.hpp">
</File>
<File <File
RelativePath=".\util\window_id.hpp"> RelativePath=".\util\window_id.hpp">
</File> </File>
...@@ -934,6 +931,12 @@ ...@@ -934,6 +931,12 @@
<File <File
RelativePath=".\util\vector2d.hpp"> RelativePath=".\util\vector2d.hpp">
</File> </File>
<File
RelativePath=".\util\version.cpp">
</File>
<File
RelativePath=".\util\version.hpp">
</File>
</Filter> </Filter>
</Filter> </Filter>
<Filter <Filter
......
...@@ -172,6 +172,26 @@ class ScriptCollection : public ScriptValue { ...@@ -172,6 +172,26 @@ class ScriptCollection : public ScriptValue {
// ----------------------------------------------------------------------------- : Collections : maps // ----------------------------------------------------------------------------- : Collections : maps
template <typename V>
ScriptValueP get_member(const map<String,V>& m, const String& name) {
map<String,V>::const_iterator it = m.find(name);
if (it != m.end()) {
return toScript(it->second);
} else {
throw ScriptError(_("Collection has no member '") + name + _("'"));
}
}
template <typename K, typename V>
ScriptValueP get_member(const IndexMap<K,V>& m, const String& name) {
IndexMap<K,V>::const_iterator it = m.find(name);
if (it != m.end()) {
return toScript(*it);
} else {
throw ScriptError(_("Collection has no member '") + name + _("'"));
}
}
/// Script value containing a map-like collection /// Script value containing a map-like collection
template <typename Collection> template <typename Collection>
class ScriptMap : public ScriptValue { class ScriptMap : public ScriptValue {
...@@ -180,12 +200,7 @@ class ScriptMap : public ScriptValue { ...@@ -180,12 +200,7 @@ class ScriptMap : public ScriptValue {
virtual ScriptType type() const { return SCRIPT_OBJECT; } virtual ScriptType type() const { return SCRIPT_OBJECT; }
virtual String typeName() const { return _("collection"); } virtual String typeName() const { return _("collection"); }
virtual ScriptValueP getMember(const String& name) const { virtual ScriptValueP getMember(const String& name) const {
Collection::const_iterator it = value->find(name); return get_member(*value, name);
if (it != value->end()) {
return toScript(it->second);
} else {
throw ScriptError(_("Collection has no member ") + name);
}
} }
private: private:
/// Store a pointer to a collection, collections are only ever used for structures owned outside the script /// Store a pointer to a collection, collections are only ever used for structures owned outside the script
......
...@@ -41,7 +41,8 @@ class IndexMap : private vector<Value> { ...@@ -41,7 +41,8 @@ class IndexMap : private vector<Value> {
void init(const vector<Key>& keys) { void init(const vector<Key>& keys) {
if (!this->empty()) return; if (!this->empty()) return;
this->reserve(keys.size()); this->reserve(keys.size());
FOR_EACH_CONST(key, keys) { for(vector<Key>::const_iterator it = keys.begin() ; it != keys.end() ; ++it) {
const Key& key = *it;
assert(key); assert(key);
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]);
...@@ -68,6 +69,15 @@ class IndexMap : private vector<Value> { ...@@ -68,6 +69,15 @@ class IndexMap : private vector<Value> {
return key->index < this.size() && get_key((*this)[key->index]) == key return key->index < this.size() && get_key((*this)[key->index]) == key
} }
/// Find a value given the key name, return an iterator
template <typename Name>
const_iterator find(const Name& key) const {
for(vector<Value>::const_iterator it = begin() ; it != end() ; ++it) {
if (get_key_name(*it) == key) return it;
}
return end();
}
private: private:
using vector<Value>::operator []; using vector<Value>::operator [];
}; };
......
...@@ -29,6 +29,8 @@ class GetDefaultMember { ...@@ -29,6 +29,8 @@ class GetDefaultMember {
inline bool reading() const { return false; } inline bool reading() const { return false; }
inline bool isComplex() const { return false; } inline bool isComplex() const { return false; }
inline void handleAppVersion() {} // no effect
/// The result, or script_nil if the member was not found /// The result, or script_nil if the member was not found
inline ScriptValueP result() { return value; } inline ScriptValueP result() { return value; }
......
...@@ -386,6 +386,7 @@ void Packaged::open(const String& package) { ...@@ -386,6 +386,7 @@ void Packaged::open(const String& package) {
Package::open(package); Package::open(package);
Reader reader(openIn(typeName()), absoluteFilename() + _("/") + typeName()); Reader reader(openIn(typeName()), absoluteFilename() + _("/") + typeName());
try { try {
reader.handleAppVersion();
reader.handle(*this); reader.handle(*this);
} catch (const ParseError& err) { } catch (const ParseError& err) {
throw FileParseError(err.what(), absoluteFilename() + _("/") + typeName()); // more detailed message throw FileParseError(err.what(), absoluteFilename() + _("/") + typeName()); // more detailed message
......
...@@ -31,6 +31,21 @@ Reader::Reader(const String& filename) ...@@ -31,6 +31,21 @@ Reader::Reader(const String& filename)
} }
void Reader::handleAppVersion() {
if (enterBlock(_("mse_version"))) {
handle(app_version);
if (::app_version < app_version) {
wxMessageBox(
filename + _("\n")
_("This file is made with a newer version of Magic Set Editor (")+ app_version.toString() +_(").\n")
_("When you open it, some aspects of the file may be lost.\n")
_("It is recommended that you upgrade to the latest version.\n")
_("Visit http:://magicseteditor.sourceforge.net/"), _("Warning"), wxOK | wxICON_EXCLAMATION);
}
exitBlock();
}
}
void Reader::warning(const String& msg) { void Reader::warning(const String& msg) {
wxMessageBox((msg + _("\nOn line: ")) << line_number << _("\nIn file: ") << filename, _("Warning"), wxOK | wxICON_EXCLAMATION); wxMessageBox((msg + _("\nOn line: ")) << line_number << _("\nIn file: ") << filename, _("Warning"), wxOK | wxICON_EXCLAMATION);
} }
......
...@@ -10,10 +10,13 @@ ...@@ -10,10 +10,13 @@
// ----------------------------------------------------------------------------- : Includes // ----------------------------------------------------------------------------- : Includes
#include <util/prec.hpp> #include <util/prec.hpp>
#include <util/version.hpp>
#include <wx/txtstrm.h> #include <wx/txtstrm.h>
template <typename T> class Defaultable; template <typename T> class Defaultable;
template <typename T> class Scriptable; template <typename T> class Scriptable;
DECLARE_POINTER_TYPE(Game);
DECLARE_POINTER_TYPE(StyleSheet);
// ----------------------------------------------------------------------------- : Reader // ----------------------------------------------------------------------------- : Reader
...@@ -44,6 +47,9 @@ class Reader { ...@@ -44,6 +47,9 @@ class Reader {
/// Is the thing currently being read 'complex', i.e. does it have children /// Is the thing currently being read 'complex', i.e. does it have children
inline bool isComplex() const { return value.empty(); } inline bool isComplex() const { return value.empty(); }
/// Read and check the application version
void handleAppVersion();
/// Show a warning message, but continue reading /// Show a warning message, but continue reading
void warning(const String& msg); void warning(const String& msg);
...@@ -72,9 +78,14 @@ class Reader { ...@@ -72,9 +78,14 @@ class Reader {
template <typename T> void handle(Defaultable<T>&); template <typename T> void handle(Defaultable<T>&);
/// Reads a Scriptable from the input stream /// Reads a Scriptable from the input stream
template <typename T> void handle(Scriptable<T>&); template <typename T> void handle(Scriptable<T>&);
// special behaviour
void handle(GameP&);
void handle(StyleSheet&);
private:
// --------------------------------------------------- : Data // --------------------------------------------------- : Data
/// App version this file was made with
Version app_version;
private:
/// The line we read /// The line we read
String line; String line;
/// The key and value of the last line we read /// The key and value of the last line we read
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "writer.hpp" #include "writer.hpp"
#include <util/vector2d.hpp> #include <util/vector2d.hpp>
#include <util/error.hpp> #include <util/error.hpp>
#include <util/version.hpp>
// ----------------------------------------------------------------------------- : Writer // ----------------------------------------------------------------------------- : Writer
...@@ -22,6 +23,10 @@ Writer::Writer(const OutputStreamP& output) ...@@ -22,6 +23,10 @@ Writer::Writer(const OutputStreamP& output)
} }
void Writer::handleAppVersion() {
handle(_("mse_version"), app_version);
}
void Writer::enterBlock(const Char* name) { void Writer::enterBlock(const Char* name) {
// indenting into a sub-block? // indenting into a sub-block?
if (just_opened) { if (just_opened) {
......
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
template <typename T> class Defaultable; template <typename T> class Defaultable;
template <typename T> class Scriptable; template <typename T> class Scriptable;
DECLARE_POINTER_TYPE(Game);
DECLARE_POINTER_TYPE(StyleSheet);
// ----------------------------------------------------------------------------- : Writer // ----------------------------------------------------------------------------- : Writer
...@@ -30,6 +32,9 @@ class Writer { ...@@ -30,6 +32,9 @@ class Writer {
inline bool reading() const { return false; } inline bool reading() const { return false; }
inline bool isComplex() const { return false; } inline bool isComplex() const { return false; }
/// Write the application version
void handleAppVersion();
// --------------------------------------------------- : Handling objects // --------------------------------------------------- : Handling objects
/// Handle an object: write it under the given name /// Handle an object: write it under the given name
template <typename T> template <typename T>
...@@ -58,6 +63,9 @@ class Writer { ...@@ -58,6 +63,9 @@ class Writer {
template <typename T> void handle(const Defaultable<T>&); template <typename T> void handle(const Defaultable<T>&);
/// Write an object of type Scriptable<T> to the output stream /// Write an object of type Scriptable<T> to the output stream
template <typename T> void handle(const Scriptable<T>&); template <typename T> void handle(const Scriptable<T>&);
// special behaviour
void handle(const GameP&);
void handle(const StyleSheet&);
private: private:
// --------------------------------------------------- : Data // --------------------------------------------------- : Data
......
...@@ -25,13 +25,15 @@ struct Version { ...@@ -25,13 +25,15 @@ struct Version {
Version() : version(0) {} Version() : version(0) {}
Version(UInt version) : version(version) {} Version(UInt version) : version(version) {}
bool operator < (Version v) { return version < v.versionSuffix; } inline bool operator < (Version v) const { return version < v.version; }
/// Convert a version number to a string /// Convert a version number to a string
String toString(); String toString() const;
/// Get the version number as an integer number
UInt toNumber() const;
/// Convert a string to a version number /// Convert a string to a version number
static Version fromString(UInt version); static Version fromString(const String& version);
private: private:
UInt version; ///< Version number encoded as aabbcc, where a=major, b=minor, c=revision UInt version; ///< Version number encoded as aabbcc, where a=major, b=minor, c=revision
...@@ -39,20 +41,14 @@ struct Version { ...@@ -39,20 +41,14 @@ struct Version {
// ----------------------------------------------------------------------------- : Versions // ----------------------------------------------------------------------------- : Versions
/// The verwsion number of MSE /// The version number of MSE
const Version app_version = 000300; // 0.3.0 extern const Version app_version;
const Char* version_suffix = _(" (beta)"); extern const Char* version_suffix;
/// File version, usually the same as program version, /// File version, usually the same as program version,
/** When no files are changed the file version is not incremented /** When no files are changed the file version is not incremented
* Changes:
* 0.2.0 : start of version numbering practice
* 0.2.2 : _("include file")
* 0.2.6 : fix in settings loading
* 0.2.7 : new tag system, different style of close tags
* 0.3.0 : port of code to C++
*/ */
const Version file_version = 000300; // 0.3.0 extern const Version file_version;
// ----------------------------------------------------------------------------- : EOF // ----------------------------------------------------------------------------- : EOF
#endif #endif
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