Browse Source

Refactor static constructors

There wasn't actually any need for `InitializeStatic()` method. In fact
it could lead to problems. Now calling `StaticCosntructor()` is allowed
instead.
pull/8/head
Anton Tarasenko 4 years ago
parent
commit
8e17324a5e
  1. 5
      docs/introduction/ObjectsActors.md
  2. 2
      sources/Global.uc
  3. 34
      sources/Types/AcediaActor.uc
  4. 21
      sources/Types/AcediaObject.uc
  5. 2
      sources/Types/Tests/TEST_Base.uc

5
docs/introduction/ObjectsActors.md

@ -21,10 +21,7 @@ Implementing and enforcing (de)allocation allowed us to introduce constructors t
To make use of them one can simply overload protected methods `Constructor()` and `Finalizer()`. Parametrized constructors are not supported. To make use of them one can simply overload protected methods `Constructor()` and `Finalizer()`. Parametrized constructors are not supported.
Static constructors are also supported (and can be used by overloading `StaticConstructor()`), - they are methods that take care of some initialization work before any instance of the given class is created. They are called only once, at the earliest of the following two events: Static constructors are also supported (and can be used by overloading `StaticConstructor()`), - they are methods that take care of some initialization work before any instance of the given class is created. They are called only once, at the latest when an instance of relevant class (or it's child class) is created. `StaticConstructor()` is allowed to be called early to initialize static members of a certain class before creating it's instances.
1. An instance of relevant class (or it's child class) is created;
2. Public `InitializeStatic()` method was called to force it early.
### General collections ### General collections

2
sources/Global.uc

@ -65,5 +65,5 @@ protected function Initialize()
color = ColorAPI(memory.Allocate(class'ColorAPI')); color = ColorAPI(memory.Allocate(class'ColorAPI'));
users = UserAPI(memory.Allocate(class'UserAPI')); users = UserAPI(memory.Allocate(class'UserAPI'));
json = JSONAPI(memory.Allocate(class'JSONAPI')); json = JSONAPI(memory.Allocate(class'JSONAPI'));
json.InitializeStatic(); json.StaticConstructor();
} }

34
sources/Types/AcediaActor.uc

@ -68,9 +68,7 @@ var private bool _hashCodeWasCached;
var private TextCache _textCache; var private TextCache _textCache;
// Formatted `strings` declared in this array will be converted into `Text`s // Formatted `strings` declared in this array will be converted into `Text`s
// available via `T()` method when static constructor is called // available via `T()` method when static constructor is called.
// (either when first object of this class is created or
// `InitializeStatic()` method is called)
var protected const array<string> stringConstants; var protected const array<string> stringConstants;
/** /**
@ -116,6 +114,10 @@ public function _constructor()
default._ = class'Global'.static.GetInstance(); default._ = class'Global'.static.GetInstance();
_ = default._; _ = default._;
} }
if (!default._staticConstructorWasCalled) {
StaticConstructor();
default._staticConstructorWasCalled = true;
}
_hashCodeWasCached = false; _hashCodeWasCached = false;
Constructor(); Constructor();
} }
@ -151,19 +153,6 @@ protected final static function bool StaticConstructorGuard()
return true; return true;
} }
/**
* Method that can cause early static constructor call for a caller class.
*
* Normally static constructor is called the first time an instance of a class
* (or it's child class) is created, but this method can be used to cause this
* initialization early.
*/
public final static function InitializeStatic()
{
if (StaticConstructorGuard()) return;
StaticConstructor();
}
/** /**
* When using proper methods for creating actors (`MemoryAPI`), * When using proper methods for creating actors (`MemoryAPI`),
* this method is guaranteed to be called after actor is spawned, * this method is guaranteed to be called after actor is spawned,
@ -185,7 +174,7 @@ protected function Constructor(){}
* |___________________________________________________________________________ * |___________________________________________________________________________
* otherwise behavior of constructors should be considered undefined. * otherwise behavior of constructors should be considered undefined.
*/ */
protected static function StaticConstructor() public static function StaticConstructor()
{ {
local int i; local int i;
local array<string> stringConstantsCopy; local array<string> stringConstantsCopy;
@ -323,9 +312,16 @@ public final function int GetLifeVersion()
* *
* You can define array `stringConstants` (of `string`s) in `defaultproperties` * You can define array `stringConstants` (of `string`s) in `defaultproperties`
* that will statically be converted into `Text` objects first time an object * that will statically be converted into `Text` objects first time an object
* of that class is created or (`InitializeStatic()` method is called). * of that class is created or `StaticConstructor()` method is called manually.
*
* Provided that returned values are not deallocated, they always refer to
* the same `Text` object for any fixed `index`.
* Otherwise new `Text` object can be allocated.
* *
* `Text` instances * @param index Index for which to return `Text` instance.
* @return `Text` instance containing the data in a `stringConstants[index]`.
* `none` if either `index < 0` or `index >= stringConstants.length`,
* otherwise guaranteed to be not `none`.
*/ */
public static final function Text T(int index) public static final function Text T(int index)
{ {

21
sources/Types/AcediaObject.uc

@ -69,9 +69,7 @@ var private bool _hashCodeWasCached;
var private TextCache _textCache; var private TextCache _textCache;
// Formatted `strings` declared in this array will be converted into `Text`s // Formatted `strings` declared in this array will be converted into `Text`s
// available via `T()` method when static constructor is called // available via `T()` method when static constructor is called.
// (either when first object of this class is created or
// `InitializeStatic()` method is called)
var protected const array<string> stringConstants; var protected const array<string> stringConstants;
/** /**
@ -156,19 +154,6 @@ protected final static function bool StaticConstructorGuard()
return true; return true;
} }
/**
* Method that can cause early static constructor call for a caller class.
*
* Normally static constructor is called the first time an instance of a class
* (or it's child class) is created, but this method can be used to cause this
* initialization early.
*/
public final static function InitializeStatic()
{
if (default._staticConstructorWasCalled) return;
StaticConstructor();
}
/** /**
* When using proper methods for creating objects (`MemoryAPI`), * When using proper methods for creating objects (`MemoryAPI`),
* this method is guaranteed to be called after object is allocated, * this method is guaranteed to be called after object is allocated,
@ -190,7 +175,7 @@ protected function Constructor(){}
* |___________________________________________________________________________ * |___________________________________________________________________________
* otherwise behavior of constructors should be considered undefined. * otherwise behavior of constructors should be considered undefined.
*/ */
protected static function StaticConstructor() public static function StaticConstructor()
{ {
local int i; local int i;
local array<string> stringConstantsCopy; local array<string> stringConstantsCopy;
@ -342,7 +327,7 @@ public final function int GetLifeVersion()
* *
* You can define array `stringConstants` (of `string`s) in `defaultproperties` * You can define array `stringConstants` (of `string`s) in `defaultproperties`
* that will statically be converted into `Text` objects first time an object * that will statically be converted into `Text` objects first time an object
* of that class is created or (`InitializeStatic()` method is called). * of that class is created or `StaticConstructor()` method is called manually.
* *
* Provided that returned values are not deallocated, they always refer to * Provided that returned values are not deallocated, they always refer to
* the same `Text` object for any fixed `index`. * the same `Text` object for any fixed `index`.

2
sources/Types/Tests/TEST_Base.uc

@ -24,7 +24,7 @@ class TEST_Base extends TestCase
protected static function TESTS() protected static function TESTS()
{ {
// Use test case itself to test `Text`-returning methods // Use test case itself to test `Text`-returning methods
InitializeStatic(); StaticConstructor();
Test_QuickText(); Test_QuickText();
Test_Constants(); Test_Constants();
} }

Loading…
Cancel
Save