Skip to content

Commit

Permalink
Lifetime
Browse files Browse the repository at this point in the history
  • Loading branch information
EgardA committed Jan 9, 2025
1 parent 164c27b commit 5b4f650
Show file tree
Hide file tree
Showing 8 changed files with 230 additions and 10 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
using E2E.Tests.Environment;
using E2E.Tests.Util;
using TaleWorlds.CampaignSystem.Roster;
using Xunit.Abstractions;

namespace E2E.Tests.Services.FlattenedTroopRosters
{
public class TroopRosterLifetimeTests : IDisposable
{
E2ETestEnvironment TestEnvironment { get; }
public TroopRosterLifetimeTests(ITestOutputHelper output)
{
TestEnvironment = new E2ETestEnvironment(output);
}

public void Dispose()
{
TestEnvironment.Dispose();
}

[Fact]
public void ServerCreateFlattenedTroopRoster_SyncAllClients()
{
// Arrange
var server = TestEnvironment.Server;

// Act
string? RosterId = null;
server.Call(() =>
{
FlattenedTroopRoster flattenedTroopRoster = new FlattenedTroopRoster();
Assert.True(server.ObjectManager.TryGetId(flattenedTroopRoster, out RosterId));
});

// Assert
Assert.True(server.ObjectManager.TryGetObject<FlattenedTroopRoster>(RosterId, out var _));

foreach (var client in TestEnvironment.Clients)
{
Assert.True(client.ObjectManager.TryGetObject<FlattenedTroopRoster>(RosterId, out var _));
}
}

[Fact]
public void ClientCreateFlattenedTroopRoster_DoesNothing()
{
// Arrange
var server = TestEnvironment.Server;
var client1 = TestEnvironment.Clients.First();
// Act
string? TroopRosterId = null;
client1.Call(() =>
{
var Roster = new FlattenedTroopRoster();
Assert.False(client1.ObjectManager.TryGetId(Roster, out TroopRosterId));
});

// Assert
Assert.False(server.ObjectManager.TryGetObject<FlattenedTroopRoster>(TroopRosterId, out var _));
foreach (var client in TestEnvironment.Clients)
{
Assert.False(client.ObjectManager.TryGetObject<FlattenedTroopRoster>(TroopRosterId, out var _));
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using GameInterface.Services.Registry;
using System;
using System.Threading;
using TaleWorlds.CampaignSystem;
using TaleWorlds.CampaignSystem.Roster;
using TaleWorlds.CampaignSystem.Settlements;
using TaleWorlds.CampaignSystem.Settlements.Buildings;

namespace GameInterface.Services.FlattenedTroopRosters;

/// <summary>
/// Registry for <see cref="FlattenedTroopRoster"/> type
/// </summary>
internal class FlattenedTroopRosterRegistry : RegistryBase<FlattenedTroopRoster>
{
private const string FlattenedIdPrefix = "CoopFlattened";
private static int InstanceCounter = 0;

public FlattenedTroopRosterRegistry(IRegistryCollection collection) : base(collection) { }

public override void RegisterAll()
{

}

protected override string GetNewId(FlattenedTroopRoster obj)
{
return $"{FlattenedIdPrefix}_{Interlocked.Increment(ref InstanceCounter)}";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
using Common.Logging;
using Common.Messaging;
using Common.Network;
using Common.Util;
using GameInterface.Services.FlattenedTroopRosters.Messages;
using GameInterface.Services.ObjectManager;
using GameInterface.Services.TroopRosters.Handlers;
using GameInterface.Services.TroopRosters.Messages;
using Serilog;
using TaleWorlds.CampaignSystem.Roster;

namespace GameInterface.Services.FlattenedTroopRosters.Handlers
{
internal class FlattenedTroopRosterLifetimeHandler : IHandler
{
private static readonly ILogger Logger = LogManager.GetLogger<TroopRosterLifetimeHandler>();
private readonly IMessageBroker messageBroker;
private readonly IObjectManager objectManager;
private readonly INetwork network;

public FlattenedTroopRosterLifetimeHandler(IMessageBroker messageBroker, IObjectManager objectManager, INetwork network)
{
this.messageBroker = messageBroker;
this.objectManager = objectManager;
this.network = network;
messageBroker.Subscribe<FlattenedTroopRosterCreated>(Handle);
messageBroker.Subscribe<NetworkCreateFlattenedTroopRoster>(Handle);
}

public void Dispose()
{
messageBroker.Unsubscribe<FlattenedTroopRosterCreated>(Handle);
messageBroker.Unsubscribe<NetworkCreateFlattenedTroopRoster>(Handle);
}

private void Handle(MessagePayload<FlattenedTroopRosterCreated> obj)
{
var payload = obj.What;

if (objectManager.AddNewObject(payload.FlattenedTroopRoster, out string rosterId) == false) return;

var message = new NetworkCreateFlattenedTroopRoster(rosterId, payload.Count);
network.SendAll(message);
}

private void Handle(MessagePayload<NetworkCreateFlattenedTroopRoster> obj)
{
var payload = obj.What;

var troopRoster = ObjectHelper.SkipConstructor<FlattenedTroopRoster>();
if (objectManager.AddExisting(payload.FlattenedTroopRosterId, troopRoster) == false)
{
Logger.Error("Failed to add existing TroopRoster, {id}", payload.FlattenedTroopRosterId);
return;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using Common.Messaging;
using TaleWorlds.CampaignSystem.Roster;

namespace GameInterface.Services.FlattenedTroopRosters.Messages
{
internal class FlattenedTroopRosterCreated : IEvent
{
public FlattenedTroopRoster FlattenedTroopRoster { get; }
public int Count { get; }

public FlattenedTroopRosterCreated(FlattenedTroopRoster flattenedTroopRoster, int count)
{
FlattenedTroopRoster = flattenedTroopRoster;
Count = count;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using Common.Messaging;
using ProtoBuf;

namespace GameInterface.Services.FlattenedTroopRosters.Messages
{
[ProtoContract(SkipConstructor = true)]
internal class NetworkCreateFlattenedTroopRoster : ICommand
{
public string FlattenedTroopRosterId { get; }
public int Count { get; }

public NetworkCreateFlattenedTroopRoster(string flattenedTroopRosterId, int count)
{
FlattenedTroopRosterId = flattenedTroopRosterId;
Count = count;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
using System;
using Common.Logging;
using Common.Messaging;
using GameInterface.Policies;
using GameInterface.Services.FlattenedTroopRosters.Messages;
using GameInterface.Services.TroopRosters.Patches;
using HarmonyLib;
using Serilog;
using TaleWorlds.CampaignSystem.Roster;

namespace GameInterface.Services.FlattenedTroopRosters.Patches
{
[HarmonyPatch]
internal class FlattenedTroopRosterLifetimePatches
{
private static ILogger Logger = LogManager.GetLogger<TroopRosterLifetimePatches>();

[HarmonyPatch(typeof(FlattenedTroopRoster), MethodType.Constructor, typeof(int))]
[HarmonyPrefix]
private static bool CreateFlattenedTroopRosterPrefix(ref FlattenedTroopRoster __instance, int count)
{
// Call original if we call this function
if (CallOriginalPolicy.IsOriginalAllowed()) return true;

if (ModInformation.IsClient)
{
Logger.Error("Client created unmanaged {name}\n"
+ "Callstack: {callstack}", typeof(TroopRoster), Environment.StackTrace);
return false;
}

var message = new FlattenedTroopRosterCreated(__instance, count);

MessageBroker.Instance.Publish(__instance, message);

return true;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,10 @@
using Common.Messaging;
using Common.Network;
using Common.Util;
using GameInterface.Services.Buildings.Handlers;
using GameInterface.Services.ObjectManager;
using GameInterface.Services.TroopRosters.Messages;
using Serilog;
using System;
using System.Collections.Generic;
using System.Text;
using TaleWorlds.CampaignSystem.Roster;
using TaleWorlds.CampaignSystem.Settlements.Buildings;

namespace GameInterface.Services.TroopRosters.Handlers
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
using Common.Logging;
using System;
using Common.Logging;
using Common.Messaging;
using GameInterface.Policies;
using GameInterface.Services.Armies.Messages.Lifetime;
using GameInterface.Services.TroopRosters.Messages;
using HarmonyLib;
using Serilog;
using System;
using TaleWorlds.CampaignSystem.Party;
using TaleWorlds.CampaignSystem.Roster;
using TaleWorlds.CampaignSystem.Settlements.Buildings;

namespace GameInterface.Services.TroopRosters.Patches
{
Expand Down

0 comments on commit 5b4f650

Please sign in to comment.