model: intro `MModule::first_real_mmodule` to get the first non-fictive module
[nit.git] / contrib / nitrpg / src / statistics.nit
index 1f55592..dfdb3ba 100644 (file)
@@ -24,22 +24,29 @@ import game
 import github::hooks
 import counter
 
-redef class Game
+redef class GameEntity
 
-       # Statistics for this game instance.
-       var stats = new GameStats
+       # Statistics for this entity.
+       fun stats: GameStats is abstract
 
-       redef fun from_json(json) do
-               super
-               if json.has_key("statistics") then
-                       stats.from_json(json["statistics"].as(JsonObject))
-               end
+       # 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
+end
 
-       redef fun to_json do
-               var obj = super
-               obj["statistics"] = stats.to_json
-               return obj
+redef class Game
+
+       redef var stats is lazy do
+               return load_statistics or else new GameStats(game)
+       end
+
+       redef fun save do
+               super
+               stats.save_in(self)
        end
 
        redef fun pretty do
@@ -49,10 +56,25 @@ redef class Game
                res.append stats.pretty
                return res.write_to_string
        end
+end
+
+redef class Player
+
+       redef var stats is lazy do
+               return load_statistics or else new GameStats(game)
+       end
 
-       redef fun clear do
+       redef fun save do
                super
-               stats.clear
+               stats.save_in(self)
+       end
+
+       redef fun pretty do
+               var res = new FlatBuffer
+               res.append super
+               res.append "# stats:\n"
+               res.append stats.pretty
+               return res.write_to_string
        end
 end
 
@@ -99,11 +121,7 @@ end
 class StatisticsReactor
        super GameReactor
 
-       redef fun react_event(game, e) do
-               super # log events
-               e.react_stats_event(game)
-               game.save
-       end
+       redef fun react_event(game, e) do e.react_stats_event(game)
 end
 
 redef class GithubEvent
@@ -118,13 +136,24 @@ redef class IssuesEvent
 
        # Count opened and closed issues.
        redef fun react_stats_event(game) do
+               var player = issue.user.player(game)
                if action == "opened" then
                        game.stats.inc("issues")
                        game.stats.inc("issues_open")
+                       game.save
+                       player.stats.inc("issues")
+                       player.stats.inc("issues_open")
+                       player.save
                else if action == "reopened" then
                        game.stats.inc("issues_open")
+                       game.save
+                       player.stats.inc("issues_open")
+                       player.save
                else if action == "closed" then
                        game.stats.dec("issues_open")
+                       game.save
+                       player.stats.dec("issues_open")
+                       player.save
                end
        end
 end
@@ -133,13 +162,28 @@ redef class PullRequestEvent
 
        # Count opened and closed pull requests.
        redef fun react_stats_event(game) do
+               var player = pull.user.player(game)
                if action == "opened" then
                        game.stats.inc("pulls")
                        game.stats.inc("pulls_open")
+                       game.save
+                       player.stats.inc("pulls")
+                       player.stats.inc("pulls_open")
+                       player.save
                else if action == "reopened" then
                        game.stats.inc("pulls_open")
+                       game.save
+                       player.stats.inc("pulls_open")
+                       player.save
                else if action == "closed" then
                        game.stats.dec("pulls_open")
+                       player.stats.dec("pulls_open")
+                       if pull.merged then
+                               game.stats["commits"] += pull.commits
+                               player.stats["commits"] += pull.commits
+                       end
+                       game.save
+                       player.save
                end
        end
 end