refactor: network implementations switched to universe objects

This commit is contained in:
Syntriax 2025-05-25 13:34:45 +03:00
parent 0da5ac6f57
commit 12f4950ffb
9 changed files with 82 additions and 49 deletions

21
.vscode/launch.json vendored
View File

@ -2,7 +2,18 @@
"version": "0.2.0", "version": "0.2.0",
"configurations": [ "configurations": [
{ {
"name": ".NET Launch (Client)", "name": ".NET Launch (Client) 1",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"program": "${workspaceFolder}/Platforms/Desktop/bin/Debug/net9.0/Desktop.exe",
"args": [],
"cwd": "${workspaceFolder}",
"stopAtEntry": false,
"console": "internalConsole"
},
{
"name": ".NET Launch (Client) 2",
"type": "coreclr", "type": "coreclr",
"request": "launch", "request": "launch",
"preLaunchTask": "build", "preLaunchTask": "build",
@ -26,8 +37,12 @@
], ],
"compounds": [ "compounds": [
{ {
"name": ".NET Launch Both", "name": ".NET Launch 2 Client & 1 Server",
"configurations": [".NET Launch (Server)", ".NET Launch (Client)"] "configurations": [
".NET Launch (Server)",
".NET Launch (Client) 1",
".NET Launch (Client) 2"
]
} }
] ]
} }

2
Engine

@ -1 +1 @@
Subproject commit 6b9020bd2491d44163f019a79d16a2f3b8a78306 Subproject commit 2df41e18818e314ebfa21e578500d5e3161cf850

View File

@ -22,7 +22,7 @@ public class PaddleBehaviour(Keys Up, Keys Down, float High, float Low, float Sp
private bool isDownPressed = false; private bool isDownPressed = false;
private IButtonInputs<Keys> inputs = null!; private IButtonInputs<Keys> inputs = null!;
private INetworkCommunicatorClient networkClient = null!; private INetworkCommunicatorClient? networkClient = null!;
private INetworkCommunicatorServer? networkServer = null; private INetworkCommunicatorServer? networkServer = null;
private TweenManager tweenManager = null!; private TweenManager tweenManager = null!;
@ -41,9 +41,9 @@ public class PaddleBehaviour(Keys Up, Keys Down, float High, float Low, float Sp
protected override void OnFirstActiveFrame() protected override void OnFirstActiveFrame()
{ {
inputs = Universe.FindRequiredBehaviour<IButtonInputs<Keys>>(); inputs = Universe.FindRequired<IButtonInputs<Keys>>();
networkClient = Universe.FindRequiredBehaviour<INetworkCommunicatorClient>(); networkClient = Universe.Find<INetworkCommunicatorClient>();
networkServer = Universe.FindBehaviour<INetworkCommunicatorServer>(); networkServer = Universe.Find<INetworkCommunicatorServer>();
tweenManager = Universe.GetRequiredUniverseObject<TweenManager>(); tweenManager = Universe.GetRequiredUniverseObject<TweenManager>();
inputs.RegisterOnPress(Up, OnUpPressed); inputs.RegisterOnPress(Up, OnUpPressed);
@ -62,10 +62,10 @@ public class PaddleBehaviour(Keys Up, Keys Down, float High, float Low, float Sp
inputs.UnregisterOnRelease(Down, OnDownReleased); inputs.UnregisterOnRelease(Down, OnDownReleased);
} }
private void OnUpPressed(IButtonInputs<Keys> inputs, Keys keys) { isUpPressed = true; networkClient.SendToServer(new PaddleKeyStatePacket(this)); } private void OnUpPressed(IButtonInputs<Keys> inputs, Keys keys) { isUpPressed = true; networkClient?.SendToServer(new PaddleKeyStatePacket(this)); }
private void OnUpReleased(IButtonInputs<Keys> inputs, Keys keys) { isUpPressed = false; networkClient.SendToServer(new PaddleKeyStatePacket(this)); } private void OnUpReleased(IButtonInputs<Keys> inputs, Keys keys) { isUpPressed = false; networkClient?.SendToServer(new PaddleKeyStatePacket(this)); }
private void OnDownPressed(IButtonInputs<Keys> inputs, Keys keys) { isDownPressed = true; networkClient.SendToServer(new PaddleKeyStatePacket(this)); } private void OnDownPressed(IButtonInputs<Keys> inputs, Keys keys) { isDownPressed = true; networkClient?.SendToServer(new PaddleKeyStatePacket(this)); }
private void OnDownReleased(IButtonInputs<Keys> inputs, Keys keys) { isDownPressed = false; networkClient.SendToServer(new PaddleKeyStatePacket(this)); } private void OnDownReleased(IButtonInputs<Keys> inputs, Keys keys) { isDownPressed = false; networkClient?.SendToServer(new PaddleKeyStatePacket(this)); }
public void OnServerPacketArrived(PaddleKeyStatePacket packet, string from) public void OnServerPacketArrived(PaddleKeyStatePacket packet, string from)
{ {
@ -73,6 +73,8 @@ public class PaddleBehaviour(Keys Up, Keys Down, float High, float Low, float Sp
return; return;
packet.Position = Transform.Position; packet.Position = Transform.Position;
isUpPressed = packet.IsUpPressed;
isDownPressed = packet.IsDownPressed;
networkServer?.SendToClient("*", packet); networkServer?.SendToClient("*", packet);
} }

View File

@ -22,7 +22,7 @@ public class PongManagerBehaviour : Behaviour,
private readonly Random random = new(); private readonly Random random = new();
private BallBehaviour ball = null!; private BallBehaviour ball = null!;
private INetworkCommunicatorClient networkClient = null!; private INetworkCommunicatorClient? networkClient = null!;
private INetworkCommunicatorServer? networkServer = null; private INetworkCommunicatorServer? networkServer = null;
public int ScoreLeft { get; private set; } = 0; public int ScoreLeft { get; private set; } = 0;
@ -36,12 +36,12 @@ public class PongManagerBehaviour : Behaviour,
protected override void OnFirstActiveFrame() protected override void OnFirstActiveFrame()
{ {
var buttonInputs = Universe.FindRequiredBehaviour<IButtonInputs<Keys>>(); IButtonInputs<Keys> buttonInputs = Universe.FindRequired<IButtonInputs<Keys>>();
buttonInputs.RegisterOnRelease(Keys.Space, (_, _1) => networkClient.SendToServer(new PongResetPacket())); buttonInputs.RegisterOnRelease(Keys.Space, (_, _1) => networkClient?.SendToServer(new PongResetPacket()));
networkClient = Universe.FindRequiredBehaviour<INetworkCommunicatorClient>();
ball = Universe.FindRequiredBehaviour<BallBehaviour>(); ball = Universe.FindRequiredBehaviour<BallBehaviour>();
networkServer = Universe.FindBehaviour<INetworkCommunicatorServer>(); networkClient = Universe.Find<INetworkCommunicatorClient>();
networkServer = Universe.Find<INetworkCommunicatorServer>();
} }
public void ScoreToLeft() public void ScoreToLeft()
@ -92,6 +92,7 @@ public class PongManagerBehaviour : Behaviour,
return Vector2D.Right.Rotate(isBackwards ? rotation + Syntriax.Engine.Core.Math.PI : rotation); return Vector2D.Right.Rotate(isBackwards ? rotation + Syntriax.Engine.Core.Math.PI : rotation);
} }
public void OnClientPacketArrived(PongStartPacket packet) => ball.LaunchBall(packet.BallVelocity);
public void OnClientPacketArrived(PongResetPacket packet) => Reset(); public void OnClientPacketArrived(PongResetPacket packet) => Reset();
public void OnClientPacketArrived(PongScoreUpdatePacket packet) public void OnClientPacketArrived(PongScoreUpdatePacket packet)
{ {
@ -103,19 +104,17 @@ public class PongManagerBehaviour : Behaviour,
public void OnServerPacketArrived(PongResetPacket packet, string from) public void OnServerPacketArrived(PongResetPacket packet, string from)
{ {
Reset(); Reset();
Vector2D ballVelocity = GetBallLaunchDirection();
ball.LaunchBall(ballVelocity);
networkServer?.SendToClient("*", new PongResetPacket()); networkServer?.SendToClient("*", new PongResetPacket());
networkServer?.SendToClient("*", new PongStartPacket() { BallVelocity = GetBallLaunchDirection() }); networkServer?.SendToClient("*", new PongStartPacket() { BallVelocity = ballVelocity });
} }
public void OnServerPacketArrived(PongStartPacket packet, string from) public void OnServerPacketArrived(PongStartPacket packet, string from)
{ {
packet = new() { BallVelocity = GetBallLaunchDirection() }; packet = new() { BallVelocity = GetBallLaunchDirection() };
networkServer?.SendToClient("*", packet);
}
public void OnClientPacketArrived(PongStartPacket packet)
{
ball.LaunchBall(packet.BallVelocity); ball.LaunchBall(packet.BallVelocity);
networkServer?.SendToClient("*", packet);
} }
public class PongStartPacket : INetworkPacket public class PongStartPacket : INetworkPacket

View File

@ -28,10 +28,7 @@ public class GamePong : Game
private BehaviourCollector<IDisplayableSprite> displayableCollector = null!; private BehaviourCollector<IDisplayableSprite> displayableCollector = null!;
private BehaviourCollector<IDisplayableShape> displayableShapeCollector = null!; private BehaviourCollector<IDisplayableShape> displayableShapeCollector = null!;
private MonoGameCamera2DBehaviour cameraBehaviour = null!; private MonoGameCamera2DBehaviour cameraBehaviour = null!;
private PongManagerBehaviour pongManager = null!; private PongManagerBehaviour pongManager = null!;
private TextScoreBehaviour leftText;
private TextScoreBehaviour rightText;
public GamePong(IUniverseObject platformSpecificUniverseObject) public GamePong(IUniverseObject platformSpecificUniverseObject)
{ {
@ -67,8 +64,24 @@ public class GamePong : Game
universe.Register(platformSpecificUniverseObject); universe.Register(platformSpecificUniverseObject);
universe.InstantiateUniverseObject<UpdateManager>().SetUniverseObject("Update Manager"); if (Environment.GetCommandLineArgs().FirstOrDefault(x => x.CompareTo("-server") == 0) is not null)
{
LiteNetLibServer server = universe.InstantiateUniverseObject<LiteNetLibServer>().SetUniverseObject("Server");
UniverseObjectFactory.Instantiate<NetworkManager>().SetUniverseObject("NetworkManager", server.BehaviourController.UniverseObject);
server.Start(8888, 2);
Window.Title = $"Server";
}
else
{
LiteNetLibClient client = universe.InstantiateUniverseObject<LiteNetLibClient>().SetUniverseObject("Client");
UniverseObjectFactory.Instantiate<NetworkManager>().SetUniverseObject("NetworkManager", client.BehaviourController.UniverseObject);
client.Connect("localhost", 8888);
Window.Title = $"Client";
universe.InstantiateUniverseObject<DrawManager>().SetUniverseObject("Draw Manager"); universe.InstantiateUniverseObject<DrawManager>().SetUniverseObject("Draw Manager");
}
universe.InstantiateUniverseObject<UpdateManager>().SetUniverseObject("Update Manager");
universe.InstantiateUniverseObject<CoroutineManager>().SetUniverseObject("Coroutine Manager"); universe.InstantiateUniverseObject<CoroutineManager>().SetUniverseObject("Coroutine Manager");
universe.InstantiateUniverseObject<TweenManager>().SetUniverseObject("Tween Manager"); universe.InstantiateUniverseObject<TweenManager>().SetUniverseObject("Tween Manager");
universe.InstantiateUniverseObject<PhysicsEngine2D>().SetUniverseObject("Physics Engine 2D"); universe.InstantiateUniverseObject<PhysicsEngine2D>().SetUniverseObject("Physics Engine 2D");
@ -139,24 +152,13 @@ public class GamePong : Game
//////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////
leftText = universe.InstantiateUniverseObject().SetUniverseObject("Score Left") universe.InstantiateUniverseObject().SetUniverseObject("Score Left")
.BehaviourController.AddBehaviour<Transform2D>().SetTransform(position: new Vector2D(-250f, 250f), scale: Vector2D.One * .25f) .BehaviourController.AddBehaviour<Transform2D>().SetTransform(position: new Vector2D(-250f, 250f), scale: Vector2D.One * .25f)
.BehaviourController.AddBehaviour<TextScoreBehaviour>(true, spriteFont); .BehaviourController.AddBehaviour<TextScoreBehaviour>(true, spriteFont);
rightText = universe.InstantiateUniverseObject().SetUniverseObject("Score Right") universe.InstantiateUniverseObject().SetUniverseObject("Score Right")
.BehaviourController.AddBehaviour<Transform2D>().SetTransform(position: new Vector2D(250f, 250f), scale: Vector2D.One * .25f) .BehaviourController.AddBehaviour<Transform2D>().SetTransform(position: new Vector2D(250f, 250f), scale: Vector2D.One * .25f)
.BehaviourController.AddBehaviour<TextScoreBehaviour>(false, spriteFont); .BehaviourController.AddBehaviour<TextScoreBehaviour>(false, spriteFont);
if (Environment.GetCommandLineArgs().FirstOrDefault(x => x.CompareTo("-server") == 0) is not null)
{
LiteNetLibServer server = universe.InstantiateUniverseObject().SetUniverseObject("Server").BehaviourController.AddBehaviour<LiteNetLibServer>();
UniverseObjectFactory.Instantiate<NetworkManager>().SetUniverseObject("NetworkManager", server.BehaviourController.UniverseObject);
server.Start(8888, 2);
Window.Title = $"{Window.Title} - Server";
}
LiteNetLibClient client = universe.InstantiateUniverseObject().SetUniverseObject("Client").BehaviourController.AddBehaviour<LiteNetLibClient>();
UniverseObjectFactory.Instantiate<NetworkManager>().SetUniverseObject("NetworkManager", client.BehaviourController.UniverseObject);
client.Connect("localhost", 8888);
} }
protected override void Update(GameTime gameTime) protected override void Update(GameTime gameTime)

View File

@ -15,7 +15,7 @@ public class LiteNetLibClient : LiteNetLibCommunicatorBase, INetworkCommunicator
public INetworkCommunicatorClient Connect(string address, int port, string? password = null) public INetworkCommunicatorClient Connect(string address, int port, string? password = null)
{ {
if (!UniverseObject.IsInUniverse) if (!IsInUniverse)
throw new($"{nameof(LiteNetLibClient)} must be in an universe to connect"); throw new($"{nameof(LiteNetLibClient)} must be in an universe to connect");
Manager.Start(); Manager.Start();
@ -33,14 +33,17 @@ public class LiteNetLibClient : LiteNetLibCommunicatorBase, INetworkCommunicator
return this; return this;
} }
protected override void OnEnteredUniverse(IUniverse universe) protected override void OnEnteringUniverse(IUniverse universe)
{ {
base.OnEnteringUniverse(universe);
cancellationTokenSource = new CancellationTokenSource(); cancellationTokenSource = new CancellationTokenSource();
PollEvents(cancellationTokenSource.Token); PollEvents(cancellationTokenSource.Token);
} }
protected override void OnExitedUniverse(IUniverse universe) protected override void OnExitingUniverse(IUniverse universe)
{ {
base.OnExitingUniverse(universe);
cancellationTokenSource?.Cancel(); cancellationTokenSource?.Cancel();
} }

View File

@ -10,7 +10,7 @@ using Syntriax.Engine.Core;
namespace Syntriax.Engine.Network; namespace Syntriax.Engine.Network;
public abstract class LiteNetLibCommunicatorBase : Behaviour, INetworkCommunicator public abstract class LiteNetLibCommunicatorBase : UniverseObject, INetworkCommunicator
{ {
protected readonly NetPacketProcessor netPacketProcessor = new(); protected readonly NetPacketProcessor netPacketProcessor = new();
@ -25,8 +25,9 @@ public abstract class LiteNetLibCommunicatorBase : Behaviour, INetworkCommunicat
return this; return this;
} }
protected override void ExitedUniverse(IUniverseObject sender, IUniverse universe) protected override void OnExitingUniverse(IUniverse universe)
{ {
base.OnExitingUniverse(universe);
Stop(); Stop();
} }

View File

@ -32,7 +32,7 @@ public class LiteNetLibServer : LiteNetLibCommunicatorBase, INetworkCommunicator
public INetworkCommunicatorServer Start(int port, int maxConnectionCount, string? password = null) public INetworkCommunicatorServer Start(int port, int maxConnectionCount, string? password = null)
{ {
if (!UniverseObject.IsInUniverse) if (!IsInUniverse)
throw new($"{nameof(LiteNetLibServer)} must be in an universe to start"); throw new($"{nameof(LiteNetLibServer)} must be in an universe to start");
Password = password ?? string.Empty; Password = password ?? string.Empty;
@ -60,7 +60,17 @@ public class LiteNetLibServer : LiteNetLibCommunicatorBase, INetworkCommunicator
return this; return this;
} }
protected override void OnEnteredUniverse(IUniverse universe) => universe.OnPostUpdate += PollEvents;
protected override void OnExitedUniverse(IUniverse universe) => universe.OnPostUpdate -= PollEvents;
private void PollEvents(IUniverse sender, UniverseTime engineTime) => Manager.PollEvents(); private void PollEvents(IUniverse sender, UniverseTime engineTime) => Manager.PollEvents();
protected override void OnEnteringUniverse(IUniverse universe)
{
base.OnEnteringUniverse(universe);
universe.OnPostUpdate += PollEvents;
}
protected override void OnExitingUniverse(IUniverse universe)
{
base.OnExitingUniverse(universe);
universe.OnPostUpdate -= PollEvents;
}
} }

View File

@ -2,6 +2,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using Syntriax.Engine.Core; using Syntriax.Engine.Core;
namespace Syntriax.Engine.Network; namespace Syntriax.Engine.Network;
@ -151,6 +152,6 @@ public class NetworkManager : UniverseObject, INetworkManager
protected override void OnEnteringUniverse(IUniverse universe) protected override void OnEnteringUniverse(IUniverse universe)
{ {
_networkEntityCollector.Assign(universe); _networkEntityCollector.Assign(universe);
NetworkCommunicator = BehaviourController.GetRequiredBehaviourInParent<INetworkCommunicator>(); NetworkCommunicator = this.GetRequiredUniverseObjectInParent<INetworkCommunicator>();
} }
} }