Browse Source

Refactor `SideEffect`s to work better with `UnflectApi`

pull/12/head
Anton Tarasenko 2 years ago
parent
commit
f51cf8ed64
  1. 2
      sources/BaseAPI/Global.uc
  2. 2
      sources/Gameplay/KF1Frontend/Health/KF1_HealthComponent.uc
  3. 115
      sources/KFImplementation/Core/KF1_SideEffectAPI.uc
  4. 2
      sources/KFImplementation/Server/ServerSideEffects.uc
  5. 2
      sources/KFImplementation/Server/Unreal/BroadcastsAPI/BroadcastEventsObserver.uc
  6. 65
      sources/KFImplementation/Server/Unreal/BroadcastsAPI/BroadcastSideEffect.uc
  7. 51
      sources/KFImplementation/Server/Unreal/BroadcastsAPI/KF1_BroadcastAPI.uc
  8. 43
      sources/KFImplementation/Server/Unreal/GameRulesAPI/GameRulesSideEffect.uc
  9. 36
      sources/KFImplementation/Server/Unreal/GameRulesAPI/KF1_GameRulesAPI.uc
  10. 164
      sources/LevelAPI/API/SideEffects/SideEffect.uc
  11. 76
      sources/LevelAPI/API/SideEffects/SideEffectAPI.uc
  12. 5
      sources/LevelAPI/AcediaAdapter.uc
  13. 8
      sources/LevelAPI/CoreGlobal.uc

2
sources/BaseAPI/Global.uc

@ -35,6 +35,7 @@ class Global extends Object;
// For getting instance of [`Global`] from any object.
var protected Global myself;
var public SideEffectAPI sideEffects;
var public RefAPI ref;
var public BoxAPI box;
var public MathAPI math;
@ -78,6 +79,7 @@ protected function Initialize() {
memory = new class'MemoryAPI';
memory._constructor();
// `TextAPI` and `CollectionsAPI` need to be loaded before `LoggerAPI`
sideEffects = SideEffectAPI(memory.Allocate(class'SideEffectAPI'));
ref = RefAPI(memory.Allocate(class'RefAPI'));
box = BoxAPI(memory.Allocate(class'BoxAPI'));
text = TextAPI(memory.Allocate(class'TextAPI'));

2
sources/Gameplay/KF1Frontend/Health/KF1_HealthComponent.uc

@ -67,7 +67,7 @@ private final function TryReplaceDamageTypes()
return;
}
triedToReplaceDamageTypes = true;
if (!class'SideEffects'.default.allowReplacingDamageTypes)
if (!class'ServerSideEffects'.default.allowReplacingDamageTypes)
{
_.logger.Auto(warnReplacingDamageTypesForbidden);
return;

115
sources/KFImplementation/Core/KF1_SideEffectAPI.uc

@ -1,115 +0,0 @@
/**
* Standard implementation for simple API for managing a list of
* `SideEffect` info objects: can add, remove, return all and by package.
* Copyright 2022 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 <https://www.gnu.org/licenses/>.
*/
class KF1_SideEffectAPI extends SideEffectAPI;
var private array<SideEffect> activeSideEffects;
public function array<SideEffect> GetAll()
{
local int i;
for (i = 0; i < activeSideEffects.length; i += 1) {
activeSideEffects[i].NewRef();
}
return activeSideEffects;
}
public function SideEffect GetClass(class<SideEffect> sideEffectClass)
{
local int i;
if (sideEffectClass == none) {
return none;
}
for (i = 0; i < activeSideEffects.length; i += 1)
{
if (activeSideEffects[i].class == sideEffectClass)
{
activeSideEffects[i].NewRef();
return activeSideEffects[i];
}
}
return none;
}
public function array<SideEffect> GetFromPackage(BaseText packageName)
{
local int i;
local Text nextPackage;
local array<SideEffect> result;
if (packageName == none) {
return result;
}
for (i = 0; i < activeSideEffects.length; i += 1)
{
nextPackage = activeSideEffects[i].GetPackage();
if (nextPackage.Compare(packageName, SCASE_INSENSITIVE))
{
activeSideEffects[i].NewRef();
result[result.length] = activeSideEffects[i];
}
_.memory.Free(nextPackage);
}
return result;
}
public function bool Add(SideEffect newSideEffect)
{
local int i;
if (newSideEffect == none) {
return false;
}
for (i = 0; i < activeSideEffects.length; i += 1)
{
if (activeSideEffects[i].class == newSideEffect.class) {
return false;
}
}
newSideEffect.NewRef();
activeSideEffects[activeSideEffects.length] = newSideEffect;
return true;
}
public function bool RemoveClass(
class<SideEffect> sideEffectClass)
{
local int i;
if (sideEffectClass == none) {
return false;
}
for (i = 0; i < activeSideEffects.length; i += 1)
{
if (activeSideEffects[i].class == sideEffectClass)
{
_.memory.Free(activeSideEffects[i]);
activeSideEffects.Remove(i, 1);
return true;
}
}
return false;
}
defaultproperties
{
}

2
sources/LevelAPI/SideEffects.uc → sources/KFImplementation/Server/ServerSideEffects.uc

@ -19,7 +19,7 @@
* You should have received a copy of the GNU General Public License
* along with Acedia. If not, see <https://www.gnu.org/licenses/>.
*/
class SideEffects extends AcediaObject
class ServerSideEffects extends AcediaObject
dependson(BroadcastAPI)
abstract
config(AcediaSystem);

2
sources/KFImplementation/Server/Unreal/BroadcastsAPI/BroadcastEventsObserver.uc

@ -207,7 +207,7 @@ var private Broadcast_OnHandleTextFor_Signal onHandleTextFor;
public final function Initialize(ServerUnrealService service)
{
usedInjectionLevel =
class'SideEffects'.default.broadcastHandlerInjectionLevel;
class'ServerSideEffects'.default.broadcastHandlerInjectionLevel;
if (usedInjectionLevel == BHIJ_Root) {
Disable('Tick');
}

65
sources/KFImplementation/Server/Unreal/BroadcastsAPI/BroadcastSideEffect.uc

@ -1,65 +0,0 @@
/**
* Object representing a side effect introduced into the game/server.
* Side effects in Acedia refer to changes that aren't a part of mod's main
* functionality, but rather something necessary to make that functionality
* possible that might also affect how other mods work.
* This is a simple data container that is meant to describe relevant
* changes to the human user.
* Copyright 2022 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 <https://www.gnu.org/licenses/>.
*/
class BroadcastSideEffect extends SideEffect
dependson(BroadcastAPI);
public final function Initialize(BroadcastAPI.InjectionLevel usedInjectionLevel)
{
sideEffectName =
_.text.FromString("AcediaCore's `BroadcastHandler` injected");
sideEffectDescription =
_.text.FromString("Handling text and localized messages between server"
@ "and clients requires AcediaCore to add its own `BroadcastHandler`"
@ "into their linked list."
@ "This is normal, since `BroadcastHandler` class was designed to allow"
@ "mods to do that, however, for full functionality Acedia requires to"
@ "inject it as the very first element (`BHIJ_Root` level injection),"
@ "since some of the events become otherwise inaccessible."
@ "This can result in incompatibility with other mods that are trying"
@ "to do the same."
@ "For that reason AcediaCore can also inject its `BroadcastHandler` as"
@ "`BHIJ_Registered`.");
sideEffectPackage = _.text.FromString("AcediaCore");
sideEffectSource = _.text.FromString("UnrealAPI");
if (usedInjectionLevel == BHIJ_Root)
{
sideEffectStatus =
_.text.FromFormattedString("{$TextPositive BHIJ_Root}");
}
else if (usedInjectionLevel == BHIJ_Registered)
{
sideEffectStatus =
_.text.FromFormattedString("{$TextNetutral BHIJ_Registered}");
}
else
{
sideEffectStatus =
_.text.FromFormattedString("{$TextNegative BHIJ_None (???)}");
}
}
defaultproperties
{
}

51
sources/KFImplementation/Server/Unreal/BroadcastsAPI/KF1_BroadcastAPI.uc

@ -1,6 +1,6 @@
/**
* Acedia's default implementation for `BroadcastAPI`.
* Copyright 2021-2022 Anton Tarasenko
* Copyright 2021-2023 Anton Tarasenko
*------------------------------------------------------------------------------
* This file is part of Acedia.
*
@ -23,7 +23,6 @@ class KF1_BroadcastAPI extends BroadcastAPI;
// wasting resources/spamming errors in the log about our inability to do so
var private bool triedToInjectBroadcastHandler;
var private LoggerAPI.Definition infoInjectedBroadcastEventsObserver;
var private LoggerAPI.Definition errBroadcasthandlerForbidden;
var private LoggerAPI.Definition errBroadcasthandlerUnknown;
@ -94,7 +93,7 @@ public function Broadcast_OnHandleLocalizedFor_Slot OnHandleLocalizedFor(
/**
* Method that attempts to inject Acedia's `BroadcastEventObserver`, while
* respecting settings inside `class'SideEffects'`.
* respecting settings inside `class'ServerSideEffects'`.
*
* @param service Reference to `ServerUnrealService` to exchange signal and
* slots classes with.
@ -102,27 +101,19 @@ public function Broadcast_OnHandleLocalizedFor_Slot OnHandleLocalizedFor(
protected final function TryInjectBroadcastHandler(ServerUnrealService service)
{
local InjectionLevel usedLevel;
local BroadcastSideEffect sideEffect;
local BroadcastEventsObserver broadcastObserver;
if (triedToInjectBroadcasthandler) {
return;
}
triedToInjectBroadcasthandler = true;
usedLevel = class'SideEffects'.default.broadcastHandlerInjectionLevel;
usedLevel = class'ServerSideEffects'.default.broadcastHandlerInjectionLevel;
broadcastObserver = BroadcastEventsObserver(_server.unreal.broadcasts.Add(
class'BroadcastEventsObserver', usedLevel));
if (broadcastObserver != none)
{
broadcastObserver.Initialize(service);
sideEffect =
BroadcastSideEffect(_.memory.Allocate(class'BroadcastSideEffect'));
sideEffect.Initialize(usedLevel);
_server.sideEffects.Add(sideEffect);
_.memory.Free(sideEffect);
_.logger
.Auto(infoInjectedBroadcastEventsObserver)
.Arg(InjectionLevelIntoText(usedLevel));
AddSideEffect();
return;
}
// We are here if we have failed
@ -137,6 +128,35 @@ protected final function TryInjectBroadcastHandler(ServerUnrealService service)
}
}
private final static function AddSideEffect() {
local InjectionLevel usedLevel;
local Text sideEffectStatus;
local SideEffect newSideEffect;
usedLevel = class'ServerSideEffects'.default.broadcastHandlerInjectionLevel;
if (usedLevel == BHIJ_Root) {
sideEffectStatus = __().text.FromFormattedString("{$TextPositive BHIJ_Root}");
} else if (usedLevel == BHIJ_Registered) {
sideEffectStatus = __().text.FromFormattedString("{$TextNeutral BHIJ_Registered}");
} else {
sideEffectStatus = __().text.FromFormattedString("{$TextNegative BHIJ_None (???)}");
}
newSideEffect = __().sideEffects.Add(
P("AcediaCore's `BroadcastHandler` injected"),
P("Handling text and localized messages between server and clients requires AcediaCore to"
@ "add its own `BroadcastHandler` into their linked list. This is normal, since"
@ "`BroadcastHandler` class was designed to allow mods to do that, however, for full"
@ "functionality Acedia requires to inject it as the very first element"
@ "(`BHIJ_Root` level injection), since some of the events become otherwise"
@ "inaccessible. This can result in incompatibility with other mods that are trying to"
@ "do the same. For that reason AcediaCore can also inject its `BroadcastHandler` as"
@ "`BHIJ_Registered`."),
P("AcediaCore"),
P("UnrealAPI"),
sideEffectStatus);
__().memory.Free(newSideEffect);
}
private final function Text InjectionLevelIntoText(
InjectionLevel injectionLevel)
{
@ -257,7 +277,6 @@ public function bool IsAdded(class<BroadcastHandler> BHClassToFind)
defaultproperties
{
infoInjectedBroadcastEventsObserver = (l=LOG_Info,m="Injected AcediaCore's `BroadcastEventsObserver` with level `%1`.")
errBroadcastHandlerForbidden = (l=LOG_Error,m="Injected AcediaCore's `BroadcastEventsObserver` is required, but forbidden by AcediaCore's settings: in file \"AcediaSystem.ini\", section [AcediaCore.SideEffects], variable `broadcastHandlerInjectionLevel`.")
errBroadcastHandlerUnknown = (l=LOG_Error,m="Injected AcediaCore's `BroadcastEventsObserver` failed to be injected with level `%1` for unknown reason.")
errBroadcastHandlerForbidden = (l=LOG_Error,m="Injected AcediaCore's `BroadcastEventsObserver` is required, but forbidden by AcediaCore's settings: in file \"AcediaSystem.ini\", section [AcediaCore.SideEffects], variable `broadcastHandlerInjectionLevel`.")
errBroadcastHandlerUnknown = (l=LOG_Error,m="Injected AcediaCore's `BroadcastEventsObserver` failed to be injected with level `%1` for unknown reason.")
}

43
sources/KFImplementation/Server/Unreal/GameRulesAPI/GameRulesSideEffect.uc

@ -1,43 +0,0 @@
/**
* Object representing a side effect introduced into the game/server.
* Side effects in Acedia refer to changes that aren't a part of mod's main
* functionality, but rather something necessary to make that functionality
* possible that might also affect how other mods work.
* This is a simple data container that is meant to describe relevant
* changes to the human user.
* Copyright 2022 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 <https://www.gnu.org/licenses/>.
*/
class GameRulesSideEffect extends SideEffect;
public final function Initialize()
{
sideEffectName =
_.text.FromString("AcediaCore's `AcediaGameRules` added");
sideEffectDescription =
_.text.FromString("`GameRule`s is one of the main ways to get notified"
@ "about various gameplay-related events in Unreal Engine."
@ "Of course AcediaCore would require handling some of those events,"
@ "depending on how it's used.");
sideEffectPackage = _.text.FromString("AcediaCore");
sideEffectSource = _.text.FromString("UnrealAPI");
sideEffectStatus = _.text.FromFormattedString("{$TextPositive active}");
}
defaultproperties
{
}

36
sources/KFImplementation/Server/Unreal/GameRulesAPI/KF1_GameRulesAPI.uc

@ -1,6 +1,6 @@
/**
* Acedia's default implementation for `GameRulesAPI` API.
* Copyright 2021-2022 Anton Tarasenko
* Copyright 2021-2023 Anton Tarasenko
*------------------------------------------------------------------------------
* This file is part of Acedia.
*
@ -23,7 +23,6 @@ class KF1_GameRulesAPI extends GameRulesAPI;
// wasting resources/spamming errors in the log about our inability to do so
var private bool triedToInjectGameRules;
var private LoggerAPI.Definition infoAddedGameRules;
var private LoggerAPI.Definition errGameRulesForbidden;
var private LoggerAPI.Definition errGameRulesUnknown;
@ -132,21 +131,20 @@ public function GameRules_OnScoreKill_Slot OnScoreKill(
/**
* Method that attempts to inject Acedia's `AcediaGameRules`, while
* respecting settings inside `class'SideEffects'`.
* respecting settings inside `class'ServerSideEffects'`.
*
* @param service Reference to `ServerUnrealService` to exchange signal and
* slots classes with.
*/
protected function TryAddingGameRules(ServerUnrealService service)
{
local AcediaGameRules gameRules;
local GameRulesSideEffect sideEffect;
local AcediaGameRules gameRules;
if (triedToInjectGameRules) {
return;
}
triedToInjectGameRules = true;
if (!class'SideEffects'.default.allowAddingGameRules)
if (!class'ServerSideEffects'.default.allowAddingGameRules)
{
_.logger.Auto(errGameRulesForbidden);
return;
@ -155,18 +153,27 @@ protected function TryAddingGameRules(ServerUnrealService service)
if (gameRules != none)
{
gameRules.Initialize(service);
sideEffect =
GameRulesSideEffect(_.memory.Allocate(class'GameRulesSideEffect'));
sideEffect.Initialize();
_server.sideEffects.Add(sideEffect);
_.memory.Free(sideEffect);
_.logger.Auto(infoAddedGameRules);
AddSideEffect();
}
else {
_.logger.Auto(errGameRulesUnknown);
}
}
private final static function AddSideEffect() {
local SideEffect newSideEffect;
newSideEffect = __().sideEffects.Add(
P("AcediaCore's `AcediaGameRules` added"),
P("`GameRule`s is one of the main ways to get notified about various gameplay-related"
@ "events in Unreal Engine. Of course AcediaCore would require handling some of those"
@ "events, depending on how it's used."),
P("AcediaCore"),
P("UnrealAPI"),
F("{$TextPositive active}"));
__().memory.Free(newSideEffect);
}
public function GameRules Add(class<GameRules> newRulesClass)
{
local GameRules newGameRules;
@ -236,7 +243,6 @@ public function bool AreAdded(class<GameRules> rulesClassToCheck)
defaultproperties
{
infoAddedGameRules = (l=LOG_Info,m="Added AcediaCore's `AcediaGameRules`.")
errGameRulesForbidden = (l=LOG_Error,m="Adding AcediaCore's `AcediaGameRules` is required, but forbidden by AcediaCore's settings: in file \"AcediaSystem.ini\", section [AcediaCore.SideEffects], variable `allowAddingGameRules`.")
errGameRulesUnknown = (l=LOG_Error,m="Adding AcediaCore's `AcediaGameRules` failed to be injected with level for unknown reason.")
errGameRulesForbidden = (l=LOG_Error,m="Adding AcediaCore's `AcediaGameRules` is required, but forbidden by AcediaCore's settings: in file \"AcediaSystem.ini\", section [AcediaCore.SideEffects], variable `allowAddingGameRules`.")
errGameRulesUnknown = (l=LOG_Error,m="Adding AcediaCore's `AcediaGameRules` failed to be injected with level for unknown reason.")
}

164
sources/LevelAPI/API/SideEffects/SideEffect.uc

@ -1,164 +0,0 @@
/**
* Object representing a side effect introduced into the game/server.
* Side effects in Acedia refer to changes that aren't a part of mod's main
* functionality, but rather something necessary to make that functionality
* possible that might also affect how other mods work.
* This is a simple data container that is meant to describe relevant
* changes to the human user.
* Copyright 2022 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 <https://www.gnu.org/licenses/>.
*/
class SideEffect extends AcediaObject
abstract;
/**
* # Side effects
*
* In Acedia "side effect" refers to changes that aren't a part of mod's
* main functionality, but rather something necessary to make that
* functionality possible that might also affect how other mods work. Their
* purpose is to help developers and server admins figure out what changes were
* performed by Acedia or mods based on it.
* What needs to be considered a side effect is loosely defined and they
* are simply a tool to inform others that something they might not have
* expected has happened, that can possibly break other (their) mods.
* AcediaCore, for example, tried to leave a minimal footprint, avoiding
* making any changes to the game classes unless requested, but it still has to
* do some changes (adding `GameRules`, replacing damage types for some zeds,
* etc.) and `SideEffect`s can be used to document these changes. They can be
* used in a similar way for AcediaFixes - a package that is only meant for
* fixing bugs, but inevitably has to make a lot of under the hood changes to
* achieve that.
* On the other hand gameplay mods like Futility can make a lot of changes,
* but they can all be just expected part of its direct functionality: we
* expect feature that shares dosh of leavers to alter players' dosh values, so
* this is not a side effect. Such mods are likely not going to have to specify
* any side effects whatsoever.
*
* ## Implementing your own `SideEffect`s
*
* Simply make a non-abstract child class based on `SideEffect`, create its
* instance filled with necessary data and register it in `SideEffectAPI` once
* side effect is introduced. If you revert introduced side effect, you should
* remove registered object through the same API.
* Each class of the `SideEffect` is supposed to represent a particular
* side effect introduced into the game engine. Whether side effect is active
* is decided by whether it is currently registered in `SideEffectAPI`.
*
* NOTE: `SideEffect` should not have any logic and should serve as
* an immutable data container.
*/
var protected Text sideEffectName;
var protected Text sideEffectDescription;
var protected Text sideEffectPackage;
var protected Text sideEffectSource;
var protected Text sideEffectStatus;
/**
* Returns name (short description) of the caller `SideEffect`. User need to
* be able to tell what this `SideEffect` is generally about from the glance at
* this name.
*
* Guideline is for this value to not exceed `80` characters, but this is not
* enforced.
*
* Must not be `none`.
*
* @return Name (short description) of the caller `SideEffect`.
* Guaranteed to not be `none`.
*/
public function Text GetName()
{
if (sideEffectName != none) {
return sideEffectName.Copy();
}
return none;
}
/**
* Returns description of the caller `SideEffect`. This should describe what
* was done and why relevant change was necessary.
*
* Must not be `none`.
*
* @return Description of the caller `SideEffect`.
* Guaranteed to not be `none`.
*/
public function Text GetDescription()
{
if (sideEffectDescription != none) {
return sideEffectDescription.Copy();
}
return none;
}
/**
* Returns name of the package ("*.u" file) that introduced this change.
*
* Note that if package "A" actually performed the change because another
* package "B" requested certain functionality, it is still package "A" that is
* responsible for the side effect.
*
* Must not be `none`.
*
* @return Name of the package ("*.u" file) that introduced this change.
* Guaranteed to not be `none`.
*/
public function Text GetPackage()
{
if (sideEffectPackage != none) {
return sideEffectPackage.Copy();
}
return none;
}
/**
* What part of package caused this change. For huge packages can be used to
* further specify what introduced the change.
*
* Returned value can be `none` (e.g. when it is unnecessary for small
* packages).
*
* @return Name (short description) of the part of the package that caused
* caller `SideEffect`.
*/
public function Text GetSource()
{
if (sideEffectSource != none) {
return sideEffectSource.Copy();
}
return none;
}
/**
* Status of the caller `SideEffect`. Some side effects can be introduced in
* several different ways - this value needs to help distinguish between them.
*
* @return Status of the caller `SideEffect`.
*/
public function Text GetStatus()
{
if (sideEffectStatus != none) {
return sideEffectStatus.Copy();
}
return none;
}
defaultproperties
{
}

76
sources/LevelAPI/API/SideEffects/SideEffectAPI.uc

@ -1,76 +0,0 @@
/**
* Base class for simple API for managing a list of `SideEffect` info
* objects: can add, remove, return all and by package.
* Copyright 2022 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 <https://www.gnu.org/licenses/>.
*/
class SideEffectAPI extends AcediaObject
abstract;
/**
* Returns all so far registered `SideEffect`s.
*
* @return Array of all registered `SideEffect`s.
*/
public function array<SideEffect> GetAll();
/**
* Returns active `SideEffect` instance of the specified class
* `sideEffectClass`.
*
* @param sideEffectClass Class of side effect to return active instance of.
* @return Active `SideEffect` instance of the specified class
* `sideEffectClass`.
* `none` if either `sideEffectClass` is `none` or side effect of such
* class is not currently active.
*/
public function SideEffect GetClass(class<SideEffect> sideEffectClass);
/**
* Returns all so far registered `SideEffect`s from a package `packageName`
* (case insensitive).
*
* @param packageName Name of the package, in `SideEffect`s from which we are
* interested. Must be not `none`.
* @return Array of all registered `SideEffect`s from a package `packageName`.
* If `none`, returns an empty array.
*/
public function array<SideEffect> GetFromPackage(BaseText packageName);
/**
* Registers a new `SideEffect` object as active.
*
* @param newSideEffect Instance of some `SideEffect` class to register as
* active side effect. Must not be `none`.
* @return `true` if new side effect was added and `false` otherwise.
*/
public function bool Add(SideEffect newSideEffect);
/**
* Removes `SideEffect` of the specified sub-class from the list of active
* side effects.
*
* @param sideEffectClass Class of the side effect to remove.
* @return `true` if some side effect was removed as a result of this operation
* and `false` otherwise (even if there was no side effect of specified
* class to begin with).
*/
public function bool RemoveClass(class<SideEffect> sideEffectClass);
defaultproperties
{
}

5
sources/LevelAPI/AcediaAdapter.uc

@ -35,9 +35,8 @@ class AcediaAdapter extends AcediaObject
* specify desired `AcediaAdapter` before loading server/client core.
*/
var public const class<SideEffectAPI> sideEffectAPIClass;
var public const class<TimeAPI> timeAPIClass;
var public const class<DBAPI> dbAPIClass;
var public const class<TimeAPI> timeAPIClass;
var public const class<DBAPI> dbAPIClass;
defaultproperties
{

8
sources/LevelAPI/CoreGlobal.uc

@ -87,11 +87,9 @@ protected function Initialize()
.ArgClass(self.class);
return;
}
api = class'Global'.static.GetInstance().memory;
sideEffects =
SideEffectAPI(api.Allocate(adapterClass.default.sideEffectAPIClass));
time = TimeAPI(api.Allocate(adapterClass.default.timeAPIClass));
db = DBAPI(api.Allocate(adapterClass.default.dbAPIClass));
api = class'Global'.static.GetInstance().memory;
time = TimeAPI(api.Allocate(adapterClass.default.timeAPIClass));
db = DBAPI(api.Allocate(adapterClass.default.dbAPIClass));
}
/**

Loading…
Cancel
Save