X-Git-Url: http://nitlanguage.org diff --git a/lib/bucketed_game.nit b/lib/bucketed_game.nit index 70866b5..45a439c 100644 --- a/lib/bucketed_game.nit +++ b/lib/bucketed_game.nit @@ -30,26 +30,32 @@ end # Something acting on the game from time to time class Bucketable[G: Game] super Turnable[G] - private var act_at: Int = 0 + private var act_at: nullable Int = null + + # Cancel the previously registered acting turn + # + # Once called, `self.do_turn` will not be invoked until `GameTurn::act_next` + # or `GameTurn::act_in` are called again. + fun cancel_act do act_at = null end # Optiomized organization of `Bucketable` instances class Buckets[G: Game] super Turnable[G] - type Bucket: HashSet[Bucketable[G]] + type BUCKET: HashSet[Bucketable[G]] - private var buckets: Array[Bucket] + private var buckets: Array[BUCKET] is noinit - private var next_bucket: nullable Bucket = null + private var next_bucket: nullable BUCKET = null private var current_bucket_key: Int = -1 init do var n_buckets = 100 - buckets = new Array[Bucket].with_capacity(n_buckets) + buckets = new Array[BUCKET].with_capacity(n_buckets) for b in [0 .. n_buckets [do - buckets[b] = new Bucket + buckets[b] = new HashSet[Bucketable[G]] end end @@ -76,24 +82,29 @@ class Buckets[G: Game] current_bucket_key = key_for_tick(turn.tick) var current_bucket = buckets[current_bucket_key] - next_bucket = new Bucket + var next_bucket = new HashSet[Bucketable[G]] for e in current_bucket do - if e.act_at == turn.tick then - e.do_turn(turn) - else if e.act_at > turn.tick and - key_for_tick(e.act_at) == current_bucket_key - then - next_bucket.as(not null).add(e) + var act_at = e.act_at + if act_at != null then + if turn.tick == act_at then + e.do_turn(turn) + else if act_at > turn.tick and + key_for_tick(act_at) == current_bucket_key + then + next_bucket.add(e) + end end end - buckets[current_bucket_key] = next_bucket.as(not null) + self.next_bucket = next_bucket + buckets[current_bucket_key] = next_bucket end end # Game related event -class GameEvent +interface GameEvent + fun apply( game : ThinGame ) is abstract end # Event raised at the first turn @@ -103,14 +114,14 @@ end # Game logic on the client class ThinGame - var tick: Int protected writable = 0 + var tick: Int = 0 is protected writable end # Game turn on the client class ThinGameTurn[G: ThinGame] - var tick: Int protected writable = 0 + var tick: Int = 0 is protected writable - var events: List[GameEvent] protected writable = new List[GameEvent] + var events: List[GameEvent] = new List[GameEvent] is protected writable init (t: Int) do tick = t end @@ -135,6 +146,12 @@ class GameTurn[G: Game] do game.buckets.add_at(e, tick + t) end + + fun add_event( event : GameEvent ) + do + event.apply( game ) + events.add( event ) + end end # Full game logic @@ -144,6 +161,11 @@ class Game var buckets: Buckets[G] = new Buckets[G] + # Last turn executed in this game + # Can be used to consult the latest events (by the display for example), + # but cannot be used to add new Events. + var last_turn: nullable ThinGameTurn[G] = null + init do end fun do_turn: GameTurn[G] @@ -154,6 +176,8 @@ class Game buckets.do_turn(turn) do_post_turn(turn) + last_turn = turn + tick += 1 return turn