e9835f3027ce9564b5379400052e891b3e0cbe5a
[nit.git] / contrib / tinks / src / client / context.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 # Provides context to abstract the exchanges with a local game or a remote game
16 module context
17
18 import gamnit::network
19
20 import game
21 intrude import game::players
22 import server
23
24 # Interface to a game
25 abstract class GameContext
26
27 # The current game
28 var game: TGame
29
30 # The local player on this client, if any
31 var local_player: nullable Player = null
32
33 # Do a turn
34 fun do_turn: TTurn is abstract
35 end
36
37 # Simple local single-player game
38 class LocalGameContext
39 super GameContext
40
41 noautoinit
42
43 init
44 do
45 # Create basic game
46 game = new TGame
47 var setup_turn = game.do_turn
48
49 var local_player = new Player
50 game.players.add local_player
51 self.local_player = local_player
52 setup_turn.spawn_tank local_player
53 end
54
55 redef fun do_turn do return game.do_turn
56 end
57
58 # Multiplayer game running on a remote server
59 class RemoteGameContext
60 super GameContext
61
62 autoinit remote_server
63
64 # Remote server that controls the `game`
65 var remote_server: RemoteServer
66
67 # Setup `game` from `remote_server`
68 fun setup
69 do
70 var game = remote_server.reader.deserialize
71 var errors = remote_server.reader.errors
72 assert errors.is_empty else print_error errors.join("\n")
73 assert game isa TGame else print_error "Server sent a {game.class_name}"
74 self.game = game
75
76 var local_player = remote_server.reader.deserialize
77 errors = remote_server.reader.errors
78 assert errors.is_empty else print_error errors.join("\n")
79 assert local_player isa Player else print_error "Server sent a {local_player.class_name}"
80 self.local_player = local_player
81 end
82
83 redef fun do_turn
84 do
85 # Get turn from server
86 var turn = remote_server.reader.deserialize
87 var errors = remote_server.reader.errors
88 assert errors.is_empty else print_error errors.join("\n")
89 assert turn isa TTurn else print_error "Server sent a {turn.class_name}"
90
91 # Apply the turn locally
92 game.apply_turn turn
93
94 # Send orders to server
95 var local_player = local_player
96 if local_player != null then
97 remote_server.writer.serialize local_player.orders
98 remote_server.socket.flush
99 local_player.orders = new Array[TOrder]
100 end
101
102 return turn
103 end
104 end
105
106 # Local game ran by a server accepting other clients
107 class LocalServerContext
108 super LocalGameContext
109
110 # The server managing the game and other clients
111 var server = new Server(default_listening_port)
112
113 init do server.game = game
114
115 redef fun do_turn do return server.do_turn
116 end