After NotBefore<> support to control initialization order.
Requires<T> means that trait of type T will be initialized first, and asserts that at least one exists. The new NotBefore<T> means that trait of type T will be initialized first, but allows no traits. This allows traits to control initialization order for optional dependencies. They want to be initialized second so they can rely on the dependencies having been initialized. But if the dependencies are optional then to not throw if none are present. We apply this to Locomotor which was previously using AddFrameEndTask to work around trait order initialization. This improves the user experience as the initialization is applied whilst the loading screen is still visible, rather than the game starting and creating jank by performing initialization on the first tick.
This commit is contained in:
committed by
Paul Chote
parent
62e7c7a318
commit
2583a7af31
@@ -17,7 +17,7 @@ using OpenRA.Traits;
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.World)]
|
||||
public class ElevatedBridgeLayerInfo : TraitInfo, Requires<DomainIndexInfo>, ILobbyCustomRulesIgnore
|
||||
public class ElevatedBridgeLayerInfo : TraitInfo, Requires<DomainIndexInfo>, ILobbyCustomRulesIgnore, ICustomMovementLayerInfo
|
||||
{
|
||||
[Desc("Terrain type used by cells outside any elevated bridge footprint.")]
|
||||
public readonly string ImpassableTerrainType = "Impassable";
|
||||
|
||||
@@ -16,7 +16,7 @@ using OpenRA.Traits;
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.World)]
|
||||
public class JumpjetActorLayerInfo : TraitInfo
|
||||
public class JumpjetActorLayerInfo : TraitInfo, ICustomMovementLayerInfo
|
||||
{
|
||||
[Desc("Terrain type of the airborne layer.")]
|
||||
public readonly string TerrainType = "Jumpjet";
|
||||
|
||||
@@ -57,7 +57,7 @@ namespace OpenRA.Mods.Common.Traits
|
||||
|
||||
[TraitLocation(SystemActors.World | SystemActors.EditorWorld)]
|
||||
[Desc("Used by Mobile. Attach these to the world actor. You can have multiple variants by adding @suffixes.")]
|
||||
public class LocomotorInfo : TraitInfo
|
||||
public class LocomotorInfo : TraitInfo, NotBefore<ICustomMovementLayerInfo>
|
||||
{
|
||||
[Desc("Locomotor ID.")]
|
||||
public readonly string Name = "default";
|
||||
@@ -376,34 +376,31 @@ namespace OpenRA.Mods.Common.Traits
|
||||
map.CustomTerrain.CellEntryChanged += UpdateCellCost;
|
||||
map.Tiles.CellEntryChanged += UpdateCellCost;
|
||||
|
||||
// This section needs to run after WorldLoaded() because we need to be sure that all types of ICustomMovementLayer have been initialized.
|
||||
w.AddFrameEndTask(_ =>
|
||||
// NotBefore<> ensures all custom movement layers have been initialized.
|
||||
var customMovementLayers = world.GetCustomMovementLayers();
|
||||
Array.Resize(ref cellsCost, customMovementLayers.Length);
|
||||
Array.Resize(ref blockingCache, customMovementLayers.Length);
|
||||
foreach (var cml in customMovementLayers)
|
||||
{
|
||||
var customMovementLayers = world.GetCustomMovementLayers();
|
||||
Array.Resize(ref cellsCost, customMovementLayers.Length);
|
||||
Array.Resize(ref blockingCache, customMovementLayers.Length);
|
||||
foreach (var cml in customMovementLayers)
|
||||
if (cml == null)
|
||||
continue;
|
||||
|
||||
var cellLayer = new CellLayer<short>(map);
|
||||
cellsCost[cml.Index] = cellLayer;
|
||||
blockingCache[cml.Index] = new CellLayer<CellCache>(map);
|
||||
|
||||
foreach (var cell in map.AllCells)
|
||||
{
|
||||
if (cml == null)
|
||||
continue;
|
||||
var index = cml.GetTerrainIndex(cell);
|
||||
|
||||
var cellLayer = new CellLayer<short>(map);
|
||||
cellsCost[cml.Index] = cellLayer;
|
||||
blockingCache[cml.Index] = new CellLayer<CellCache>(map);
|
||||
var cost = PathGraph.MovementCostForUnreachableCell;
|
||||
|
||||
foreach (var cell in map.AllCells)
|
||||
{
|
||||
var index = cml.GetTerrainIndex(cell);
|
||||
if (index != byte.MaxValue)
|
||||
cost = terrainInfos[index].Cost;
|
||||
|
||||
var cost = PathGraph.MovementCostForUnreachableCell;
|
||||
|
||||
if (index != byte.MaxValue)
|
||||
cost = terrainInfos[index].Cost;
|
||||
|
||||
cellLayer[cell] = cost;
|
||||
}
|
||||
cellLayer[cell] = cost;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
CellCache GetCache(CPos cell)
|
||||
|
||||
@@ -16,7 +16,7 @@ using OpenRA.Traits;
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.World)]
|
||||
public class SubterraneanActorLayerInfo : TraitInfo
|
||||
public class SubterraneanActorLayerInfo : TraitInfo, ICustomMovementLayerInfo
|
||||
{
|
||||
[Desc("Terrain type of the underground layer.")]
|
||||
public readonly string TerrainType = "Subterranean";
|
||||
|
||||
@@ -17,7 +17,7 @@ using OpenRA.Traits;
|
||||
namespace OpenRA.Mods.Common.Traits
|
||||
{
|
||||
[TraitLocation(SystemActors.World)]
|
||||
public class TerrainTunnelLayerInfo : TraitInfo, Requires<DomainIndexInfo>, ILobbyCustomRulesIgnore
|
||||
public class TerrainTunnelLayerInfo : TraitInfo, Requires<DomainIndexInfo>, ILobbyCustomRulesIgnore, ICustomMovementLayerInfo
|
||||
{
|
||||
[Desc("Terrain type used by cells outside any tunnel footprint.")]
|
||||
public readonly string ImpassableTerrainType = "Impassable";
|
||||
|
||||
Reference in New Issue
Block a user