Skip to content

Added networked variants of the entity listeners. #351

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Sep 27, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,20 @@ Called when an entity has been created.
pass


OnNetworkedEntityCreated
---------------

Called when a networked entity has been created.

.. code-block:: python

from listeners import OnNetworkedEntityCreated

@OnNetworkedEntityCreated
def on_networked_entity_created(entity):
pass


OnEntityDeleted
---------------

Expand All @@ -216,6 +230,20 @@ Called when an entity gets deleted.
pass


OnNetworkedEntityDeleted
---------------

Called when a networked entity gets deleted.

.. code-block:: python

from listeners import OnNetworkedEntityDeleted

@OnNetworkedEntityDeleted
def on_networked_entity_deleted(entity):
pass


OnEntityOutput
--------------

Expand Down Expand Up @@ -252,6 +280,22 @@ Called before an entity has been spawned.
.. note:: This listener gets only called in Black Mesa: Source.


OnNetworkedEntityPreSpawned
------------------

Called before a networked entity has been spawned.

.. code-block:: python

from listeners import OnNetworkedEntityPreSpawned

@OnNetworkedEntityPreSpawned
def on_networked_entity_pre_spawned(entity):
pass

.. note:: This listener gets only called in Black Mesa: Source.


OnEntitySpawned
---------------

Expand All @@ -266,6 +310,20 @@ Called when an entity has been spawned.
pass


OnNetworkedEntitySpawned
---------------

Called when a networked entity has been spawned.

.. code-block:: python

from listeners import OnNetworkedEntitySpawned

@OnNetworkedEntitySpawned
def on_networked_entity_spawned(entity):
pass


OnLevelInit
-----------

Expand Down
14 changes: 4 additions & 10 deletions addons/source-python/packages/source-python/entities/_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -785,18 +785,12 @@ def set_parent(self, parent, attachment=INVALID_ATTACHMENT_INDEX):
# =============================================================================
# NOTE: This callback is called by sp_main.cpp after all registered entity
# deletion listeners have been called.
def _on_entity_deleted(base_entity):
"""Called when an entity is removed.
def _on_networked_entity_deleted(index):
"""Called when a networked entity is removed.

:param BaseEntity base_entity:
The removed entity.
:param int index:
The removed entity index.
"""
try:
# Get the index of the entity...
index = base_entity.index
except ValueError:
return

# Loop through all delays...
for delay in _entity_delays.pop(index, ()):

Expand Down
33 changes: 19 additions & 14 deletions addons/source-python/packages/source-python/entities/dictionary.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from entities.entity import Entity
from entities.helpers import index_from_inthandle
# Listeners
from listeners import on_entity_deleted_listener_manager
from listeners import on_networked_entity_deleted_listener_manager


# ============================================================================
Expand All @@ -42,8 +42,8 @@ def __init__(self, factory=Entity, *args, **kwargs):
self._kwargs = kwargs

# Register our OnEntityDeleted listener...
on_entity_deleted_listener_manager.register_listener(
self._on_entity_deleted)
on_networked_entity_deleted_listener_manager.register_listener(
self._on_networked_entity_deleted)

# Initialize the dictionary...
super().__init__()
Expand Down Expand Up @@ -79,22 +79,27 @@ def from_inthandle(self, inthandle):
def on_automatically_removed(self, index):
"""Called when an index is automatically removed."""

def _on_entity_deleted(self, base_entity):
"""OnEntityDeleted listener callback."""
try:
# Get the index of the entity...
index = base_entity.index
except ValueError:
def _on_networked_entity_deleted(self, entity):
"""Internal networked entity deletion callback.

:param Entity entity:
The networked entity being removed.
"""
# Get the index of the entity
index = entity.index

# No need to go further if there is no object associated to this index
if index not in self:
return

if index in self:
try:
# Call the deletion callback for the index...
self.on_automatically_removed(index)

finally:
# Remove the index from the dictionary...
super().__delitem__(index)

def _unload_instance(self):
"""Unregister our OnEntityDeleted listener."""
on_entity_deleted_listener_manager.unregister_listener(
self._on_entity_deleted)
"""Unregister our networked entity deletion listener."""
on_networked_entity_deleted_listener_manager.unregister_listener(
self._on_networked_entity_deleted)
12 changes: 5 additions & 7 deletions addons/source-python/packages/source-python/entities/hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
# Filters
from filters.entities import EntityIter
# Listeners
from listeners import OnEntityCreated
from listeners import OnNetworkedEntityCreated
# Entities
from entities.entity import Entity
# Players
Expand Down Expand Up @@ -219,9 +219,7 @@ def initialize(self, index):
# =============================================================================
# >> LISTENERS
# =============================================================================
@OnEntityCreated
def on_entity_created(base_entity):
"""Called when a new entity has been created."""
if not base_entity.is_networked():
return
_waiting_entity_hooks.initialize(base_entity.index)
@OnNetworkedEntityCreated
def on_networked_entity_created(entity):
"""Called when a new networked entity has been created."""
_waiting_entity_hooks.initialize(entity.index)
36 changes: 36 additions & 0 deletions addons/source-python/packages/source-python/listeners/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,13 @@
from _listeners import on_edict_allocated_listener_manager
from _listeners import on_edict_freed_listener_manager
from _listeners import on_entity_pre_spawned_listener_manager
from _listeners import on_networked_entity_pre_spawned_listener_manager
from _listeners import on_entity_created_listener_manager
from _listeners import on_networked_entity_created_listener_manager
from _listeners import on_entity_spawned_listener_manager
from _listeners import on_networked_entity_spawned_listener_manager
from _listeners import on_entity_deleted_listener_manager
from _listeners import on_networked_entity_deleted_listener_manager
from _listeners import on_data_loaded_listener_manager
from _listeners import on_combiner_pre_cache_listener_manager
from _listeners import on_data_unloaded_listener_manager
Expand Down Expand Up @@ -91,11 +95,15 @@
'OnEdictAllocated',
'OnEdictFreed',
'OnEntityCreated',
'OnNetworkedEntityCreated',
'OnEntityDeleted',
'OnNetworkedEntityDeleted',
'OnEntityOutput',
'OnEntityOutputListenerManager',
'OnEntityPreSpawned',
'OnNetworkedEntityPreSpawned',
'OnEntitySpawned',
'OnNetworkedEntitySpawned',
'OnLevelInit',
'OnLevelShutdown',
'OnLevelEnd',
Expand Down Expand Up @@ -125,10 +133,14 @@
'on_edict_allocated_listener_manager',
'on_edict_freed_listener_manager',
'on_entity_created_listener_manager',
'on_networked_entity_created_listener_manager',
'on_entity_deleted_listener_manager',
'on_networked_entity_deleted_listener_manager',
'on_entity_output_listener_manager',
'on_entity_pre_spawned_listener_manager',
'on_networked_entity_pre_spawned_listener_manager',
'on_entity_spawned_listener_manager',
'on_networked_entity_spawned_listener_manager',
'on_level_end_listener_manager',
'on_level_init_listener_manager',
'on_level_shutdown_listener_manager',
Expand Down Expand Up @@ -355,24 +367,48 @@ class OnEntityPreSpawned(ListenerManagerDecorator):
manager = on_entity_pre_spawned_listener_manager


class OnNetworkedEntityPreSpawned(ListenerManagerDecorator):
"""Register/unregister a OnNetworkedEntityPreSpawned listener."""

manager = on_networked_entity_pre_spawned_listener_manager


class OnEntityCreated(ListenerManagerDecorator):
"""Register/unregister a OnEntityCreated listener."""

manager = on_entity_created_listener_manager


class OnNetworkedEntityCreated(ListenerManagerDecorator):
"""Register/unregister a OnNetworkedEntityCreated listener."""

manager = on_networked_entity_created_listener_manager


class OnEntitySpawned(ListenerManagerDecorator):
"""Register/unregister a OnEntitySpawned listener."""

manager = on_entity_spawned_listener_manager


class OnNetworkedEntitySpawned(ListenerManagerDecorator):
"""Register/unregister a OnNetworkedEntitySpawned listener."""

manager = on_networked_entity_spawned_listener_manager


class OnEntityDeleted(ListenerManagerDecorator):
"""Register/unregister a OnEntityDeleted listener."""

manager = on_entity_deleted_listener_manager


class OnNetworkedEntityDeleted(ListenerManagerDecorator):
"""Register/unregister a OnNetworkedEntityDeleted listener."""

manager = on_networked_entity_deleted_listener_manager


class OnDataLoaded(ListenerManagerDecorator):
"""Register/unregister a OnDataLoaded listener."""

Expand Down
8 changes: 8 additions & 0 deletions src/core/modules/listeners/listeners_wrap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,13 @@ DEFINE_MANAGER_ACCESSOR(OnQueryCvarValueFinished)
DEFINE_MANAGER_ACCESSOR(OnServerActivate)
DEFINE_MANAGER_ACCESSOR(OnTick)
DEFINE_MANAGER_ACCESSOR(OnEntityPreSpawned)
DEFINE_MANAGER_ACCESSOR(OnNetworkedEntityPreSpawned)
DEFINE_MANAGER_ACCESSOR(OnEntityCreated)
DEFINE_MANAGER_ACCESSOR(OnNetworkedEntityCreated)
DEFINE_MANAGER_ACCESSOR(OnEntitySpawned)
DEFINE_MANAGER_ACCESSOR(OnNetworkedEntitySpawned)
DEFINE_MANAGER_ACCESSOR(OnEntityDeleted)
DEFINE_MANAGER_ACCESSOR(OnNetworkedEntityDeleted)
DEFINE_MANAGER_ACCESSOR(OnDataLoaded)
DEFINE_MANAGER_ACCESSOR(OnCombinerPreCache)
DEFINE_MANAGER_ACCESSOR(OnDataUnloaded)
Expand Down Expand Up @@ -153,9 +157,13 @@ void export_listener_managers(scope _listeners)
_listeners.attr("on_tick_listener_manager") = object(ptr(GetOnTickListenerManager()));

_listeners.attr("on_entity_pre_spawned_listener_manager") = object(ptr(GetOnEntityPreSpawnedListenerManager()));
_listeners.attr("on_networked_entity_pre_spawned_listener_manager") = object(ptr(GetOnNetworkedEntityPreSpawnedListenerManager()));
_listeners.attr("on_entity_created_listener_manager") = object(ptr(GetOnEntityCreatedListenerManager()));
_listeners.attr("on_networked_entity_created_listener_manager") = object(ptr(GetOnNetworkedEntityCreatedListenerManager()));
_listeners.attr("on_entity_spawned_listener_manager") = object(ptr(GetOnEntitySpawnedListenerManager()));
_listeners.attr("on_networked_entity_spawned_listener_manager") = object(ptr(GetOnNetworkedEntitySpawnedListenerManager()));
_listeners.attr("on_entity_deleted_listener_manager") = object(ptr(GetOnEntityDeletedListenerManager()));
_listeners.attr("on_networked_entity_deleted_listener_manager") = object(ptr(GetOnNetworkedEntityDeletedListenerManager()));

_listeners.attr("on_data_loaded_listener_manager") = object(ptr(GetOnDataLoadedListenerManager()));
_listeners.attr("on_combiner_pre_cache_listener_manager") = object(ptr(GetOnCombinerPreCacheListenerManager()));
Expand Down
51 changes: 47 additions & 4 deletions src/core/sp_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -604,6 +604,17 @@ void CSourcePython::OnEdictFreed( const edict_t *edict )
void CSourcePython::OnEntityPreSpawned( CBaseEntity *pEntity )
{
CALL_LISTENERS(OnEntityPreSpawned, ptr((CBaseEntityWrapper*) pEntity));

GET_LISTENER_MANAGER(OnNetworkedEntityPreSpawned, on_networked_entity_pre_spawned_manager);
if (!on_networked_entity_pre_spawned_manager->GetCount())
return;

unsigned int uiIndex;
if (!IndexFromBaseEntity(pEntity, uiIndex))
return;

static object Entity = import("entities").attr("entity").attr("Entity");
CALL_LISTENERS_WITH_MNGR(on_networked_entity_pre_spawned_manager, Entity(uiIndex));
}
#endif

Expand All @@ -619,21 +630,53 @@ void CSourcePython::OnEntityCreated( CBaseEntity *pEntity )
InitHooks(pEntity);

CALL_LISTENERS(OnEntityCreated, ptr((CBaseEntityWrapper*) pEntity));

GET_LISTENER_MANAGER(OnNetworkedEntityCreated, on_networked_entity_created_manager);
if (!on_networked_entity_created_manager->GetCount())
return;

unsigned int uiIndex;
if (!IndexFromBaseEntity(pEntity, uiIndex))
return;

static object Entity = import("entities").attr("entity").attr("Entity");
CALL_LISTENERS_WITH_MNGR(on_networked_entity_created_manager, Entity(uiIndex));
}

void CSourcePython::OnEntitySpawned( CBaseEntity *pEntity )
{
CALL_LISTENERS(OnEntitySpawned, ptr((CBaseEntityWrapper*) pEntity));

GET_LISTENER_MANAGER(OnNetworkedEntitySpawned, on_networked_entity_spawned_manager);
if (!on_networked_entity_spawned_manager->GetCount())
return;

unsigned int uiIndex;
if (!IndexFromBaseEntity(pEntity, uiIndex))
return;

static object Entity = import("entities").attr("entity").attr("Entity");
CALL_LISTENERS_WITH_MNGR(on_networked_entity_spawned_manager, Entity(uiIndex));
}

void CSourcePython::OnEntityDeleted( CBaseEntity *pEntity )
{
object oEntity(ptr((CBaseEntityWrapper*) pEntity));
CALL_LISTENERS(OnEntityDeleted, oEntity);
CALL_LISTENERS(OnEntityDeleted, ptr((CBaseEntityWrapper*) pEntity));

unsigned int uiIndex;
if (!IndexFromBaseEntity(pEntity, uiIndex))
return;

GET_LISTENER_MANAGER(OnNetworkedEntityDeleted, on_networked_entity_deleted_manager);
if (on_networked_entity_deleted_manager->GetCount())
{
static object Entity = import("entities").attr("entity").attr("Entity");
CALL_LISTENERS_WITH_MNGR(on_networked_entity_deleted_manager, Entity(uiIndex));
}

// Invalidate the internal entity cache once all callbacks have been called.
static object _on_entity_deleted = import("entities").attr("_base").attr("_on_entity_deleted");
_on_entity_deleted(oEntity);
static object _on_networked_entity_deleted = import("entities").attr("_base").attr("_on_networked_entity_deleted");
_on_networked_entity_deleted(uiIndex);
}

void CSourcePython::OnDataLoaded( MDLCacheDataType_t type, MDLHandle_t handle )
Expand Down