Skip to content
This repository has been archived by the owner on Jan 18, 2022. It is now read-only.

Remove the View #1364

Merged
merged 11 commits into from
Aug 7, 2020
Merged
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

## Unreleased

### Breaking Changes

- The `Authority` field on Readers and Writers has been changed to `HasAuthority`. It now returns a bool to indicate whether you have authority over the component it represents. [#1364](https://github.com/spatialos/gdk-for-unity/pull/1364)
- This no longer supports AuthorityImminentLoss.
- ComponentUpdateSystem no longer has the API `GetAuthority`, `GetComponent`, and `HasComponent`. [#1364](https://github.com/spatialos/gdk-for-unity/pull/1364)
- Use the Unity Entities `EntityManager` instead.

### Added

- Added capability to test commands through the `MockConnectionHandler`. [#1437](https://github.com/spatialos/gdk-for-unity/pull/1437)
Expand All @@ -21,6 +28,7 @@

- Added C# bindings for C Event Tracing API. [#1440](https://github.com/spatialos/gdk-for-unity/pull/1440)
- Added native classes for IO operations in Event Tracing API. [#1444](https://github.com/spatialos/gdk-for-unity/pull/1444)
- Removed the `View` class and its generated storage classes. [#1364](https://github.com/spatialos/gdk-for-unity/pull/1364)

## `0.3.9` - 2020-07-24

Expand Down
17 changes: 17 additions & 0 deletions UPGRADE_GUIDE.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
# Upgrade Guide

## From `0.3.9` to `0.3.10`

### ComponentUpdateSystem API changes

The methods `GetAuthority`, `GetComponent`, and `HasComponent` have been removed from the `ComponentUpdateSystem`.
They can be replaced by similar usage of the `EntityManager`.

* `componentUpdateSystem.GetAuthority(entityId, componentId)` to `EntityManager.HasComponent<ComponentType.Authority>(entity)`.
* `componentUpdateSystem.GetComponent<ComponentType.Snapshot>(entityId)` to `EntityManager.GetComponentData<ComponentType.Component>(entity)`.
* `componentUpdateSystem.HasComponent(componentId, entityId)` to `EntityManager.HasComponent<ComponentType.Component>(entity)`

The `WorkerSystem` and `ComponentDatabase` can be used to convert from `entityId` to `entity`, and from `componentId` to a component type.

### Readers and Writers Authority

The `Reader` and `Writer` classes have had their `public Authority Authority` property changed to `public bool HasAuthority`. `HasAuthority` now indicates whether you have authority over the given component or not.

## From `0.3.7` to `0.3.8`

### Asset based entity representation
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using Improbable.Gdk.Core;
using Improbable.Gdk.Subscriptions;
using Improbable.Worker.CInterop;
using UnityEngine;

namespace Playground.MonoBehaviours
Expand All @@ -16,7 +15,7 @@ public class ToggleRotationCommandSender : MonoBehaviour

private void Update()
{
if (reader.Authority != Authority.NotAuthoritative)
if (reader.HasAuthority)
{
// Perform sending logic only on non-authoritative workers.
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ public CoreCodegenJob(CodegenJobOptions options, IFileSystem fileSystem, Details
c => ($"{c.Name}EcsViewManager.cs", UnityEcsViewManagerGenerator.Generate),
c => ($"{c.Name}ComponentDiffStorage.cs", ComponentDiffStorageGenerator.Generate),
c => ($"{c.Name}ComponentDiffDeserializer.cs", ComponentDiffDeserializerGenerator.Generate),
c => ($"{c.Name}ViewStorage.cs", ViewStorageGenerator.Generate),
c => ($"{c.Name}Metaclass.cs", MetaclassGenerator.Generate));

Logger.Trace("Adding job targets for commands.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ public static CodeWriter Generate(UnityComponentDetails componentDetails)
public Type DiffDeserializer {{ get; }} = typeof({rootNamespace}.DiffComponentDeserializer);

public Type DiffStorage {{ get; }} = typeof({rootNamespace}.DiffComponentStorage);
public Type ViewStorage {{ get; }} = typeof({rootNamespace}.{componentDetails.Name}ViewStorage);
public Type EcsViewManager {{ get; }} = typeof({rootNamespace}.EcsViewManager);
public Type DynamicInvokable {{ get; }} = typeof({rootNamespace}.{componentDetails.Name}Dynamic);
");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ public interface IComponentMetaclass
Type DiffDeserializer { get; }

Type DiffStorage { get; }
Type ViewStorage { get; }
Type EcsViewManager { get; }
Type DynamicInvokable { get; }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,16 @@ public static IComponentMetaclass GetMetaclass(uint componentId)
return metaclass;
}

public static IComponentMetaclass GetMetaclass<T>() where T : ISpatialComponentData
zeroZshadow marked this conversation as resolved.
Show resolved Hide resolved
{
if (!ComponentsToIds.TryGetValue(typeof(T), out var id))
{
throw new ArgumentException($"Can not find Metaclass for unregistered SpatialOS component {nameof(T)}.");
}

return Metaclasses[id];
}
zeroZshadow marked this conversation as resolved.
Show resolved Hide resolved

public static uint GetComponentId<T>() where T : ISpatialComponentData
{
if (!ComponentsToIds.TryGetValue(typeof(T), out var id))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,19 +124,21 @@ public override void ResetValue(ISubscription subscription)
public abstract class CommandReceiverSubscriptionManagerBase<T> : SubscriptionManager<T>
where T : ICommandReceiver
{
private readonly ComponentUpdateSystem componentUpdateSystem;
private readonly EntityManager entityManager;

private Dictionary<EntityId, HashSet<Subscription<T>>> entityIdToReceiveSubscriptions;

private HashSet<EntityId> entitiesMatchingRequirements = new HashSet<EntityId>();
private HashSet<EntityId> entitiesNotMatchingRequirements = new HashSet<EntityId>();

private readonly uint componentId;
private readonly ComponentType componentAuthType;

protected CommandReceiverSubscriptionManagerBase(World world, uint componentId) : base(world)
{
this.componentId = componentId;
componentUpdateSystem = world.GetExistingSystem<ComponentUpdateSystem>();
var componentMetaClass = ComponentDatabase.GetMetaclass(componentId);
componentAuthType = componentMetaClass.Authority;

entityManager = world.EntityManager;

var constraintSystem = world.GetExistingSystem<ComponentConstraintsCallbackSystem>();

Expand Down Expand Up @@ -196,8 +198,7 @@ public override Subscription<T> Subscribe(EntityId entityId)
}

if (WorkerSystem.TryGetEntity(entityId, out var entity)
&& componentUpdateSystem.HasComponent(componentId, entityId)
&& componentUpdateSystem.GetAuthority(entityId, componentId) != Authority.NotAuthoritative)
&& entityManager.HasComponent(entity, componentAuthType))
{
entitiesMatchingRequirements.Add(entityId);
subscription.SetAvailable(CreateReceiver(World, entity, entityId));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ public abstract class Reader<TComponent, TUpdate> : IRequireable
protected readonly EntityManager EntityManager;
protected readonly Entity Entity;
protected readonly EntityId EntityId;

private static readonly uint ComponentId = ComponentDatabase.GetComponentId<TComponent>();
private static readonly ComponentType ComponentAuthType = ComponentDatabase.GetMetaclass<TComponent>().Authority;

private Dictionary<Action<Authority>, ulong> authorityCallbackToCallbackKey;
private Dictionary<Action<TUpdate>, ulong> updateCallbackToCallbackKey;
Expand All @@ -35,16 +37,16 @@ public TComponent Data
}
}

public Authority Authority
public bool HasAuthority
{
get
{
if (!IsValid)
{
throw new InvalidOperationException("Cannot read authority when Reader is not valid");
throw new InvalidOperationException($"Cannot read {nameof(HasAuthority)} when Reader is not valid");
}

return ComponentUpdateSystem.GetAuthority(EntityId, ComponentId);
return EntityManager.HasComponent(Entity, ComponentAuthType);
Comment on lines +40 to +49
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On balance, should we make this breaking change?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the breaking change here?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both the type and name of the property are changing.

We could keep this backwards compatible by changing the return to:

return EntityManager.HasComponent(Entity, ComponentAuthType) ? Authority.Authoritative : Authority.NotAuthoritative;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the endgame is to remove auth loss imminent, I think it's fine to make this breaking change

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, but removing auth loss imminent doesn't mandate or require this change

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess I just don't see the value in keeping backwards compatibility given we'll be imposing that Authority is essentially nothing but true or false

Sure it's breaking but it does simplify logic for users (no more ==/!= comparisons)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My opinion is that the bar for making a breaking change should be relatively high and be done for good reason. With this case I don't feel the rationale is strong enough, but if you two both feel otherwise, I'm not gonna die on this hill.

}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,15 @@ public class WorkerFlagReader
public bool IsValid;

private readonly WorkerFlagCallbackSystem callbackSystem;
private readonly View view;
private readonly WorkerSystem workerSystem;

private Dictionary<Action<string, string>, ulong> callbackToKey;

public WorkerFlagReader(World world)
{
IsValid = true;
callbackSystem = world.GetExistingSystem<WorkerFlagCallbackSystem>();
view = world.GetExistingSystem<WorkerSystem>().View;
workerSystem = world.GetExistingSystem<WorkerSystem>();
}

public event Action<string, string> OnWorkerFlagChange
Expand Down Expand Up @@ -92,7 +92,7 @@ public event Action<string, string> OnWorkerFlagChange

public string GetFlag(string name)
{
return view.GetWorkerFlag(name);
return workerSystem.GetWorkerFlag(name);
}

internal void RemoveAllCallbacks()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,18 @@ namespace Improbable.Gdk.Subscriptions
public abstract class WriterSubscriptionManager<TComponent, TWriter> : SubscriptionManager<TWriter>
where TWriter : IRequireable where TComponent : ISpatialComponentData
{
private readonly ComponentUpdateSystem componentUpdateSystem;
private readonly EntityManager entityManager;
private Dictionary<EntityId, HashSet<Subscription<TWriter>>> entityIdToWriterSubscriptions;

private readonly HashSet<EntityId> entitiesMatchingRequirements = new HashSet<EntityId>();
private readonly HashSet<EntityId> entitiesNotMatchingRequirements = new HashSet<EntityId>();

private static readonly uint ComponentId = ComponentDatabase.GetComponentId<TComponent>();
private static readonly ComponentType ComponentAuthType = ComponentDatabase.GetMetaclass<TComponent>().Authority;

protected WriterSubscriptionManager(World world) : base(world)
{
componentUpdateSystem = world.GetExistingSystem<ComponentUpdateSystem>();
entityManager = World.EntityManager;

RegisterComponentCallbacks();
}
Expand Down Expand Up @@ -84,8 +85,7 @@ public override Subscription<TWriter> Subscribe(EntityId entityId)
}

if (WorkerSystem.TryGetEntity(entityId, out var entity)
&& componentUpdateSystem.HasComponent(ComponentId, entityId)
&& componentUpdateSystem.GetAuthority(entityId, ComponentId) != Authority.NotAuthoritative)
&& entityManager.HasComponent(entity, ComponentAuthType))
{
entitiesMatchingRequirements.Add(entityId);
subscription.SetAvailable(CreateWriter(entity, entityId));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System.Collections.Generic;
using Improbable.Worker.CInterop;
using Unity.Entities;

namespace Improbable.Gdk.Core
Expand All @@ -12,7 +11,6 @@ public class ComponentUpdateSystem : ComponentSystem

public void SendUpdate<T>(in T update, EntityId entityId) where T : struct, ISpatialComponentUpdate
{
worker.View.UpdateComponent(entityId, in update);
worker.MessagesToSend.AddComponentUpdate(in update, entityId.Id);
}

Expand Down Expand Up @@ -72,26 +70,11 @@ public List<EntityId> GetComponentsRemoved(uint componentId)
return manager.GetComponentsRemoved();
}

public Authority GetAuthority(EntityId entityId, uint componentId)
{
return worker.View.GetAuthority(entityId, componentId);
}

public T GetComponent<T>(EntityId entityId) where T : struct, ISpatialComponentSnapshot
{
return worker.View.GetComponent<T>(entityId);
}

public void AcknowledgeAuthorityLoss(EntityId entityId, uint componentId)
{
worker.MessagesToSend.AcknowledgeAuthorityLoss(entityId.Id, componentId);
}
zeroZshadow marked this conversation as resolved.
Show resolved Hide resolved

public bool HasComponent(uint componentId, EntityId entityId)
{
return worker.View.HasComponent(entityId, componentId);
}

protected override void OnCreate()
{
base.OnCreate();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ public class EntitySystem : ComponentSystem

private ProfilerMarker applyDiffMarker = new ProfilerMarker("EntitySystem.ApplyDiff");

private WorkerSystem workerSystem;

public List<EntityId> GetEntitiesAdded()
{
return entitiesAdded;
Expand All @@ -29,11 +27,6 @@ public List<EntityId> GetEntitiesRemoved()
return entitiesRemoved;
}

public HashSet<EntityId> GetEntitiesInView()
{
return workerSystem.View.GetEntityIds();
}

internal void ApplyDiff(ViewDiff diff)
{
using (applyDiffMarker.Auto())
Expand All @@ -59,13 +52,6 @@ internal void ApplyDiff(ViewDiff diff)
}
}

protected override void OnCreate()
{
base.OnCreate();

workerSystem = World.GetExistingSystem<WorkerSystem>();
}

protected override void OnUpdate()
{
entitiesAdded.Clear();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace Improbable.Gdk.Core
[UpdateInGroup(typeof(SpatialOSReceiveGroup.InternalSpatialOSReceiveGroup))]
public class SpatialOSReceiveSystem : ComponentSystem
{
private WorkerSystem worker;
private WorkerSystem workerSystem;
private EcsViewSystem ecsViewSystem;
private EntitySystem entitySystem;
private NetworkStatisticsSystem networkStatisticsSystem;
Expand All @@ -21,7 +21,7 @@ protected override void OnCreate()
{
base.OnCreate();

worker = World.GetExistingSystem<WorkerSystem>();
workerSystem = World.GetExistingSystem<WorkerSystem>();
ecsViewSystem = World.GetOrCreateSystem<EcsViewSystem>();
entitySystem = World.GetOrCreateSystem<EntitySystem>();
networkStatisticsSystem = World.GetOrCreateSystem<NetworkStatisticsSystem>();
Expand All @@ -31,17 +31,16 @@ protected override void OnUpdate()
{
try
{
worker.Tick();
workerSystem.Tick();

var diff = worker.Diff;
worker.View.ApplyDiff(diff);
var diff = workerSystem.Diff;
ecsViewSystem.ApplyDiff(diff);
entitySystem.ApplyDiff(diff);
networkStatisticsSystem.ApplyDiff(diff);
}
catch (Exception e)
{
worker.LogDispatcher.HandleLog(LogType.Exception, new LogEvent("Exception:")
workerSystem.LogDispatcher.HandleLog(LogType.Exception, new LogEvent("Exception:")
.WithException(e));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ public class WorkerSystem : ComponentSystem
/// </summary>
public bool IsConnected => Worker.IsConnected;

internal readonly View View;
public IReadOnlyDictionary<string, string> WorkerFlags => Worker.WorkerFlags;

internal readonly Dictionary<EntityId, Entity> EntityIdToEntity = new Dictionary<EntityId, Entity>();

internal WorkerInWorld Worker;
internal readonly WorkerInWorld Worker;

internal ViewDiff Diff => Worker.ViewDiff;
internal MessagesToSend MessagesToSend => Worker.MessagesToSend;
Expand All @@ -50,7 +50,6 @@ public WorkerSystem(WorkerInWorld worker)
WorkerType = worker.WorkerType;
WorkerId = worker.WorkerId;
Origin = worker.Origin;
View = worker.View;
}

/// <summary>
Expand Down Expand Up @@ -94,6 +93,16 @@ public void SendLogMessage(string message, string loggerName, LogLevel logLevel,
Worker.MessagesToSend.AddLogMessage(new LogMessageToSend(message, loggerName, logLevel, entityId?.Id));
}

/// <summary>
/// Gets the value for a given worker flag.
/// </summary>
/// <param name="key">The key of the worker flag.</param>
/// <returns>The value of the flag, if it exists, null otherwise.</returns>
public string GetWorkerFlag(string key)
{
return Worker.GetWorkerFlag(key);
}

public void SendMetrics(Metrics metrics)
{
Worker.MessagesToSend.AddMetrics(metrics);
Expand Down
Loading