/** * One of the two classes that make up a core of event system in Acedia. * * `Events` (or it's child) class shouldn't be instantiated. * Usually module would provide '...Events' class that defines * certain set of static functions that can generate event calls to * all it's active listeners. * If you're simply using modules someone made, - * you don't need to bother yourself with further specifics. * If you wish to create your own event generator, * then first create a `...ListenerBase` object * (more about it in the description of `Listener` class) * and set `relatedListener` variable to point to it's class. * Then for each event create a caller function in your `Event` class, * following this template: * ____________________________________________________________________________ * | static function CallEVENT_NAME() * | { * | local int i; * | local array< class > listeners; * | listeners = GetListeners(); * | for (i = 0; i < listeners.length; i += 1) * | { * | class<...ListenerBase>(listeners[i]) * | .static.EVENT_NAME(); * | } * | } * |___________________________________________________________________________ * If each listener must indicate whether it gives it's permission for * something to happen, then use this template: * ____________________________________________________________________________ * | static function CallEVENT_NAME() * | { * | local int i; * | local bool result; * | local array< class > listeners; * | listeners = GetListeners(); * | for (i = 0; i < listeners.length; i += 1) * | { * | result = class<...ListenerBase>(listeners[i]) * | .static.EVENT_NAME(); * | if (!result) return false; * | } * | return true; * | } * |___________________________________________________________________________ * For concrete example look at * `MutatorEvents` and `MutatorListenerBase`. * Copyright 2020 Anton Tarasenko *------------------------------------------------------------------------------ * This file is part of Acedia. * * Acedia is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3 of the License, or * (at your option) any later version. * * Acedia is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Acedia. If not, see . */ class Events extends AcediaObject abstract; var private array< class > listeners; // Reference to the base class of listeners that are allowed to listen to // these events var public const class relatedListener; // Event class can also auto-spawn a `Service`, // in case it's require to generate events var public const class connectedServiceClass; // Set this to `true`if you want `connectedServiceClass` service to also // auto-shutdown whenever no-one listens to the events. var public const bool shutDownServiceWithoutListeners; static public final function array< class > GetListeners() { return default.listeners; } // Make given listener active. // If listener was already activated also returns 'false'. static public final function bool ActivateListener(class newListener) { local int i; if (newListener == none) return false; if (!ClassIsChildOf(newListener, default.relatedListener)) return false; // Spawn service, if absent if ( default.listeners.length == 0 && default.connectedServiceClass != none) { default.connectedServiceClass.static.Require(); } // Add listener for (i = 0;i < default.listeners.length;i += 1) { if (default.listeners[i] == newListener) { return false; } } default.listeners[default.listeners.length] = newListener; return true; } // Make given listener inactive. // If listener wasn't active returns 'false'. static public final function bool DeactivateListener(class listener) { local int i; local bool removedListener; local Service service; if (listener == none) return false; // Remove listener for (i = 0; i < default.listeners.length; i += 1) { if (default.listeners[i] == listener) { default.listeners.Remove(i, 1); removedListener = true; break; } } // Remove unneeded service if ( default.shutDownServiceWithoutListeners && default.listeners.length == 0 && default.connectedServiceClass != none) { service = Service(default.connectedServiceClass.static.GetInstance()); if (service != none) { service.Destroy(); } } return removedListener; } static public final function bool IsActiveListener(class listener) { local int i; if (listener == none) return false; for (i = 0; i < default.listeners.length; i += 1) { if (default.listeners[i] == listener) { return true; } } return false; } defaultproperties { relatedListener = class'Listener' }