Skip to content

Commit

Permalink
Fix network race conditions
Browse files Browse the repository at this point in the history
  • Loading branch information
rettoph committed Oct 21, 2021
1 parent ba2312b commit 74cf0c1
Show file tree
Hide file tree
Showing 34 changed files with 406 additions and 161 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ protected override void Draw(GameTime gameTime)
{
base.Draw(gameTime);

this.Do(debugView => debugView.RenderDebugData(_camera.Projection, _camera.View));
// this.Do(debugView => debugView.RenderDebugData(_camera.Projection, _camera.View));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
using VoidHuntersRevived.Library.Services;
using tainicom.Aether.Physics2D.Diagnostics;
using VoidHuntersRevived.Client.Library.Entities.Aether;
using VoidHuntersRevived.Client.Library.Services;

namespace VoidHuntersRevived.Client.Library.Scenes
{
Expand All @@ -30,7 +31,8 @@ public class ClientPrimaryScene : PrimaryScene
private Camera2D _camera;
private MouseService _mouse;
private AetherDebugView _debugView;
BasicEffect _effect;
private BasicEffect _effect;
private ShipPartRenderService _shipPartRenderService;
#endregion

#region Lifecycle Methods
Expand All @@ -43,6 +45,7 @@ protected override void Initialize(GuppyServiceProvider provider)
provider.Service(out _camera);
provider.Service(out _mouse);
provider.Service(out _debugView);
provider.Service(out _shipPartRenderService);


_effect = new BasicEffect(provider.GetService<GraphicsDevice>())
Expand Down Expand Up @@ -101,6 +104,13 @@ protected override void PostDraw(GameTime gameTime)
_spriteBatch.End();
}

protected override void PreUpdate(GameTime gameTime)
{
base.PreUpdate(gameTime);

_shipPartRenderService.Clean();
}

protected override void Update(GameTime gameTime)
{
base.Update(gameTime);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,73 +22,73 @@ public void RegisterServices(GuppyServiceCollection services)
#region Ship Movement Inputs
inputs.Add(new InputCommandContext()
{
Handle = "set_direction_forward",
Handle = "thrust_forward",
DefaultInput = new InputButton(Keys.W),
Lockable = false,
Commands = new[]
{
(state: ButtonState.Pressed, command: "ship set direction Forward true"),
(state: ButtonState.Released, command: "ship set direction Forward false")
(state: ButtonState.Pressed, command: "ship thrust Forward true"),
(state: ButtonState.Released, command: "ship thrust Forward false")
}
});

inputs.Add(new InputCommandContext()
{
Handle = "set_direction_turn_right",
Handle = "thrust_turn_right",
DefaultInput = new InputButton(Keys.D),
Lockable = false,
Commands = new[]
{
(state: ButtonState.Pressed, command: "ship set direction TurnRight true"),
(state: ButtonState.Released, command: "ship set direction TurnRight false")
(state: ButtonState.Pressed, command: "ship thrust TurnRight true"),
(state: ButtonState.Released, command: "ship thrust TurnRight false")
}
});

inputs.Add(new InputCommandContext()
{
Handle = "set_direction_backward",
Handle = "thrust_backward",
DefaultInput = new InputButton(Keys.S),
Lockable = false,
Commands = new[]
{
(state: ButtonState.Pressed, command: "ship set direction Backward true"),
(state: ButtonState.Released, command: "ship set direction Backward false")
(state: ButtonState.Pressed, command: "ship thrust Backward true"),
(state: ButtonState.Released, command: "ship thrust Backward false")
}
});

inputs.Add(new InputCommandContext()
{
Handle = "set_direction_turn_left",
Handle = "thrust_turn_left",
DefaultInput = new InputButton(Keys.A),
Lockable = false,
Commands = new[]
{
(state: ButtonState.Pressed, command: "ship set direction TurnLeft true"),
(state: ButtonState.Released, command: "ship set direction TurnLeft false")
(state: ButtonState.Pressed, command: "ship thrust TurnLeft true"),
(state: ButtonState.Released, command: "ship thrust TurnLeft false")
}
});

inputs.Add(new InputCommandContext()
{
Handle = "set_direction_right",
Handle = "thrust_right",
DefaultInput = new InputButton(Keys.E),
Lockable = false,
Commands = new[]
{
(state: ButtonState.Pressed, command: "ship set direction Right true"),
(state: ButtonState.Released, command: "ship set direction Right false")
(state: ButtonState.Pressed, command: "ship thrust Right true"),
(state: ButtonState.Released, command: "ship thrust Right false")
}
});

inputs.Add(new InputCommandContext()
{
Handle = "set_direction_left",
Handle = "thrust_left",
DefaultInput = new InputButton(Keys.Q),
Lockable = false,
Commands = new[]
{
(state: ButtonState.Pressed, command: "ship set direction Left true"),
(state: ButtonState.Released, command: "ship set direction Left false")
(state: ButtonState.Pressed, command: "ship thrust Left true"),
(state: ButtonState.Released, command: "ship thrust Left false")
}
});

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
using Guppy;
using Guppy.DependencyInjection;
using Guppy.Extensions.System.Collections;
using Guppy.Extensions.Utilities;
using Guppy.Services;
using Guppy.Utilities;
using Guppy.Utilities.Cameras;
using Guppy.Utilities.Primitives;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
Expand All @@ -11,6 +14,7 @@
using System.Text;
using tainicom.Aether.Physics2D.Collision.Shapes;
using VoidHuntersRevived.Library.Contexts.ShipParts;
using VoidHuntersRevived.Library.Dtos.Utilities;
using VoidHuntersRevived.Library.Entities.ShipParts;
using VoidHuntersRevived.Library.Enums;
using VoidHuntersRevived.Library.Services;
Expand All @@ -20,10 +24,19 @@ namespace VoidHuntersRevived.Client.Library.Services
{
public class ShipPartRenderService : Frameable
{
#region Constants
private static Color TransparentWhite = new Color(255, 255, 255, 0);
#endregion

#region Private Structs
private struct ShipPartContextPrimitiveData
private class ShipPartContextPrimitiveData
{
public Color DefaultShapeColor;
public Color DefaultPathColor;
public Boolean InheritColor;

public PrimitiveShape[] Shapes;
public PrimitivePath[] Paths;
}
#endregion

Expand All @@ -32,8 +45,15 @@ private struct ShipPartContextPrimitiveData

private PrimitiveBatch<VertexPositionColor> _primitiveBatch;
private ShipPartService _shipParts;
private ColorService _colors;

private PrimitivePath _estrangedNodePrimitive;
private PrimitivePath _nodePrimitive;

private Camera2D _camera;

private Single _configuredZoom;
private Single _width = 1;
#endregion

#region Lifecycle Methods
Expand All @@ -45,8 +65,11 @@ protected override void PreInitialize(GuppyServiceProvider provider)

provider.Service(out _primitiveBatch);
provider.Service(out _shipParts);
provider.Service(out _colors);
provider.Service(out _camera);

_nodePrimitive = PrimitivePath.Create(0.025f, new Vector2(0.2f, -0.1f), new Vector2(0.025f, 0), new Vector2(0.2f, 0.1f));
_estrangedNodePrimitive = PrimitivePath.Create(0.025f, new Vector2(0.1f, -0.075f), new Vector2(0, 0), new Vector2(0.1f, 0.075f));
_nodePrimitive = PrimitivePath.Create(0.025f, new Vector2(0.075f, 0), new Vector2(0, 0));
}

protected override void Initialize(GuppyServiceProvider provider)
Expand Down Expand Up @@ -74,6 +97,8 @@ protected override void PostRelease()

_primitiveBatch = null;
_shipParts = null;
_colors = null;
_camera = null;
}
#endregion

Expand All @@ -84,41 +109,72 @@ protected override void PostRelease()
/// <param name="shipPart"></param>
public void Render(ShipPart shipPart, ref Matrix worldTransformation)
{
foreach(PrimitiveShape shape in _primitives[shipPart.Context.Id].Shapes)
ShipPartContextPrimitiveData primitiveData = _primitives[shipPart.Context.Id];

Color shapeColor = primitiveData.DefaultShapeColor;
Color pathColor = primitiveData.DefaultPathColor;

if(primitiveData.InheritColor && shipPart.Chain.Color.HasValue)
{
shapeColor = Color.Lerp(shipPart.Chain.Color.Value, Color.Transparent, 0.25f);
pathColor = Color.Lerp(shipPart.Chain.Color.Value, ShipPartRenderService.TransparentWhite, 0.25f);
}


foreach (PrimitiveShape shape in primitiveData.Shapes)
{ // Draw all shapes...
_primitiveBatch.DrawPrimitive(
shape,
Color.Green,
shapeColor,
worldTransformation);
}

// _primitiveBatch.TryFlushTriangleVertices(true);
foreach (PrimitivePath path in primitiveData.Paths)
{ // Draw all paths...
_primitiveBatch.DrawPrimitive(
path,
pathColor,
worldTransformation);
}

foreach(ConnectionNode node in shipPart.ConnectionNodes)
foreach (ConnectionNode node in shipPart.ConnectionNodes)
{
var nodeWorldTransformation = node.LocalTransformationMatrix * worldTransformation;

if(node.Connection.State == ConnectionNodeState.Estranged)
{
_primitiveBatch.DrawPrimitive(
_estrangedNodePrimitive,
pathColor,
nodeWorldTransformation);
}
else
{
Color color = default;

switch (node.Connection.State)
{
case ConnectionNodeState.Estranged:
color = Color.Red;
break;
case ConnectionNodeState.Parent:
color = Color.Blue;
break;
case ConnectionNodeState.Child:
color = Color.White;
break;
}

var nodeWorldTransformation = node.LocalTransformationMatrix * worldTransformation;

_primitiveBatch.DrawPrimitive(
_nodePrimitive,
color,
pathColor,
nodeWorldTransformation);
}
}
}

// _primitiveBatch.TryFlushLineVertices(true);
public void Clean()
{
if (_camera.Zoom != _configuredZoom && Math.Abs(_configuredZoom - _camera.Zoom) / _configuredZoom > 0.005f)
{
_configuredZoom = _camera.Zoom;
_width = (1 / _camera.Zoom);

foreach (ShipPartContextPrimitiveData primitives in _primitives.Values)
{
foreach(PrimitivePath path in primitives.Paths)
{
path.Width = _width;
}
}

_nodePrimitive.Width = _width;
_estrangedNodePrimitive.Width = _width;
}
}
#endregion
Expand All @@ -133,15 +189,20 @@ private void RegisterContextPrimitiveData(ShipPartContext context)
{
_primitives[context.Id] = new ShipPartContextPrimitiveData()
{
Shapes = context.Shapes.Select(s =>
DefaultShapeColor = Color.Lerp(_colors[context.Color], Color.Transparent, 0.25f),
DefaultPathColor = Color.Lerp(_colors[context.Color], ShipPartRenderService.TransparentWhite, 0.25f),
InheritColor = context.InheritColor,
Shapes = context.Shapes.Where(s => s.IsVisible).Select(s =>
{
switch(s.ShapeType)
return s.Data switch
{
case ShapeType.Polygon:
return PrimitiveShape.Create((s as PolygonShape).Vertices);
default:
throw new ArgumentOutOfRangeException($"Unable to create PrimitiveShape for {s.ShapeType}");
}
PolygonShape polygon => PrimitiveShape.Create(polygon.Vertices),
_ => throw new ArgumentOutOfRangeException($"Unable to create PrimitiveShape for {s.Data.ShapeType}")
};
}).ToArray(),
Paths = context.Paths.Select(p =>
{
return PrimitivePath.Create(0.25f, p);
}).ToArray()
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,17 @@

namespace VoidHuntersRevived.Library.Components.Entities.Players
{
internal sealed class UserPlayerCurrentUserDirectionComponent : UserPlayerCurrentUserCommandActionBaseComponent<DirectionState>
internal sealed class UserPlayerCurrentUserThrustComponent : UserPlayerCurrentUserCommandActionBaseComponent<DirectionState>
{
public override UInt32 ActionRequestMessageType => Constants.Messages.UserPlayer.RequestDirectionChanged;

public override String CurrentUserCommandInput => "ship set direction";
public override String CurrentUserCommandInput => "ship thrust";

public override ICommandHandler CurrentUserCommandHandler => CommandHandler.Create<Direction, Boolean, IConsole>(this.HandleSetDirectionCommand);

protected override Boolean TryDoActionRequest(DirectionState request, out DirectionState response)
{
if (this.Entity.Ship?.Components.Get<ShipDirectionComponent>().TrySetDirection(request) ?? false)
if (this.Entity.Ship?.Components.Get<ShipThrustComponent>().TrySetDirection(request) ?? false)
{
response = request;
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,19 +77,21 @@ protected override void ReleaseCurrentUser()
#region UserPlayerCurrentUserBaseComponent<TractorBeamAction> Implementation
protected override Boolean TryDoActionRequest(TractorBeamAction request, out TractorBeamAction response)
{
this.log.Info("UserPlayerCurrentUserTractorBeamComponent::TryDoActionRequest => TryAction()");
this.log.Info($"{nameof(UserPlayerCurrentUserTractorBeamComponent)}::{nameof(TryDoActionRequest)} => {nameof(ShipTractorBeamComponent)}::{nameof(ShipTractorBeamComponent.TryAction)}");
response = this.Entity.Ship?.Components.Get<ShipTractorBeamComponent>().TryAction(request) ?? default;

return response.Type != TractorBeamActionType.None;
}

protected override TractorBeamAction ReadCurrentUserActionRequestMessage(NetIncomingMessage im)
{
this.Entity.Ship.Components.Get<ShipTargetingComponent>().Target = im.ReadVector2();
return im.ReadTractorBeamAction(_shipParts, ShipPartSerializationFlags.None);
}

protected override void WriteCurrentUserActionRequestMessage(NetOutgoingMessage om, TractorBeamAction request)
{
om.Write(this.Entity.Ship.Components.Get<ShipTargetingComponent>().Target);
om.Write(request, _shipParts, ShipPartSerializationFlags.None);
}
#endregion
Expand Down
Loading

0 comments on commit 74cf0c1

Please sign in to comment.