diff --git a/sources/Feature.uc b/sources/Feature.uc index 5d3d65e..5e3eff1 100644 --- a/sources/Feature.uc +++ b/sources/Feature.uc @@ -48,25 +48,43 @@ var private config bool autoEnable; // Listeners listed here will be automatically activated. var public const array< class > requiredListeners; -protected function Contructor() +// `Service` that will be launched and shut down along with this `Feature`. +// One should never launch or shut down this service manually. +var protected const class serviceClass; + +protected function Constructor() { + local FeatureService myService; if (default.blockSpawning) { FreeSelf(); return; } - SetListenersActiveSatus(true); + SetListenersActiveStatus(true); + if (serviceClass != none) { + myService = FeatureService(serviceClass.static.Require()); + } + if (myService != none) { + myService.SetOwnerFeature(self); + } OnEnabled(); } protected function Finalizer() { - if (GetInstance() == self) - { - SetListenersActiveSatus(false); - OnDisabled(); - default.activeInstance = none; + local FeatureService service; + if (GetInstance() != self) { + return; + } + SetListenersActiveStatus(false); + OnDisabled(); + if (serviceClass != none) { + service = FeatureService(serviceClass.static.GetInstance()); + } + if (service != none) { + service.Destroy(); } + default.activeInstance = none; } /** @@ -91,6 +109,21 @@ public final static function Feature GetInstance() return default.activeInstance; } +/** + * Returns reference to this `Feature`'s `FeatureService`. + * + * @return Reference to this `Feature`'s `FeatureService`. + * `none` if caller `Feature` did not set a proper `serviceClass`, + * otherwise guaranteed to be not `none`. + */ +public final function Service GetService() +{ + if (serviceClass == none) { + return none; + } + return serviceClass.static.Require(); +} + /** * Checks if caller `Feature` should be auto-enabled on game starting. * @@ -169,7 +202,7 @@ protected function OnEnabled(){} */ protected function OnDisabled(){} -private static function SetListenersActiveSatus(bool newStatus) +private static function SetListenersActiveStatus(bool newStatus) { local int i; for (i = 0; i < default.requiredListeners.length; i += 1) @@ -183,4 +216,5 @@ defaultproperties { autoEnable = false blockSpawning = true + serviceClass = none } \ No newline at end of file diff --git a/sources/FeatureService.uc b/sources/FeatureService.uc new file mode 100644 index 0000000..e764ec7 --- /dev/null +++ b/sources/FeatureService.uc @@ -0,0 +1,51 @@ +/** + * Special service type that is supposed to be launched alongside + * a particular `Feature`. + * Such service is spawned right before `OnEnabled()` event. + * Copyright 2021 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 FeatureService extends Service + abstract; + +var protected Feature ownerFeature; + +protected function OnShutdown() +{ + ownerFeature = none; +} + +/** + * Called right after spawning a service to record it's owner. + * + * Can be overloaded to convert and record `newOwnerFeature` in a more + * type-specific variable, so that service does not have to constantly convert + * `ownerFeature` to your `Feature` class to access it's methods. + * + * @param newOwnerFeature `Feature` that this `Service` is launched for. + */ +public function SetOwnerFeature(Feature newOwnerFeature) +{ + if (ownerFeature != none) { + return; + } + ownerFeature = newOwnerFeature; +} + +defaultproperties +{ +} \ No newline at end of file