Browse Source

Fix `_textCache` missing for some classes

Previously `_textCache` relied on static constructor inside base classes
`AcediaObject` / `AceduaActor` to be created and filled with necessary
data. This was faulty approach, since their static constructor was only
ever supposed to be called once.

This patch moves `_textCache` creation into `_constructor()` and `T()`,
`P()`, `C()`, `F()` methods.
pull/8/head
Anton Tarasenko 3 years ago
parent
commit
2a8e5db73f
  1. 48
      sources/Types/AcediaActor.uc
  2. 48
      sources/Types/AcediaObject.uc

48
sources/Types/AcediaActor.uc

@ -114,7 +114,9 @@ public function _constructor()
default._ = class'Global'.static.GetInstance(); default._ = class'Global'.static.GetInstance();
_ = default._; _ = default._;
} }
if (!default._staticConstructorWasCalled) { if (!default._staticConstructorWasCalled)
{
CreateTextCache();
StaticConstructor(); StaticConstructor();
default._staticConstructorWasCalled = true; default._staticConstructorWasCalled = true;
} }
@ -165,7 +167,7 @@ protected function Constructor(){}
/** /**
* 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 of this (or it's child) * this method is guaranteed to be called after object of this (or it's child)
* class is deallocated. * class is allocated.
* *
* If you overload this method, first two lines must always be * If you overload this method, first two lines must always be
* ____________________________________________________________________________ * ____________________________________________________________________________
@ -174,22 +176,27 @@ protected function Constructor(){}
* |___________________________________________________________________________ * |___________________________________________________________________________
* otherwise behavior of constructors should be considered undefined. * otherwise behavior of constructors should be considered undefined.
*/ */
public static function StaticConstructor() public static function StaticConstructor(){}
// By default this method will only create `TextCache` instance if it
// is needed, which is detected by checking whether `stringConstantsCopy` array
// is empty.
// However even if it is - class might make use of `P()`, `C()` or `F()`
// methods that also use `TextCache`. To force creating `TextCache` for them -
// set `forceCreation` parameter to `true`.
private final static function CreateTextCache(optional bool forceCreation)
{ {
local int i; local int i;
local array<string> stringConstantsCopy; local array<string> stringConstantsCopy;
if (StaticConstructorGuard()) return; // Cache already created
if (default._textCache != none) return;
// Do not do it for the cache itself
if (default.class == class'TextCache') return;
// If there is no string constants to convert into `Text`s, // If there is no string constants to convert into `Text`s,
// then this constructor has nothing to do. // then this constructor has nothing to do.
if (default.stringConstants.length <= 0) return; if (!forceCreation && default.stringConstants.length <= 0) return;
// Since `TextCache` does not have any string constants to convert,
// this check should never fail, but still do check to make extra sure
// there would not be any infinite loops if someone decided to add them.
if (default.class == class'TextCache') return;
if (default._textCache == none) { default._textCache = TextCache(__().memory.Allocate(class'TextCache'));
default._textCache = TextCache(__().memory.Allocate(class'TextCache'));
}
// Create `Text` constants // Create `Text` constants
stringConstantsCopy = default.stringConstants; stringConstantsCopy = default.stringConstants;
for (i = 0; i < stringConstantsCopy.length; i += 1) { for (i = 0; i < stringConstantsCopy.length; i += 1) {
@ -325,9 +332,8 @@ public final function int GetLifeVersion()
*/ */
public static final function Text T(int index) public static final function Text T(int index)
{ {
if (default._textCache == none) { // Here cache should already be created, but make extra sure
default._textCache = TextCache(__().memory.Allocate(class'TextCache')); CreateTextCache(true);
}
return default._textCache.GetIndexedText(index); return default._textCache.GetIndexedText(index);
} }
@ -346,9 +352,7 @@ public static final function Text T(int index)
*/ */
public static final function Text P(string string) public static final function Text P(string string)
{ {
if (default._textCache == none) { CreateTextCache(true);
default._textCache = TextCache(__().memory.Allocate(class'TextCache'));
}
return default._textCache.GetPlainText(string); return default._textCache.GetPlainText(string);
} }
@ -368,9 +372,7 @@ public static final function Text P(string string)
*/ */
public static final function Text C(string string) public static final function Text C(string string)
{ {
if (default._textCache == none) { CreateTextCache(true);
default._textCache = TextCache(__().memory.Allocate(class'TextCache'));
}
return default._textCache.GetColoredText(string); return default._textCache.GetColoredText(string);
} }
@ -390,9 +392,7 @@ public static final function Text C(string string)
*/ */
public static final function Text F(string string) public static final function Text F(string string)
{ {
if (default._textCache == none) { CreateTextCache(true);
default._textCache = TextCache(__().memory.Allocate(class'TextCache'));
}
return default._textCache.GetFormattedText(string); return default._textCache.GetFormattedText(string);
} }

48
sources/Types/AcediaObject.uc

@ -115,7 +115,9 @@ public final function _constructor()
default._ = class'Global'.static.GetInstance(); default._ = class'Global'.static.GetInstance();
_ = default._; _ = default._;
} }
if (!default._staticConstructorWasCalled) { if (!default._staticConstructorWasCalled)
{
CreateTextCache();
StaticConstructor(); StaticConstructor();
default._staticConstructorWasCalled = true; default._staticConstructorWasCalled = true;
} }
@ -166,7 +168,7 @@ protected function Constructor(){}
/** /**
* 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 of this (or it's child) * this method is guaranteed to be called after object of this (or it's child)
* class is deallocated. * class is allocated.
* *
* If you overload this method, first two lines must always be * If you overload this method, first two lines must always be
* ____________________________________________________________________________ * ____________________________________________________________________________
@ -175,22 +177,27 @@ protected function Constructor(){}
* |___________________________________________________________________________ * |___________________________________________________________________________
* otherwise behavior of constructors should be considered undefined. * otherwise behavior of constructors should be considered undefined.
*/ */
public static function StaticConstructor() public static function StaticConstructor(){}
// By default this method will only create `TextCache` instance if it
// is needed, which is detected by checking whether `stringConstantsCopy` array
// is empty.
// However even if it is - class might make use of `P()`, `C()` or `F()`
// methods that also use `TextCache`. To force creating `TextCache` for them -
// set `forceCreation` parameter to `true`.
private final static function CreateTextCache(optional bool forceCreation)
{ {
local int i; local int i;
local array<string> stringConstantsCopy; local array<string> stringConstantsCopy;
if (StaticConstructorGuard()) return; // Cache already created
if (default._textCache != none) return;
// Do not do it for the cache itself
if (default.class == class'TextCache') return;
// If there is no string constants to convert into `Text`s, // If there is no string constants to convert into `Text`s,
// then this constructor has nothing to do. // then this constructor has nothing to do.
if (default.stringConstants.length <= 0) return; if (!forceCreation && default.stringConstants.length <= 0) return;
// Since `TextCache` does not have any string constants to convert,
// this check should never fail, but still do check to make extra sure
// there would not be any infinite loops if someone decided to add them.
if (default.class == class'TextCache') return;
if (default._textCache == none) { default._textCache = TextCache(__().memory.Allocate(class'TextCache'));
default._textCache = TextCache(__().memory.Allocate(class'TextCache'));
}
// Create `Text` constants // Create `Text` constants
stringConstantsCopy = default.stringConstants; stringConstantsCopy = default.stringConstants;
for (i = 0; i < stringConstantsCopy.length; i += 1) { for (i = 0; i < stringConstantsCopy.length; i += 1) {
@ -340,9 +347,8 @@ public final function int GetLifeVersion()
*/ */
public static final function Text T(int index) public static final function Text T(int index)
{ {
if (default._textCache == none) { // Here cache should already be created, but make extra sure
default._textCache = TextCache(__().memory.Allocate(class'TextCache')); CreateTextCache(true);
}
return default._textCache.GetIndexedText(index); return default._textCache.GetIndexedText(index);
} }
@ -361,9 +367,7 @@ public static final function Text T(int index)
*/ */
public static final function Text P(string string) public static final function Text P(string string)
{ {
if (default._textCache == none) { CreateTextCache(true);
default._textCache = TextCache(__().memory.Allocate(class'TextCache'));
}
return default._textCache.GetPlainText(string); return default._textCache.GetPlainText(string);
} }
@ -383,9 +387,7 @@ public static final function Text P(string string)
*/ */
public static final function Text C(string string) public static final function Text C(string string)
{ {
if (default._textCache == none) { CreateTextCache(true);
default._textCache = TextCache(__().memory.Allocate(class'TextCache'));
}
return default._textCache.GetColoredText(string); return default._textCache.GetColoredText(string);
} }
@ -405,9 +407,7 @@ public static final function Text C(string string)
*/ */
public static final function Text F(string string) public static final function Text F(string string)
{ {
if (default._textCache == none) { CreateTextCache(true);
default._textCache = TextCache(__().memory.Allocate(class'TextCache'));
}
return default._textCache.GetFormattedText(string); return default._textCache.GetFormattedText(string);
} }

Loading…
Cancel
Save