Skip to content

Commit 005e8c5

Browse files
author
Danny Lade
committed
Merge branch 'release/1.3'
features: * Dissolve callback functions into abstract methods in client-layer. ** This is more intuitive and simpler to use then callbacks. fixed: * Fixed player is not alive during spawn and before very first move. * Fixed behavior for bots which sends no steer command. other: * Merged topic and adapter. * Simply set logging level everywhere.
2 parents 79653f3 + 7a0ea7c commit 005e8c5

File tree

7 files changed

+140
-136
lines changed

7 files changed

+140
-136
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@ __pycache__
22
.ipynb_checkpoints/
33
.vscode/
44
.spyproject/
5+
.idea/
56

67
*.egg-info/

setup.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ def __readme__():
2626

2727
setup(
2828
name='traze-client',
29-
version='1.2',
29+
version='1.3',
3030
author="Danny Lade",
3131
author_email="[email protected]",
3232
description=("A client for the simple tron-like multi client online game called 'Traze' which is using MQTT for communication."), # noqa
@@ -44,7 +44,14 @@ def __readme__():
4444
],
4545

4646
classifiers=[
47-
"Development Status :: 5 - Production/Stable",
47+
# Development Status :: 1 - Planning
48+
# Development Status :: 2 - Pre-Alpha
49+
# Development Status :: 3 - Alpha
50+
# Development Status :: 4 - Beta
51+
# Development Status :: 5 - Production/Stable
52+
# Development Status :: 6 - Mature
53+
# Development Status :: 7 - Inactive
54+
"Development Status :: 1 - Planning",
4855
"Topic :: Games/Entertainment :: Simulation",
4956
"Programming Language :: Python :: 3.5",
5057
"License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)", # noqa

traze/adapter.py

Lines changed: 48 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,22 +17,51 @@
1717
@author: Danny Lade
1818
"""
1919
import uuid
20+
import json
2021
import functools
2122

2223
import paho.mqtt.client as mqtt
2324

2425
from .log import setup_custom_logger
25-
from .topic import MqttTopic
2626

2727
__all__ = [
2828
"TrazeMqttAdapter"
2929
]
3030

3131

32+
class _MqttTopic:
33+
34+
def __init__(self, client, name, *args):
35+
def topic_name(topicName, *args):
36+
if not args:
37+
return topicName
38+
return topicName.replace('+', '%s') % (args)
39+
40+
self._client = client
41+
self._name = topic_name(name, *args)
42+
self.functions = set()
43+
44+
def subscribe(self, on_payload_func):
45+
def on_message(client, userdata, message):
46+
payload = json.loads(str(message.payload, 'utf-8'))
47+
for on_payload in self.functions:
48+
on_payload(payload)
49+
50+
if not self.functions:
51+
self._client.subscribe(self._name)
52+
self._client.message_callback_add(self._name, on_message)
53+
54+
if on_payload_func not in self.functions:
55+
self.functions.add(on_payload_func)
56+
57+
def publish(self, obj=None):
58+
self._client.publish(self._name, json.dumps(obj))
59+
60+
3261
class TrazeMqttAdapter:
3362

3463
def __init__(self, host='traze.iteratec.de', port=8883, transport='tcp'):
35-
self.logger = setup_custom_logger(name=type(self).__name__)
64+
self.logger = setup_custom_logger(self)
3665

3766
def _on_connect(client, userdata, flags, rc):
3867
self.logger.info("Connected the MQTT broker.")
@@ -50,16 +79,17 @@ def _on_disconnect(client, userdata, rc):
5079
self._client.connect(host, port)
5180
self._client.loop_start()
5281

53-
def on_heartbeat(self, game_name, on_heartbeat):
54-
# there is no heartbeat from server but the grid-event is a good base
55-
self.__get_topic__('traze/+/grid', game_name).subscribe(on_heartbeat)
56-
82+
#
83+
# world based topic(s)
84+
# - parameters: None
85+
#
5786
def on_game_info(self, on_game_info):
5887
self.__get_topic__('traze/games').subscribe(on_game_info)
5988

60-
def on_player_info(self, game_name, on_player_info):
61-
self.__get_topic__('traze/+/player/+', game_name, self.__client_id__).subscribe(on_player_info) # noqa
62-
89+
#
90+
# game based topic(s)
91+
# - parameters: game_name
92+
#
6393
def on_grid(self, game_name, on_grid):
6494
self.__get_topic__('traze/+/grid', game_name).subscribe(on_grid)
6595

@@ -69,6 +99,13 @@ def on_players(self, game_name, on_players):
6999
def on_ticker(self, game_name, on_ticker):
70100
self.__get_topic__('traze/+/ticker', game_name).subscribe(on_ticker)
71101

102+
def on_player_info(self, game_name, on_player_info):
103+
self.__get_topic__('traze/+/player/+', game_name, self.__client_id__).subscribe(on_player_info) # noqa
104+
105+
#
106+
# player based topic(s)
107+
# - parameters: game_name, player_id/player_name
108+
#
72109
def publish_join(self, game_name, player_name):
73110
self.__get_topic__('traze/+/join', game_name).publish({'name': player_name, 'mqttClientName': self.__client_id__}) # noqa
74111

@@ -81,6 +118,6 @@ def publish_bail(self, game_name, player_id, player_token):
81118
def disconnect(self):
82119
self._client.disconnect()
83120

84-
@functools.lru_cache()
121+
@functools.lru_cache() # singleton by parameter (for same arguments always return the same object)
85122
def __get_topic__(self, topic_name, *args):
86-
return MqttTopic(self._client, topic_name, *args)
123+
return _MqttTopic(self._client, topic_name, *args)

traze/bot.py

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -40,23 +40,13 @@ def __repr__(self):
4040

4141
@classmethod
4242
def from_name(cls, name):
43-
for action in Action:
44-
if action.name == name:
45-
return action
46-
raise ValueError('{} is not a valid action name'.format(name))
43+
return cls.__members__[name]
4744

4845

4946
class BotBase(Player, metaclass=ABCMeta):
50-
def __init__(self, game, name=None):
51-
def on_update():
52-
next_action = None
53-
actions = self.actions
54-
if actions:
55-
next_action = self.next_action(actions)
56-
if next_action:
57-
self.steer(next_action)
5847

59-
super().__init__(game, name, on_update)
48+
def __init__(self, game, name=None):
49+
super().__init__(game, name)
6050

6151
def play(self, count=1, suppress_server_timeout=False):
6252
for i in range(1, count + 1):
@@ -76,13 +66,28 @@ def play(self, count=1, suppress_server_timeout=False):
7666

7767
self.destroy()
7868

69+
def on_update(self):
70+
self.logger.debug("on_update: {}".format((self.x, self.y)))
71+
72+
next_action = None
73+
actions = self.actions
74+
if actions:
75+
next_action = self.next_action(actions)
76+
self.steer(next_action)
77+
78+
def on_dead(self):
79+
self.logger.debug("on_dead: {}".format((self.x, self.y)))
80+
81+
return
82+
7983
@property
8084
def actions(self):
8185
valid_actions = set()
8286
for action in list(Action):
8387
if self.valid(self.x + action.dX, self.y + action.dY):
8488
valid_actions.add(action)
8589

90+
self.logger.debug("valid_actions: {}".format(valid_actions))
8691
return tuple(valid_actions)
8792

8893
@abstractmethod

0 commit comments

Comments
 (0)