From: Jean Privat Date: Fri, 24 Apr 2015 06:03:14 +0000 (+0700) Subject: Merge: nitrpg: periodize stats X-Git-Tag: v0.7.4~5 X-Git-Url: http://nitlanguage.org?hp=9b518490ebefb3618cfba5392a55d4ba4eba6919 Merge: nitrpg: periodize stats This will be used to display periodic stats about players and games. Pull-Request: #1292 Reviewed-by: Jean Privat --- diff --git a/contrib/nitrpg/src/achievements.nit b/contrib/nitrpg/src/achievements.nit index eeae17e..99cc0c2 100644 --- a/contrib/nitrpg/src/achievements.nit +++ b/contrib/nitrpg/src/achievements.nit @@ -35,7 +35,7 @@ redef class GameEntity var key = self.key / achievement.key if game.store.has_key(key) then return stats.inc("achievements") - achievement.save_in(self) + achievement.save_in(self.key) save end diff --git a/contrib/nitrpg/src/events.nit b/contrib/nitrpg/src/events.nit index 227469a..dde2c55 100644 --- a/contrib/nitrpg/src/events.nit +++ b/contrib/nitrpg/src/events.nit @@ -25,7 +25,7 @@ import game redef class GameEntity # Saves `event` in `self`. - fun add_event(event: GameEvent) do event.save_in(self) + fun add_event(event: GameEvent) do event.save_in(self.key) # List all events registered in this entity. # diff --git a/contrib/nitrpg/src/game.nit b/contrib/nitrpg/src/game.nit index d1dff3e..1ab143e 100644 --- a/contrib/nitrpg/src/game.nit +++ b/contrib/nitrpg/src/game.nit @@ -43,11 +43,11 @@ interface GameEntity # Date are stored under `self.key`. fun save do game.store.store_object(key, to_json) - # Saves `self` state into `target` key data. + # Saves `self` state under `key` data. # - # Data are stored under `target.key / self.key`. - fun save_in(target: GameEntity) do - game.store.store_object(target.key / key, to_json) + # Data are stored under `key / self.key`. + fun save_in(key: String) do + game.store.store_object(key / self.key, to_json) end # Json representation of `self`. diff --git a/contrib/nitrpg/src/statistics.nit b/contrib/nitrpg/src/statistics.nit index 7b493c6..e8afccc 100644 --- a/contrib/nitrpg/src/statistics.nit +++ b/contrib/nitrpg/src/statistics.nit @@ -26,27 +26,17 @@ import counter redef class GameEntity - # Statistics for this entity. - fun stats: GameStats is abstract - - # Load statistics for this `MEntity` if any. - fun load_statistics: nullable GameStats do - var key = self.key / "statistics" - if not game.store.has_key(key) then return null - var json = game.store.load_object(key) - return new GameStats.from_json(game, json) - end + # Statistics manager for this entity. + fun stats: GameStatsManager is abstract end redef class Game - redef var stats is lazy do - return load_statistics or else new GameStats(game) - end + redef var stats is lazy do return new GameStatsManager(game, self) redef fun save do super - stats.save_in(self) + stats.save_in(self.key) end redef fun pretty do @@ -60,15 +50,16 @@ end redef class Player - redef var stats is lazy do - return load_statistics or else new GameStats(game) - end + redef var stats is lazy do return new GameStatsManager(game, self) redef fun save do super - stats.save_in(self) + stats.save_in(self.key) end + redef fun nitcoins do return stats["nitcoins"] + redef fun nitcoins=(nc) do stats["nitcoins"] = nc + redef fun pretty do var res = new FlatBuffer res.append super @@ -78,6 +69,98 @@ redef class Player end end +# Store game stats for defined period. +class GameStatsManager + super GameEntity + super Counter[String] + + redef var game + + # The GameEntity monitored by these statistics. + var owner: GameEntity + + redef var key = "stats" + + # Returns the `GameStats` instance for the overall statistics. + var overall: GameStats is lazy do + return load_stats_for("all") + end + + # Returns the `GameStats` instance for the current year statistics. + var yearly: GameStats is lazy do + var date = new Tm.gmtime + var key = date.strftime("%Y") + return load_stats_for(key) + end + + # Returns the `GameStats` instance for the current month statistics. + var monthly: GameStats is lazy do + var date = new Tm.gmtime + var key = date.strftime("%Y-%m") + return load_stats_for(key) + end + + # Returns the `GameStats` instance for the current day statistics. + var daily: GameStats is lazy do + var date = new Tm.gmtime + var key = date.strftime("%Y-%m-%d") + return load_stats_for(key) + end + + # Returns the `GameStats` instance for the current week statistics. + var weekly: GameStats is lazy do + var date = new Tm.gmtime + var key = date.strftime("%Y-W%U") + return load_stats_for(key) + end + + # Load statistics for a `period` key. + fun load_stats_for(period: String): GameStats do + var key = owner.key / self.key / period + if not game.store.has_key(key) then + return new GameStats(game, period) + end + var json = game.store.load_object(key) + return new GameStats.from_json(game, period, json) + end + + redef fun [](key) do return overall[key] + + redef fun []=(key, value) do + overall[key] = value + yearly[key] = value + monthly[key] = value + daily[key] = value + weekly[key] = value + end + + redef fun inc(e) do + overall.inc(e) + yearly.inc(e) + monthly.inc(e) + daily.inc(e) + weekly.inc(e) + end + + redef fun dec(e) do + overall.dec(e) + yearly.dec(e) + monthly.dec(e) + daily.dec(e) + weekly.dec(e) + end + + redef fun save_in(key) do + overall.save_in(key / self.key) + yearly.save_in(key / self.key) + monthly.save_in(key / self.key) + daily.save_in(key / self.key) + weekly.save_in(key / self.key) + end + + redef fun pretty do return overall.pretty +end + # Game statistics structure that can be saved as a `GameEntity`. class GameStats super GameEntity @@ -85,11 +168,13 @@ class GameStats redef var game - redef var key = "statistics" + # The pedriod these stats are about. + var period: String + + redef fun key do return period - # Load `self` from saved data - init from_json(game: Game, json: JsonObject) do - self.game = game + # Load `self` from saved data. + init from_json(game: Game, period: String, json: JsonObject) do for k, v in json do self[k] = v.as(Int) end @@ -99,15 +184,6 @@ class GameStats return obj end - # Decrements the value of `key` statistic entry by 1. - fun dec(key: String) do - if not has_key(key) then - self[key] = 0 - else - self[key] -= 1 - end - end - redef fun pretty do var res = new FlatBuffer for k, v in self do diff --git a/lib/counter.nit b/lib/counter.nit index 6545b73..6d5729d 100644 --- a/lib/counter.nit +++ b/lib/counter.nit @@ -93,6 +93,22 @@ class Counter[E] for e in es do inc(e) end + # Decrement the value of `e` by 1 + fun dec(e: E) do + if not has_key(e) then + self.map[e] = 0 + else + self.map[e] = self[e] - 1 + sum += - 1 + end + end + + # Decrement the value for each element of `es` + fun dec_all(es: Collection[E]) + do + for e in es do dec(e) + end + # A new Counter initialized with `inc_all`. init from(es: Collection[E]) do