Skip to content

Commit

Permalink
add priority keyword to add_system() method
Browse files Browse the repository at this point in the history
    Add a `priority` attribute to `ecs.models.Systems` and sort
    `ecs.managers.SystemManager._systems` by it every time a system is added.
    Also add a new test case to ensure that system with the same priority
    end up being executed in the order they were added and adjust
    `test_systems_added` and `test_remove_system`.
  • Loading branch information
pmrv committed Mar 14, 2014
1 parent d0599c3 commit 4499db0
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 5 deletions.
7 changes: 6 additions & 1 deletion ecs/managers.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,11 +157,13 @@ def systems(self):
"""
return self._systems

def add_system(self, system_instance):
def add_system(self, system_instance, priority=0):
"""Add a :class:`ecs.models.System` instance to the manager.
:param system_instance: instance of a system
:param priority: non-negative integer (default: 0)
:type system_instance: :class:`ecs.models.System`
:type priority: :class:`int`
:raises: :class:`ecs.exceptions.DuplicateSystemTypeError` when the
system type is already present in this manager
:raises: :class:`ecs.exceptions.SystemAlreadyAddedToManagerError` when
Expand All @@ -178,6 +180,9 @@ def add_system(self, system_instance):
self._system_types[system_type] = system_instance
self._systems.append(system_instance)

system_instance.priority = priority
self._systems.sort(key=lambda x: x.priority)

def remove_system(self, system_type):
"""Tell the manager to no longer run the system of this type.
Expand Down
4 changes: 4 additions & 0 deletions ecs/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ def __init__(self):
self.system_manager = None
"""The system manager to which this system belongs. Again, a system is
only allowed to belong to one at a time."""
self.priority = None
"""The priority for this system when the system manager runs
:meth:`ecs.managers.SystemManager.update()`. Must be a non-negative
integer with 0 being the highest priority."""

@abstractmethod
def update(self, dt):
Expand Down
26 changes: 22 additions & 4 deletions tests/test_managers.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import re
import random

from pytest import fixture, raises
import pytest
Expand Down Expand Up @@ -128,7 +129,7 @@ def system_types(self):
return [
type('System' + str(i),
(System,),
{'update': MagicMock()})
{'update': MagicMock(), 'order': i})
for i in range(5)]

@fixture
Expand All @@ -139,13 +140,15 @@ def systems(self, system_types):
def manager(self, systems):
sm = SystemManager(sentinel.entity_manager)
for system in systems:
sm.add_system(system)
sm.add_system(system, priority=random.randrange(4))
return sm

class TestAddSystem(object):
def test_systems_added(self, manager, systems):
# add_system was called normally in the fixture.
assert manager.systems == systems
# since add_system sorts the manager.systems
# we switch to sets for easy comparing
assert set(manager.systems) == set(systems)

def test_entity_manager_set(self, manager):
for system in manager.systems:
Expand All @@ -155,6 +158,20 @@ def test_system_manager_set(self, manager):
for system in manager.systems:
assert system.system_manager == manager

class TestPriority(object):
def test_obeys_order(self, manager, systems):
old_priority = -1
old_order = -1
for s in manager.systems:
priority = s.priority
order = s.order
assert old_priority <= priority
if priority == old_priority:
assert old_order < order

old_priority = priority
old_order = old_order

class TestDuplicate(object):
def test_raises_error(self, manager, systems):
with raises(DuplicateSystemTypeError) as exc_info:
Expand Down Expand Up @@ -194,7 +211,8 @@ def test_system_and_entity_managers_not_changed(
class TestRemoveSystem(object):
def test_remove_system(self, manager, systems, system_types):
manager.remove_system(system_types[0])
assert manager.systems == systems[1:]
# using sets for the same reason as in test_systems_added
assert set(manager.systems) == set(systems[1:])

def test_entity_manager_unset(self, manager, systems, system_types):
manager.remove_system(system_types[0])
Expand Down

0 comments on commit 4499db0

Please sign in to comment.