Skip to content

Instantly share code, notes, and snippets.

@jalbright015
Created April 10, 2021 02:40
Show Gist options
  • Save jalbright015/3b3a2364d678fa0f06f9913181ddb31d to your computer and use it in GitHub Desktop.
Save jalbright015/3b3a2364d678fa0f06f9913181ddb31d to your computer and use it in GitHub Desktop.
/*
// events.c by Panic@Astaria 9/2008
// Basic observer pattern. Exposes a group of events and allows
// event subscribers to be notified of changes.
- Exposed a set and query for _subscriber.
- Uncommented the create and remove functions so that everything can call functions
here instead of inheriting. This way everything can query for any event from
any source.
Jezu@Astaria 08.30.2019
*/
// Definitions
#include <config.h>
#include <mudlib.h>
#include <events.h>
#include <iterator.h>
// Instance variables
static mapping _events = ([ ]) ;
static object _dispatcher ;
nomask void add_subscriber( string eventname, object receiver );
object _subscriber;
// NB: Events and Event Subscribers are intended to be inherited
// into other classes. If you need stand alone event handling,
// inherit from this class and add the following code.
//
void create()
{
seteuid(getuid());
}
// This is commented because it was being scoped by objects and bypassing their
// intended remove() functions. We may be able to do without this function
// anyways. I am not entirely sure what it's intended purpose is.
/*
void remove()
{
destruct(this_object());
}
*/
object set_subscriber(object subscriber) { _subscriber = subscriber; return _subscriber; } // Jezu
object query_subscriber() { return _subscriber; } // Jezu
public mapping query_events()
{
return _events;
}
/// <summary>
/// Encapsulated singleton for dispatcher instantiation. Ultimately
/// intended as an extension point for alternate dispatch strategies
/// if they're needed in the future.
/// </summary>
/// <returns>A reference to the dispatcher.</returns>
private object get_dispatcher()
{
if (!_dispatcher)
_dispatcher = load_object( DISPATCHER );
return _dispatcher;
}
/// <summary>
/// Returns an iterator for receivers subscribed to the specified event.
/// </summary>
/// <param name="eventname">The event name.</param>
/// <returns>An iterator for a collection of receivers.</returns>
nomask object event_iterator( string eventname )
{
object oIterator ;
seteuid(getuid());
if( !eventname || !sizeof(_events[eventname]) )
{
return new( NULL_ITERATOR ) ;
}
else
{
oIterator = new( ARRAY_ITERATOR ) ;
oIterator->set_collection( _events[eventname] ) ;
return oIterator ;
}
}
/// <summary>
/// Create an empty event collection for the specified event name.
/// </summary>
/// <param name="eventname">The event name.</param>
nomask void add_event( string eventname )
{
object subscriber;
if (!eventname || eventname == "")
return;
if (!_events[eventname])
{
_events[eventname] = ({ }) ;
// Jezu
if ( !objectp(subscriber = query_subscriber()) )
subscriber = set_subscriber(load_object(SUBSCRIBER));
if ( objectp(subscriber) )
add_subscriber( eventname, subscriber);
// -Jezu
}
}
/// <summary>
/// Removes an event collection for the specified event name.
/// </summary>
/// <param name="eventname">The event name.</param>
nomask void remove_event( string eventname )
{
if (!eventname)
return;
if (_events[eventname])
map_delete( _events, eventname ) ;
}
/// <summary>
/// Fires the specified event.
/// </summary>
/// <param name="eventname">The event name.</param>
/// <param name="state">The state.</param>
nomask varargs void fire_event( string eventname, mapping state )
{
if (!eventname)
return;
if (_events[eventname])
get_dispatcher()->notify_subscribers( eventname, previous_object(), state, event_iterator(eventname) );
//get_dispatcher()->notify_subscribers( eventname, this_object(), state, event_iterator(eventname) );
}
/// <summary>
/// Subscribes a receiver to the specified event name.
/// </summary>
/// <param name="eventname">The event name.</param>
/// <param name="receiver">The receiver.</param>
nomask void add_subscriber( string eventname, object receiver )
{
object *receivers;
if (!eventname || !receiver )
return ;
// Jezu - Added member_array check
if (_events[eventname] && member_array(receiver, _events[eventname]) == -1 )
_events[eventname] += ({ receiver }) ;
}
/// <summary>
/// Unsubscribes a receiver from the specified event name.
/// </summary>
/// <param name="eventname">The eventname.</param>
/// <param name="receiver">The receiver.</param>
nomask void remove_subscriber( string eventname, object receiver )
{
if (!eventname || !receiver )
return ;
if (_events[eventname])
_events[eventname] -= ({ receiver }) ;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment