Skip to content

Commit 14a38d4

Browse files
committed
First pass on entity transmission filtering system.
1 parent 814e9a7 commit 14a38d4

File tree

6 files changed

+767
-0
lines changed

6 files changed

+767
-0
lines changed
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
# ../entities/transmit.py
2+
3+
"""Provides entity transmission filtering."""
4+
5+
# ============================================================================
6+
# >> IMPORTS
7+
# ============================================================================
8+
# Source.Python
9+
# Core
10+
from core import AutoUnload
11+
# Entities
12+
from entities.entity import Entity
13+
from entities.hooks import EntityCondition
14+
# Filters
15+
from filters.entities import EntityIter
16+
# Listeners
17+
from listeners import on_entity_created_listener_manager
18+
from listeners import on_entity_deleted_listener_manager
19+
20+
21+
# ============================================================================
22+
# >> FORWARD IMPORTS
23+
# ============================================================================
24+
# Source.Python
25+
# Entities
26+
from _entities._transmit import BaseTransmitCriteria
27+
from _entities._transmit import BaseTransmitFilter
28+
from _entities._transmit import TransmitManager
29+
from _entities._transmit import TransmitStates
30+
from _entities._transmit import TransmitTarget
31+
from _entities._transmit import TransmitType
32+
from _entities._transmit import transmit_manager
33+
34+
35+
# ============================================================================
36+
# >> ALL DECLARATION
37+
# ============================================================================
38+
__all__ = [
39+
'BaseTransmitCriteria',
40+
'BaseTransmitFilter',
41+
'TransmitCriteria',
42+
'TransmitFilter',
43+
'TransmitManager',
44+
'TransmitStates',
45+
'TransmitTarget',
46+
'TransmitType',
47+
'transmit_manager',
48+
]
49+
50+
51+
# ============================================================================
52+
# >> CLASSES
53+
# ============================================================================
54+
class TransmitFilter(AutoUnload, BaseTransmitFilter):
55+
"""Decorator class used to register entity transmission filter."""
56+
57+
def __call__(self, callback):
58+
"""Register the given callback and initialize the filter.
59+
60+
:param function callback:
61+
The callback to register.
62+
"""
63+
self.callback = callback
64+
self.initialize()
65+
return self
66+
67+
def initialize(self):
68+
"""Initializes the filter."""
69+
transmit_manager.register_filter(self)
70+
71+
def _unload_instance(self):
72+
"""Unregister ourself as filter."""
73+
transmit_manager.unregister_filter(self)
74+
75+
76+
class TransmitCriteria(AutoUnload, BaseTransmitCriteria):
77+
"""Class used to narrow down entity transmission filtering."""
78+
79+
def __init__(self, conditions, target=TransmitTarget.ENTITY):
80+
"""Initialize the criteria.
81+
82+
:param function/iterable conditions:
83+
Conditions that an entity have to meet in order to match this
84+
criteria.
85+
:param TransmitTarget target:
86+
Whether the criteria is to be checked against the entity being
87+
transmitted or the receiving player.
88+
"""
89+
super().__init__(target)
90+
91+
# Validate and store the given conditions
92+
if callable(conditions):
93+
self.conditions = (conditions,)
94+
else:
95+
for condition in conditions:
96+
if not callable(condition):
97+
raise ValueError(f'"{condition}" is not callable.')
98+
self.conditions = conditions
99+
100+
# Let's test existing entities
101+
for entity in EntityIter():
102+
self[entity.index] = self.test_entity(entity)
103+
104+
# Register our internal listeners
105+
on_entity_created_listener_manager.register_listener(
106+
self._on_entity_created)
107+
on_entity_deleted_listener_manager.register_listener(
108+
self._on_entity_deleted)
109+
110+
def test_entity(self, entity):
111+
"""Test whether the entity matches all the conditions.
112+
113+
:param Entity entity::
114+
The entity to test against all conditions.
115+
116+
:rtype:
117+
bool
118+
"""
119+
for condition in self.conditions:
120+
if not condition(entity):
121+
return False
122+
123+
return True
124+
125+
def _on_entity_created(self, base_entity):
126+
"""Called when an entity is created.
127+
128+
:param BaseEntity base_entity:
129+
The entity that was created.
130+
"""
131+
# Try to grab an index or exit if the entity isn't networked
132+
try:
133+
entity = Entity(base_entity.index)
134+
except ValueError:
135+
return
136+
137+
# Test the entity and set the result
138+
self[entity.index] = self.test_entity(entity)
139+
140+
def _on_entity_deleted(self, base_entity):
141+
"""Called when an entity is being deleted.
142+
143+
:param BaseEntity base_entity:
144+
The entity that is being deleted.
145+
"""
146+
# Try to grab an index or exit if the entity isn't networked
147+
try:
148+
entity_index = base_entity.index
149+
except ValueError:
150+
return
151+
152+
# Mark the entity as no longer matching
153+
del self[entity_index]
154+
155+
def _unload_instance(self):
156+
"""Unregister our internal listeners."""
157+
self.listener.unregister_listener(self._on_entity_created)
158+
on_entity_deleted_listener_manager.unregister_listener(
159+
self._on_entity_deleted)
160+
161+
162+
# For convenience, register some commonly used criterias
163+
TransmitCriteria.is_player = TransmitCriteria(
164+
EntityCondition.is_player)
165+
TransmitCriteria.is_not_player = TransmitCriteria(
166+
EntityCondition.is_not_player)
167+
TransmitCriteria.is_human_player = TransmitCriteria(
168+
EntityCondition.is_human_player)
169+
TransmitCriteria.is_bot_player = TransmitCriteria(
170+
EntityCondition.is_bot_player)
171+
TransmitCriteria.equals_entity_classname = (
172+
lambda *classnames: TransmitCriteria(
173+
EntityCondition.equals_entity_classname(*classnames)))
174+
TransmitCriteria.equals_entity_classname = (
175+
lambda *classnames: TransmitCriteria(
176+
EntityCondition.equals_entity_classname(*classnames)))

src/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ Set(SOURCEPYTHON_ENTITIES_MODULE_HEADERS
222222
core/modules/entities/${SOURCE_ENGINE}/entities_props_wrap.h
223223
core/modules/entities/${SOURCE_ENGINE}/entities_constants_wrap.h
224224
core/modules/entities/entities_entity.h
225+
core/modules/entities/entities_transmit.h
225226
)
226227

227228
Set(SOURCEPYTHON_ENTITIES_MODULE_SOURCES
@@ -238,6 +239,8 @@ Set(SOURCEPYTHON_ENTITIES_MODULE_SOURCES
238239
core/modules/entities/entities_props_wrap.cpp
239240
core/modules/entities/entities_entity.cpp
240241
core/modules/entities/entities_entity_wrap.cpp
242+
core/modules/entities/entities_transmit.cpp
243+
core/modules/entities/entities_transmit_wrap.cpp
241244
)
242245

243246
# ------------------------------------------------------------------

0 commit comments

Comments
 (0)