return object._unVal.pThread;
}
+// begin: serialization functions
+
+void store_float(HSQUIRRELVM vm, const char* name, float val)
+{
+ sq_pushstring(vm, name, -1);
+ sq_pushfloat(vm, val);
+ if(SQ_FAILED(sq_createslot(vm, -3)))
+ throw Scripting::SquirrelError(vm, "Couldn't add float value to table");
+}
+
+void store_int(HSQUIRRELVM vm, const char* name, int val)
+{
+ sq_pushstring(vm, name, -1);
+ sq_pushinteger(vm, val);
+ if(SQ_FAILED(sq_createslot(vm, -3)))
+ throw Scripting::SquirrelError(vm, "Couldn't add int value to table");
+}
+
+void store_string(HSQUIRRELVM vm, const char* name, const std::string& val)
+{
+ sq_pushstring(vm, name, -1);
+ sq_pushstring(vm, val.c_str(), val.length());
+ if(SQ_FAILED(sq_createslot(vm, -3)))
+ throw Scripting::SquirrelError(vm, "Couldn't add float value to table");
+}
+
+void store_bool(HSQUIRRELVM vm, const char* name, bool val)
+{
+ sq_pushstring(vm, name, -1);
+ sq_pushbool(vm, val ? SQTrue : SQFalse);
+ if(SQ_FAILED(sq_createslot(vm, -3)))
+ throw Scripting::SquirrelError(vm, "Couldn't add float value to table");
+}
+
+bool has_float(HSQUIRRELVM vm, const char* name)
+{
+ sq_pushstring(vm, name, -1);
+ if (SQ_FAILED(sq_get(vm, -2))) return false;
+ sq_pop(vm, 1);
+ return true;
+}
+
+bool has_int(HSQUIRRELVM vm, const char* name)
+{
+ return has_float(vm, name);
+}
+
+bool has_string(HSQUIRRELVM vm, const char* name)
+{
+ return has_float(vm, name);
+}
+
+bool has_bool(HSQUIRRELVM vm, const char* name)
+{
+ return has_float(vm, name);
+}
+
+float read_float(HSQUIRRELVM vm, const char* name)
+{
+ sq_pushstring(vm, name, -1);
+ if(SQ_FAILED(sq_get(vm, -2))) {
+ std::ostringstream msg;
+ msg << "Couldn't get float value for '" << name << "' from table";
+ throw Scripting::SquirrelError(vm, msg.str());
+ }
+
+ float result;
+ if(SQ_FAILED(sq_getfloat(vm, -1, &result))) {
+ std::ostringstream msg;
+ msg << "Couldn't get float value for '" << name << "' from table";
+ throw Scripting::SquirrelError(vm, msg.str());
+ }
+ sq_pop(vm, 1);
+
+ return result;
+}
+
+int read_int(HSQUIRRELVM vm, const char* name)
+{
+ sq_pushstring(vm, name, -1);
+ if(SQ_FAILED(sq_get(vm, -2))) {
+ std::ostringstream msg;
+ msg << "Couldn't get int value for '" << name << "' from table";
+ throw Scripting::SquirrelError(vm, msg.str());
+ }
+
+ int result;
+ if(SQ_FAILED(sq_getinteger(vm, -1, &result))) {
+ std::ostringstream msg;
+ msg << "Couldn't get int value for '" << name << "' from table";
+ throw Scripting::SquirrelError(vm, msg.str());
+ }
+ sq_pop(vm, 1);
+
+ return result;
+}
+
+
+std::string read_string(HSQUIRRELVM vm, const char* name)
+{
+ sq_pushstring(vm, name, -1);
+ if(SQ_FAILED(sq_get(vm, -2))) {
+ std::ostringstream msg;
+ msg << "Couldn't get string value for '" << name << "' from table";
+ throw Scripting::SquirrelError(vm, msg.str());
+ }
+
+ const char* result;
+ if(SQ_FAILED(sq_getstring(vm, -1, &result))) {
+ std::ostringstream msg;
+ msg << "Couldn't get string value for '" << name << "' from table";
+ throw Scripting::SquirrelError(vm, msg.str());
+ }
+ sq_pop(vm, 1);
+
+ return std::string(result);
+}
+
+bool read_bool(HSQUIRRELVM vm, const char* name)
+{
+ sq_pushstring(vm, name, -1);
+ if(SQ_FAILED(sq_get(vm, -2))) {
+ std::ostringstream msg;
+ msg << "Couldn't get bool value for '" << name << "' from table";
+ throw Scripting::SquirrelError(vm, msg.str());
+ }
+
+ SQBool result;
+ if(SQ_FAILED(sq_getbool(vm, -1, &result))) {
+ std::ostringstream msg;
+ msg << "Couldn't get bool value for '" << name << "' from table";
+ throw Scripting::SquirrelError(vm, msg.str());
+ }
+ sq_pop(vm, 1);
+
+ return result == SQTrue;
+}
+
+bool get_float(HSQUIRRELVM vm, const char* name, float& val) {
+ if (!has_float(vm, name)) return false;
+ val = read_float(vm, name);
+ return true;
+}
+
+bool get_int(HSQUIRRELVM vm, const char* name, int& val) {
+ if (!has_int(vm, name)) return false;
+ val = read_int(vm, name);
+ return true;
+}
+
+bool get_string(HSQUIRRELVM vm, const char* name, std::string& val) {
+ if (!has_string(vm, name)) return false;
+ val = read_string(vm, name);
+ return true;
+}
+
+bool get_bool(HSQUIRRELVM vm, const char* name, bool& val) {
+ if (!has_bool(vm, name)) return false;
+ val = read_bool(vm, name);
+ return true;
+}
+
+// end: serialization functions
+
}
}
}
+ // begin serialization functions
+ void store_float(HSQUIRRELVM vm, const char* name, float val);
+ void store_int(HSQUIRRELVM vm, const char* name, int val);
+ void store_string(HSQUIRRELVM vm, const char* name, const std::string& val);
+ void store_bool(HSQUIRRELVM vm, const char* name, bool val);
+
+ bool has_float(HSQUIRRELVM vm, const char* name);
+ bool has_int(HSQUIRRELVM vm, const char* name);
+ bool has_string(HSQUIRRELVM vm, const char* name);
+ bool has_bool(HSQUIRRELVM vm, const char* name);
+
+ bool get_float(HSQUIRRELVM vm, const char* name, float& val);
+ bool get_int(HSQUIRRELVM vm, const char* name, int& val);
+ bool get_string(HSQUIRRELVM vm, const char* name, std::string& val);
+ bool get_bool(HSQUIRRELVM vm, const char* name, bool& val);
+
+ float read_float(HSQUIRRELVM vm, const char* name);
+ int read_int(HSQUIRRELVM vm, const char* name);
+ std::string read_string(HSQUIRRELVM vm, const char* name);
+ bool read_bool(HSQUIRRELVM vm, const char* name);
+ // end serialization functions
+
}
#endif
#include "main.hpp"
#include "statistics.hpp"
#include "log.hpp"
+#include "scripting/squirrel_util.hpp"
namespace {
const int nv_coins = std::numeric_limits<int>::min();
{
}
+/*
void
Statistics::parse(const lisp::Lisp& reader)
{
writer.write_int("secrets-found", secrets);
writer.write_int("secrets-found-total", total_secrets);
}
+*/
+
+void
+Statistics::serialize_to_squirrel(HSQUIRRELVM vm)
+{
+ // TODO: there's some bug in the unserialization routines that breaks stuff when an empty statistics table is written, so -- as a workaround -- let's make sure we will actually write something first
+ if (!((coins != nv_coins) || (total_coins != nv_coins) || (badguys != nv_badguys) || (total_badguys != nv_badguys) || (time != nv_time) || (secrets != nv_secrets) || (total_secrets != nv_secrets))) return;
+
+ sq_pushstring(vm, "statistics", -1);
+ sq_newtable(vm);
+ if (coins != nv_coins) Scripting::store_int(vm, "coins-collected", coins);
+ if (total_coins != nv_coins) Scripting::store_int(vm, "coins-collected-total", total_coins);
+ if (badguys != nv_badguys) Scripting::store_int(vm, "badguys-killed", badguys);
+ if (total_badguys != nv_badguys) Scripting::store_int(vm, "badguys-killed-total", total_badguys);
+ if (time != nv_time) Scripting::store_float(vm, "time-needed", time);
+ if (secrets != nv_secrets) Scripting::store_int(vm, "secrets-found", secrets);
+ if (total_secrets != nv_secrets) Scripting::store_int(vm, "secrets-found-total", total_secrets);
+ sq_createslot(vm, -3);
+}
+
+void
+Statistics::unserialize_from_squirrel(HSQUIRRELVM vm)
+{
+ sq_pushstring(vm, "statistics", -1);
+ if(SQ_FAILED(sq_get(vm, -2))) {
+ return;
+ }
+ Scripting::get_int(vm, "coins-collected", coins);
+ Scripting::get_int(vm, "coins-collected-total", total_coins);
+ Scripting::get_int(vm, "badguys-killed", badguys);
+ Scripting::get_int(vm, "badguys-killed-total", total_badguys);
+ Scripting::get_float(vm, "time-needed", time);
+ Scripting::get_int(vm, "secrets-found", secrets);
+ Scripting::get_int(vm, "secrets-found-total", total_secrets);
+ sq_pop(vm, 1);
+}
//define TOTAL_DISPLAY_TIME 3400
//define FADING_TIME 600
}
void
+Statistics::zero()
+{
+ reset();
+ total_coins = 0;
+ total_badguys = 0;
+ total_secrets = 0;
+}
+
+void
Statistics::reset()
{
coins = 0;
#ifndef SUPERTUX_STATISTICS_H
#define SUPERTUX_STATISTICS_H
+#include <squirrel.h>
#include "timer.hpp"
namespace lisp { class Writer; }
~Statistics();
/// read statistics from lisp file
- void parse(const lisp::Lisp& lisp);
+ //void parse(const lisp::Lisp& lisp);
/// write statistics to lisp file
- void write(lisp::Writer& writer);
+ //void write(lisp::Writer& writer);
+
+ /**
+ * serialize statistics object as squirrel table "statistics"
+ */
+ void serialize_to_squirrel(HSQUIRRELVM vm);
+
+ /**
+ * unserialize statistics object from squirrel table "statistics"
+ */
+ void unserialize_from_squirrel(HSQUIRRELVM vm);
void draw_worldmap_info(DrawingContext& context); /**< draw worldmap stat HUD */
void draw_message_info(DrawingContext& context, std::string title); /**< draw stats at level start */
void draw_endseq_panel(DrawingContext& context, Statistics* best_stats, Surface* backdrop); /**< draw panel shown during level's end sequence */
+ void zero(); /**< Set stats to zero */
void reset(); /**< Set stats (but not totals) to zero */
void merge(Statistics& stats); /**< Given another Statistics object finds the best of each one */
void operator+=(const Statistics& o); /**< Add two Statistics objects */
void WorldMap::calculate_total_stats()
{
- total_stats.reset();
+ total_stats.zero();
for(LevelTiles::iterator i = levels.begin(); i != levels.end(); ++i) {
LevelTile* level = *i;
if (level->solved) {
sq_pop(global_vm, 1);
}
-static void store_float(HSQUIRRELVM vm, const char* name, float val)
-{
- sq_pushstring(vm, name, -1);
- sq_pushfloat(vm, val);
- if(SQ_FAILED(sq_createslot(vm, -3)))
- throw Scripting::SquirrelError(vm, "Couldn't add float value to table");
-}
-
-/*
-static void store_int(HSQUIRRELVM vm, const char* name, int val)
-{
- sq_pushstring(vm, name, -1);
- sq_pushinteger(vm, val);
- if(SQ_FAILED(sq_createslot(vm, -3)))
- throw Scripting::SquirrelError(vm, "Couldn't add float value to table");
-}
-*/
-
-static void store_string(HSQUIRRELVM vm, const char* name, const std::string& val)
-{
- sq_pushstring(vm, name, -1);
- sq_pushstring(vm, val.c_str(), val.length());
- if(SQ_FAILED(sq_createslot(vm, -3)))
- throw Scripting::SquirrelError(vm, "Couldn't add float value to table");
-}
-
-static void store_bool(HSQUIRRELVM vm, const char* name, bool val)
-{
- sq_pushstring(vm, name, -1);
- sq_pushbool(vm, val ? SQTrue : SQFalse);
- if(SQ_FAILED(sq_createslot(vm, -3)))
- throw Scripting::SquirrelError(vm, "Couldn't add float value to table");
-}
-
-static float read_float(HSQUIRRELVM vm, const char* name)
-{
- sq_pushstring(vm, name, -1);
- if(SQ_FAILED(sq_get(vm, -2))) {
- std::ostringstream msg;
- msg << "Couldn't get float value for '" << name << "' from table";
- throw Scripting::SquirrelError(vm, msg.str());
- }
-
- float result;
- if(SQ_FAILED(sq_getfloat(vm, -1, &result))) {
- std::ostringstream msg;
- msg << "Couldn't get float value for '" << name << "' from table";
- throw Scripting::SquirrelError(vm, msg.str());
- }
- sq_pop(vm, 1);
-
- return result;
-}
-
-static std::string read_string(HSQUIRRELVM vm, const char* name)
-{
- sq_pushstring(vm, name, -1);
- if(SQ_FAILED(sq_get(vm, -2))) {
- std::ostringstream msg;
- msg << "Couldn't get string value for '" << name << "' from table";
- throw Scripting::SquirrelError(vm, msg.str());
- }
-
- const char* result;
- if(SQ_FAILED(sq_getstring(vm, -1, &result))) {
- std::ostringstream msg;
- msg << "Couldn't get string value for '" << name << "' from table";
- throw Scripting::SquirrelError(vm, msg.str());
- }
- sq_pop(vm, 1);
-
- return std::string(result);
-}
-
-static bool read_bool(HSQUIRRELVM vm, const char* name)
-{
- sq_pushstring(vm, name, -1);
- if(SQ_FAILED(sq_get(vm, -2))) {
- std::ostringstream msg;
- msg << "Couldn't get bool value for '" << name << "' from table";
- throw Scripting::SquirrelError(vm, msg.str());
- }
-
- SQBool result;
- if(SQ_FAILED(sq_getbool(vm, -1, &result))) {
- std::ostringstream msg;
- msg << "Couldn't get bool value for '" << name << "' from table";
- throw Scripting::SquirrelError(vm, msg.str());
- }
- sq_pop(vm, 1);
-
- return result == SQTrue;
-}
-
void
WorldMap::save_state()
{
sq_newtable(vm);
store_bool(vm, "solved", level->solved);
- // TODO write statistics
- // i->statistics.write(writer);
+ level->statistics.serialize_to_squirrel(vm);
sq_createslot(vm, -3);
}
sq_createslot(vm, -3);
+ // overall statistics...
+ total_stats.serialize_to_squirrel(vm);
+
// push world into worlds table
sq_createslot(vm, -3);
} catch(std::exception& ) {
if(SQ_SUCCEEDED(sq_get(vm, -2))) {
level->solved = read_bool(vm, "solved");
level->sprite->set_action(level->solved ? "solved" : "default");
- // i->statistics.parse(*level);
+ level->statistics.unserialize_from_squirrel(vm);
sq_pop(vm, 1);
}
}
+
+ // leave state table
sq_pop(vm, 1);
+ // load overall statistics
+ total_stats.unserialize_from_squirrel(vm);
+
} catch(std::exception& e) {
log_debug << "Not loading worldmap state: " << e.what() << std::endl;
}