Move Selection into a Trait

This commit is contained in:
Evgeniy S
2019-05-16 16:15:32 +03:00
committed by reaperrr
parent 6723306bb4
commit 3a30b013a5
14 changed files with 55 additions and 33 deletions

View File

@@ -333,7 +333,8 @@ namespace OpenRA
foreach (var t in TraitsImplementing<INotifyOwnerChanged>())
t.OnOwnerChanged(this, oldOwner, newOwner);
World.Selection.OnOwnerChanged(this, oldOwner, newOwner);
foreach (var t in World.WorldActor.TraitsImplementing<INotifyOwnerChanged>())
t.OnOwnerChanged(this, oldOwner, newOwner);
if (wasInWorld)
World.Add(this);

View File

@@ -602,7 +602,6 @@ namespace OpenRA
Sync.RunUnsynced(Settings.Debug.SyncCheckUnsyncedCode, world, () =>
{
world.OrderGenerator.Tick(world);
world.Selection.Tick(world);
});
world.Tick();

View File

@@ -413,6 +413,22 @@ namespace OpenRA.Traits
bool SpatiallyPartitionable { get; }
}
public interface ISelection
{
int Hash { get; }
IEnumerable<Actor> Actors { get; }
void Add(Actor a);
void Remove(Actor a);
bool Contains(Actor a);
void Combine(World world, IEnumerable<Actor> newSelection, bool isCombine, bool isClick);
void Clear();
void DoControlGroup(World world, WorldRenderer worldRenderer, int group, Modifiers mods, int multiTapCount);
void AddToControlGroup(Actor a, int group);
void RemoveFromControlGroup(Actor a);
int? GetControlGroupForActor(Actor a);
}
/// <summary>
/// Indicates target types as defined on <see cref="Traits.ITargetable"/> are present in a <see cref="Primitives.BitSet{T}"/>.
/// </summary>

View File

@@ -155,7 +155,7 @@ namespace OpenRA
}
}
public readonly Selection Selection;
public readonly ISelection Selection;
public void CancelInputMode() { OrderGenerator = new UnitOrderGenerator(); }
@@ -193,8 +193,7 @@ namespace OpenRA
WorldActor = CreateActor(worldActorType, new TypeDictionary());
ActorMap = WorldActor.Trait<IActorMap>();
ScreenMap = WorldActor.Trait<ScreenMap>();
Selection = new Selection(WorldActor.TraitsImplementing<INotifySelection>());
Selection = WorldActor.Trait<ISelection>();
// Add players
foreach (var cmp in WorldActor.TraitsImplementing<ICreatePlayers>())

View File

@@ -45,9 +45,6 @@ namespace OpenRA.Mods.Common.Traits
if (localPlayer == null && renderPlayer != null)
nodes.Add(new MiniYamlNode("RenderPlayer", FieldSaver.FormatValue(renderPlayer.PlayerActor.ActorID)));
if (localPlayer != null && localPlayer.PlayerActor == self)
nodes.Add(new MiniYamlNode("Selection", "", self.World.Selection.Serialize()));
return nodes;
}
@@ -57,10 +54,6 @@ namespace OpenRA.Mods.Common.Traits
if (viewportNode != null)
worldRenderer.Viewport.Center(FieldLoader.GetValue<WPos>("Viewport", viewportNode.Value.Value));
var selectionNode = data.FirstOrDefault(n => n.Key == "Selection");
if (selectionNode != null)
self.World.Selection.Deserialize(self.World, selectionNode.Value.Nodes);
var renderPlayerNode = data.FirstOrDefault(n => n.Key == "RenderPlayer");
if (renderPlayerNode != null)
{

View File

@@ -15,19 +15,26 @@ using OpenRA.Graphics;
using OpenRA.Primitives;
using OpenRA.Traits;
namespace OpenRA
namespace OpenRA.Mods.Common.Traits
{
public class Selection
public class SelectionInfo : ITraitInfo
{
public object Create(ActorInitializer init) { return new Selection(this); }
}
public class Selection : ISelection, INotifyCreated, INotifyOwnerChanged, ITick, IGameSaveTraitData
{
public int Hash { get; private set; }
public IEnumerable<Actor> Actors { get { return actors; } }
readonly HashSet<Actor> actors = new HashSet<Actor>();
readonly INotifySelection[] worldNotifySelection;
INotifySelection[] worldNotifySelection;
internal Selection(IEnumerable<INotifySelection> worldNotifySelection)
public Selection(SelectionInfo info) { }
void INotifyCreated.Created(Actor self)
{
this.worldNotifySelection = worldNotifySelection.ToArray();
this.worldNotifySelection = self.TraitsImplementing<INotifySelection>().ToArray();
}
void UpdateHash()
@@ -38,7 +45,7 @@ namespace OpenRA
Hash += 1;
}
public void Add(Actor a)
public virtual void Add(Actor a)
{
actors.Add(a);
UpdateHash();
@@ -50,7 +57,7 @@ namespace OpenRA
ns.SelectionChanged();
}
public void Remove(Actor a)
public virtual void Remove(Actor a)
{
if (actors.Remove(a))
{
@@ -60,7 +67,7 @@ namespace OpenRA
}
}
internal void OnOwnerChanged(Actor a, Player oldOwner, Player newOwner)
void INotifyOwnerChanged.OnOwnerChanged(Actor a, Player oldOwner, Player newOwner)
{
if (!actors.Contains(a))
return;
@@ -78,7 +85,7 @@ namespace OpenRA
return actors.Contains(a);
}
public void Combine(World world, IEnumerable<Actor> newSelection, bool isCombine, bool isClick)
public virtual void Combine(World world, IEnumerable<Actor> newSelection, bool isCombine, bool isClick)
{
if (isClick)
{
@@ -137,16 +144,16 @@ namespace OpenRA
UpdateHash();
}
public void Tick(World world)
void ITick.Tick(Actor self)
{
var removed = actors.RemoveWhere(a => !a.IsInWorld || (!a.Owner.IsAlliedWith(world.RenderPlayer) && world.FogObscures(a)));
var removed = actors.RemoveWhere(a => !a.IsInWorld || (!a.Owner.IsAlliedWith(self.World.RenderPlayer) && self.World.FogObscures(a)));
if (removed > 0)
UpdateHash();
foreach (var cg in controlGroups.Values)
{
// note: NOT `!a.IsInWorld`, since that would remove things that are in transports.
cg.RemoveAll(a => a.Disposed || a.Owner != world.LocalPlayer);
cg.RemoveAll(a => a.Disposed || a.Owner != self.World.LocalPlayer);
}
}
@@ -201,7 +208,7 @@ namespace OpenRA
.FirstOrDefault();
}
public List<MiniYamlNode> Serialize()
List<MiniYamlNode> IGameSaveTraitData.IssueTraitData(Actor self)
{
var groups = controlGroups
.Where(cg => cg.Value.Any())
@@ -216,14 +223,14 @@ namespace OpenRA
};
}
public void Deserialize(World world, List<MiniYamlNode> data)
void IGameSaveTraitData.ResolveTraitData(Actor self, List<MiniYamlNode> data)
{
var selectionNode = data.FirstOrDefault(n => n.Key == "Selection");
if (selectionNode != null)
{
var selected = FieldLoader.GetValue<uint[]>("Selection", selectionNode.Value.Value)
.Select(a => world.GetActorById(a));
Combine(world, selected, false, false);
.Select(a => self.World.GetActorById(a));
Combine(self.World, selected, false, false);
}
var groupsNode = data.FirstOrDefault(n => n.Key == "Groups");
@@ -232,7 +239,7 @@ namespace OpenRA
foreach (var n in groupsNode.Value.Nodes)
{
var group = FieldLoader.GetValue<uint[]>(n.Key, n.Value.Value)
.Select(a => world.GetActorById(a));
.Select(a => self.World.GetActorById(a));
controlGroups[int.Parse(n.Key)].AddRange(group);
}
}

View File

@@ -23,7 +23,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic.Ingame
public class CycleBasesHotkeyLogic : SingleHotkeyBaseLogic
{
readonly Viewport viewport;
readonly Selection selection;
readonly ISelection selection;
readonly World world;
[ObjectCreator.UseCtor]

View File

@@ -14,6 +14,7 @@ using System.Linq;
using OpenRA.Graphics;
using OpenRA.Mods.Common.Lint;
using OpenRA.Mods.Common.Traits;
using OpenRA.Traits;
using OpenRA.Widgets;
namespace OpenRA.Mods.Common.Widgets.Logic.Ingame
@@ -22,7 +23,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic.Ingame
public class CycleProductionActorsHotkeyLogic : SingleHotkeyBaseLogic
{
readonly Viewport viewport;
readonly Selection selection;
readonly ISelection selection;
readonly World world;
readonly string clickSound = ChromeMetrics.Get<string>("ClickSound");

View File

@@ -12,6 +12,7 @@
using System.Collections.Generic;
using OpenRA.Graphics;
using OpenRA.Mods.Common.Lint;
using OpenRA.Traits;
using OpenRA.Widgets;
namespace OpenRA.Mods.Common.Widgets.Logic.Ingame
@@ -20,7 +21,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic.Ingame
public class JumpToSelectedActorsHotkeyLogic : SingleHotkeyBaseLogic
{
readonly Viewport viewport;
readonly Selection selection;
readonly ISelection selection;
[ObjectCreator.UseCtor]
public JumpToSelectedActorsHotkeyLogic(Widget widget, ModData modData, WorldRenderer worldRenderer, World world, Dictionary<string, MiniYaml> logicArgs)

View File

@@ -12,6 +12,7 @@
using System.Collections.Generic;
using System.Linq;
using OpenRA.Mods.Common.Lint;
using OpenRA.Traits;
using OpenRA.Widgets;
namespace OpenRA.Mods.Common.Widgets.Logic.Ingame
@@ -19,7 +20,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic.Ingame
[ChromeLogicArgsHotkeys("RemoveFromControlGroupKey")]
public class RemoveFromControlGroupHotkeyLogic : SingleHotkeyBaseLogic
{
readonly Selection selection;
readonly ISelection selection;
readonly World world;
[ObjectCreator.UseCtor]

View File

@@ -3,6 +3,7 @@
Inherits: ^Palettes
ScreenMap:
ActorMap:
Selection:
MusicPlaylist:
VictoryMusic: win1
DefeatMusic: nod_map1

View File

@@ -3,6 +3,7 @@
AlwaysVisible:
ScreenMap:
ActorMap:
Selection:
MusicPlaylist:
VictoryMusic: score
DefeatMusic: score

View File

@@ -3,6 +3,7 @@
AlwaysVisible:
ActorMap:
ScreenMap:
Selection:
MusicPlaylist:
VictoryMusic: score
DefeatMusic: map

View File

@@ -3,6 +3,7 @@
AlwaysVisible:
ScreenMap:
ActorMap:
Selection:
MusicPlaylist:
VictoryMusic: score
DefeatMusic: maps