Skip to content

Commit

Permalink
322 dependency injection and inversion of control (#323)
Browse files Browse the repository at this point in the history
* Add basic DI framework

* Add ITurnProcessor interface

* Delete some obsolete comments

* Apply DI to the TurnProcessor in the TechnologyTest

* Implement DI for the TurnProcessor instances used in the game itself

* Reorganize some comments

* Move TurnProcessor to a new FrEee.Processes project

* Put DI configuration code in its own root project

* Make IModObject actually implement IDisposable

* Add IAI interface for the AIs, but I'm not sure what to do about C# vs. Python scripts so I'l leave it at that for now

* Move Configuration class where it belongs

* DI the battles

* Order commands are now in DI

* DI for notes commands

* Fix incorrect name for IAddOrderCommand

* DI for design commands

* Add DIRoot for easier access to common services

* Fleet commands get DI'd

* Actually use the DI for fleet commands

* Remove access to implementation details of game features from the Blazor UI, just to be safe. Prepare to do so for the WinForms UI but we can't do that quite yet; have to clean some stuff up first.

* DI the waypoint commands

* Use DI for message commands

* Minister commands; fix copypasta namespaces

* Remove PrivateAssets="all" from root project reference since it didn't seem to do anything

* Make private assets restriction more granular

* Update DI framework package

* Get rid of overarching disable transitive referencves for Blazor project too, it's now in the individual feature projects

* Actually inject the minister command factory

* Extract more properties into IBattle interface

* Remove dependencies on concrete classes for fleet commands rom UI
  • Loading branch information
ekolis authored Oct 20, 2024
1 parent 81c4d0c commit a041ccb
Show file tree
Hide file tree
Showing 144 changed files with 1,945 additions and 823 deletions.
4 changes: 2 additions & 2 deletions FrEee.Core.Domain/Extensions/ChecksExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using FrEee.Objects.Civilization;
using FrEee.Objects.Commands;
using FrEee.Objects.Space;
using System;
using System.Collections;
Expand All @@ -11,6 +10,7 @@
using FrEee.Objects.GameState;
using FrEee.Processes.Combat;
using FrEee.Modding.Abilities;
using FrEee.Gameplay.Commands.Orders;
namespace FrEee.Extensions;

public static class ChecksExtensions
Expand Down Expand Up @@ -154,7 +154,7 @@ from subcloak in gj.DefaultIfEmpty()
/// <returns></returns>
public static bool IsNew(this IOrder order)
{
return Game.Current.Referrables.OfType<AddOrderCommand>().Where(cmd => cmd.Order == order).Any();
return Game.Current.Referrables.OfType<IAddOrderCommand>().Where(cmd => cmd.Order == order).Any();
}

public static bool IsPointDefense(this WeaponTypes wt)
Expand Down
9 changes: 5 additions & 4 deletions FrEee.Core.Domain/Extensions/CommonExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
using System.Threading.Tasks;
using FrEee.Objects.Civilization;
using FrEee.Processes.Combat;
using FrEee.Objects.Commands;
using FrEee.Objects.LogMessages;
using FrEee.Objects.Space;
using FrEee.Objects.Technology;
Expand All @@ -23,6 +22,8 @@
using FrEee.Objects.GameState;
using System.Numerics;
using FrEee.Modding.Abilities;
using FrEee.Gameplay.Commands;
using FrEee.Gameplay.Commands.Orders;

namespace FrEee.Extensions;

Expand Down Expand Up @@ -970,15 +971,15 @@ public static ResourceQuantity RemoteMiningIncome(this IIncomeProducer o)
/// <param name="obj">The object from which to remove an order.</param>
/// <param name="order">The order to remove.</param>
/// <returns>The remove-order command created, if any.</returns>
public static RemoveOrderCommand RemoveOrderClientSide(this IOrderable obj, IOrder order)
public static IRemoveOrderCommand RemoveOrderClientSide(this IOrderable obj, IOrder order)
{
if (Empire.Current == null)
throw new InvalidOperationException("RemoveOrderClientSide is intended for client side use.");
var addCmd = Empire.Current.Commands.OfType<AddOrderCommand>().SingleOrDefault(c => c.Order == order);
var addCmd = Empire.Current.Commands.OfType<IAddOrderCommand>().SingleOrDefault(c => c.Order == order);
if (addCmd == null)
{
// not a newly added order, so create a remove command to take it off the server
var remCmd = new RemoveOrderCommand(obj, order);
var remCmd = DIRoot.OrderCommands.RemoveOrder(obj, order);
Empire.Current.Commands.Add(remCmd);
obj.RemoveOrder(order);
return remCmd;
Expand Down
2 changes: 1 addition & 1 deletion FrEee.Core.Domain/FrEee.Core.Domain.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
</ItemGroup>
<ItemGroup>
<Compile Remove="Processes\Combat\Simple\Battle.cs" />
<Compile Remove="Objects\Commands\EditStrategyCommand.cs" />
<Compile Remove="Gameplay\Commands\EditStrategyCommand.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\FrEee.Core.Utility\FrEee.Core.Utility.csproj" />
Expand Down
66 changes: 66 additions & 0 deletions FrEee.Core.Domain/Gameplay/Commands/Command.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
using FrEee.Objects.Civilization;
using FrEee.Objects.GameState;
using FrEee.Serialization;
using System;
using System.Collections.Generic;
using System.Linq;

namespace FrEee.Gameplay.Commands;

/// <summary>
/// A generic command.
/// </summary>
/// <typeparam name="T"></typeparam>
[Serializable]
public abstract class Command<T> : ICommand<T>
where T : IReferrable
{
protected Command(T target)
{
Issuer = Empire.Current;
Executor = target;
}

[DoNotSerialize]
public T Executor { get { return executor; } set { executor = value; } }

IReferrable ICommand.Executor
{
get { return Executor; }
}

public long ExecutorID { get { return executor.ID; } }

public bool IsDisposed { get; set; }

[DoNotSerialize]
public Empire Issuer { get { return issuer; } set { issuer = value; } }

public virtual IEnumerable<IReferrable> NewReferrables
{
get
{
yield break;
}
}

protected GameReference<T> executor { get; set; }

private GameReference<Empire> issuer { get; set; }

public abstract void Execute();

public virtual void ReplaceClientIDs(IDictionary<long, long> idmap, ISet<IPromotable> done = null)
{
if (done == null)
done = new HashSet<IPromotable>();
if (!done.Contains(this))
{
done.Add(this);
issuer.ReplaceClientIDs(idmap, done);
executor.ReplaceClientIDs(idmap, done);
foreach (var r in NewReferrables.OfType<IPromotable>())
r.ReplaceClientIDs(idmap, done);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using FrEee.Objects.Civilization;
using FrEee.Objects.Vehicles;

namespace FrEee.Objects.Commands;
namespace FrEee.Gameplay.Commands.Designs;

/// <summary>
/// A command for an empire to create a design.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FrEee.Objects.Civilization;
using FrEee.Objects.Civilization.Orders;
using FrEee.Objects.GameState;
using FrEee.Objects.Vehicles;

namespace FrEee.Gameplay.Commands.Designs;

/// <summary>
/// Builds various types of commands used for managing vehicle designs.
public interface IDesignCommandFactory
{
ICreateDesignCommand CreateDesign<T>(IDesign<T> design)
where T : IVehicle;

ISetObsoleteFlagCommand SetObsoleteFlag(IDesign design, bool isObsolete);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using FrEee.Objects.Civilization;
using FrEee.Objects.Vehicles;

namespace FrEee.Gameplay.Commands.Designs;

/// <summary>
/// A command to mark a design as obsolete or not obsolete.
/// </summary>
public interface ISetObsoleteFlagCommand : ICommand<IDesign>
{
/// <summary>
/// The design to set the flag on if it's already knwon by the server.
/// </summary>
IDesign Design { get; }

/// <summary>
/// The design to set the flag on if it's only in the library and not in the game or it's a brand new design.
/// </summary>
IDesign NewDesign { get; set; }

/// <summary>
/// The flag state to set.
/// </summary>
bool IsObsolete { get; set; }
}
17 changes: 17 additions & 0 deletions FrEee.Core.Domain/Gameplay/Commands/Fleets/ICreateFleetCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using FrEee.Objects.Civilization;
using FrEee.Objects.Space;

namespace FrEee.Gameplay.Commands.Fleets;
public interface ICreateFleetCommand
: ICommand<Empire>
{
/// <summary>
/// The fleet to create.
/// </summary>
Fleet Fleet { get; set; }

/// <summary>
/// The sector to place the fleet in.
/// </summary>
Sector Sector { get; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using FrEee.Objects.Civilization;
using FrEee.Objects.Space;

namespace FrEee.Gameplay.Commands.Fleets;
public interface IDisbandFleetCommand
: ICommand<Fleet>
{
}
24 changes: 24 additions & 0 deletions FrEee.Core.Domain/Gameplay/Commands/Fleets/IFleetCommandFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FrEee.Objects.Space;

namespace FrEee.Gameplay.Commands.Fleets;

/// <summary>
/// Builds various types of commands used for managing fleets.
/// </summary>
public interface IFleetCommandFactory
{
ICreateFleetCommand CreateFleet(Fleet fleet, Sector sector);

IDisbandFleetCommand DisbandFleet(Fleet fleet);

IJoinFleetCommand JoinFleet(IMobileSpaceObject vehicle, Fleet fleet);

IJoinFleetCommand JoinFleet(IMobileSpaceObject vehicle, ICreateFleetCommand command);

ILeaveFleetCommand LeaveFleet(IMobileSpaceObject vehicle);
}
16 changes: 16 additions & 0 deletions FrEee.Core.Domain/Gameplay/Commands/Fleets/IJoinFleetCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using FrEee.Objects.Space;

namespace FrEee.Gameplay.Commands.Fleets;
public interface IJoinFleetCommand
: ICommand<IMobileSpaceObject>
{
/// <summary>
/// The command that creates the fleet to join (if the fleet is newly created on the client side).
/// </summary>
ICreateFleetCommand CreateFleetCommand { get; set; }

/// <summary>
/// The fleet to join.
/// </summary>
Fleet Fleet { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using FrEee.Objects.Civilization;
using FrEee.Objects.Space;

namespace FrEee.Gameplay.Commands.Fleets;
public interface ILeaveFleetCommand
: ICommand<IMobileSpaceObject>
{
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
using FrEee.Objects.GameState;
using System.Collections.Generic;

namespace FrEee.Objects.Commands;
namespace FrEee.Gameplay.Commands;

/// <summary>
/// A command to some object.
Expand Down
16 changes: 16 additions & 0 deletions FrEee.Core.Domain/Gameplay/Commands/ICommandFactory.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FrEee.Gameplay.Commands;

/// <summary>
/// Builds various types of <see cref="ICommand"> used by the game.
/// </summary>
public interface ICommandFactory
{
// TODO: split these out into separate factories for each category and add parameters
ICommand Research();
}
21 changes: 21 additions & 0 deletions FrEee.Core.Domain/Gameplay/Commands/IToggleCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FrEee.Objects.Civilization;
using FrEee.Objects.Civilization.Orders;

namespace FrEee.Gameplay.Commands;

/// <summary>
/// A command which enables or disables something.
/// </summary>
public interface IToggleCommand
: ICommand
{
/// <summary>
/// Is the toggle enabled or disabled?
/// </summary>
bool IsToggleEnabled { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FrEee.Gameplay.Commands.Messages;
public interface IDeleteMessageCommand
: IMessageCommand
{
}
15 changes: 15 additions & 0 deletions FrEee.Core.Domain/Gameplay/Commands/Messages/IMessageCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FrEee.Objects.Civilization;
using FrEee.Objects.Civilization.Diplomacy.Messages;

namespace FrEee.Gameplay.Commands.Messages;

public interface IMessageCommand
: ICommand<Empire>
{
IMessage Message { get; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FrEee.Objects.Civilization;
using FrEee.Objects.Civilization.Diplomacy.Messages;

namespace FrEee.Gameplay.Commands.Messages;

/// <summary>
/// Builds commands allowing players to manage diplomatic messages.
/// </summary>
public interface IMessageCommandFactory
{
IDeleteMessageCommand DeleteMessage(IMessage message);

ISendMessageCommand SendMessage(IMessage message);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FrEee.Gameplay.Commands.Messages;
public interface ISendMessageCommand
: IMessageCommand
{
}
Loading

0 comments on commit a041ccb

Please sign in to comment.