public IOwned <RpcObjectRef <TService> > PublishInstance <TService>(IOwned <TService> serviceInstance) where TService : class { if (serviceInstance is null) { throw new ArgumentNullException(nameof(serviceInstance)); } var allServices = RpcBuilderUtil.GetAllServices(serviceInstance.Value.GetType(), true); this.TryRegisterServiceDefinitions(allServices, null); var connectionInfo = this.RetrieveConnectionInfo(); lock (this.syncRoot) { var serviceInstanceId = RpcObjectId.NewId(); var publishedServices = this.PublishInstanceCore_Locked(allServices, serviceInstance, serviceInstanceId, false); Func <ValueTask> disposeAction = () => this.UnpublishInstanceAsync(serviceInstanceId); return(OwnedObject.Create(new RpcObjectRef <TService>( connectionInfo, serviceInstanceId, publishedServices.ToArray()), disposeAction)); } }
private void ScrubOwnedObject(OwnedObject ownedObject) { //remove any children that don't need to exist on the server foreach (Transform child in ownedObject.transform) { if (child.CompareTag(CLIENT_ANY_TAG) || child.CompareTag(CLIENT_SELF_TAG)) { Destroy(child.gameObject); } } //destroy any remaining visibility togglers foreach (VisibilityToggle visibilityToggle in ownedObject.GetComponentsInChildren <VisibilityToggle>()) { Destroy(visibilityToggle); } //destroy any remaining animators foreach (Animator animator in ownedObject.GetComponentsInChildren <Animator>()) { Destroy(animator); } //destroy any remaining audio sources foreach (AudioSource audioSource in ownedObject.GetComponents <AudioSource>()) { Destroy(audioSource); } }
public static IOwned <RpcObjectRef <TService> > PublishInstance <TService>(this IRpcServer server, TService serviceInstance, bool takeOwnership = false) where TService : class { if (server is null) { throw new ArgumentNullException(nameof(server)); } return(server.ServicePublisher.PublishInstance(takeOwnership ? OwnedObject.Create(serviceInstance) : OwnedObject.CreateUnowned(serviceInstance))); }
protected void ColorizeOwnedObject(OwnedObject ownedObject) { Color teamColor = clientGameManager.GameState.teams[ownedObject.teamId].color; foreach (Colorable colorable in ownedObject.GetComponentsInChildren <Colorable>()) { colorable.SetColor(teamColor); } }
public IOwned <RpcSingletonRef <TService> > PublishSingleton <TService>(Func <IServiceProvider?, IOwned <TService> > factory) where TService : class { this.PublishSingletonFactoryCore(factory); return(OwnedObject.Create(new RpcSingletonRef <TService>( this.RetrieveConnectionInfo()), () => this.UnpublishSingletonAsync <TService>())); }
[Test] public void CircularOwnership() { OwnedObject data = new OwnedObject(); data.TestProperty = new OwnedObject(); data.TestProperty.TestProperty = data; OwnedObject dataResult = data.DeepClone(); Assert.IsTrue(dataResult.TestProperty.TestProperty == dataResult); }
public static IOwned <RpcSingletonRef <TService> > PublishSingleton <TService>(this IRpcServicePublisher servicePublisher, Func <TService> factory) where TService : class { if (servicePublisher is null) { throw new ArgumentNullException(nameof(servicePublisher)); } IOwned <TService> CreateActivatedService(IServiceProvider?_) => OwnedObject.Create(factory()); return(servicePublisher.PublishSingleton(CreateActivatedService)); }
[Test] public void CloneRecursiveGraphs() { // Make sure that object referencing themselves can be cloned without problems OwnedObject source = new OwnedObject(); source.TestData = 42; source.TestProperty = source; OwnedObject target = source.DeepClone(); Assert.AreNotSame(source, target); Assert.AreEqual(source.TestData, target.TestData); Assert.AreSame(target, target.TestProperty); }
/// <summary> /// Publishes an RPC service instance using an instance factory. /// </summary> /// <typeparam name="TService">The type of the published instance.</typeparam> /// <param name="factory">A factory function that should create the service instance specified by the <see cref="RpcObjectId"/>. If the created /// instance implements <see cref="IDisposable"/> the instance will be disposed when the RPC call has finished. /// </param> /// <returns>A scoped object including the <see cref="RpcObjectRef"/> identifying the published instance. The scoped object will unpublish /// the service instance when disposed.</returns> public static IOwned <RpcObjectRef <TService> > PublishInstance <TService>(this IRpcServicePublisher servicePublisher, Func <RpcObjectId, TService> factory) where TService : class { if (servicePublisher is null) { throw new ArgumentNullException(nameof(servicePublisher)); } IOwned <TService> CreateActivatedService(IServiceProvider?services, RpcObjectId objectId) { return(OwnedObject.Create(factory(objectId))); } return(servicePublisher.PublishInstance(CreateActivatedService)); }
private void SetTargeting(GameObject targetingObject, int resourceCost, OwnedObject referencedObject = null, Entity targetingEntity = null) { if (targetingObject == null && currentTargetingObject != null) { Destroy(currentTargetingObject); } currentTargetingObject = targetingObject; currentTargetingResourceCost = resourceCost; currentTargetingReference = referencedObject; currentTargetingEntity = targetingEntity; if (currentTargetingObject != null) { currentTargetingCollider = currentTargetingObject.GetComponentInChildren <Collider>(); } isTargetingValid = false; }
internal static IOwned <TService> CreateActivatedService(IServiceProvider?services) { if (services == null) { throw new RpcFailureException(RpcFailure.RemoteDefinitionError, "An IServiceProvider must be supplied when services are published using IServiceProvider factories."); } TService service = services.GetService <TServiceImpl>(); if (service != null) { return(OwnedObject.CreateUnowned(service)); } service = (TService)Factory.Value(services, Array.Empty <object>()); return(OwnedObject.Create(service)); }
public IOwned <RpcObjectRef <TService> > PublishInstance <TService>(Func <IServiceProvider?, RpcObjectId, IOwned <TService> > factory) where TService : class { var allServices = RpcBuilderUtil.GetAllServices(typeof(TService), RpcServiceDefinitionSide.Server, true); this.TryRegisterServiceDefinitions(allServices, null); var connectionInfo = this.RetrieveConnectionInfo(); lock (this.syncRoot) { var objectId = RpcObjectId.NewId(); var publishedServices = this.PublishInstanceFactoryCore_Locked(allServices, objectId, factory); return(OwnedObject.Create(new RpcObjectRef <TService>( connectionInfo, objectId, publishedServices.ToArray()), () => this.UnpublishInstanceAsync(objectId))); } }
/// <summary> /// Publishes an RPC service instance with the help of a service provider factory. /// </summary> /// <typeparam name="TService">The type of the published instance.</typeparam> /// <param name="factory">A factory function that should create the service instance specified by the <see cref="RpcObjectId"/> /// with the help of the provided <see cref="IServiceProvider"/>.</param> /// <returns>A scoped object including the <see cref="RpcObjectRef"/> identifying the published instance. The scoped object will unpublish /// the service instance when disposed.</returns> public static IOwned <RpcObjectRef <TService> > PublishInstance <TService>(this IRpcServicePublisher servicePublisher, Func <IServiceProvider, RpcObjectId, TService> factory) where TService : class { if (servicePublisher is null) { throw new ArgumentNullException(nameof(servicePublisher)); } IOwned <TService> CreateActivatedService(IServiceProvider?services, RpcObjectId objectId) { if (services == null) { throw new RpcDefinitionException("An IServiceProvider must be supplied when services are published using IServiceProvider factories."); } return(OwnedObject.CreateUnowned(factory(services, objectId))); } return(servicePublisher.PublishInstance(CreateActivatedService)); }
public IOwned <RpcSingletonRef <TService> > PublishSingleton <TService>(IOwned <TService> singletonService) where TService : class { if (singletonService == null) { throw new ArgumentNullException(nameof(singletonService)); } var allServices = RpcBuilderUtil.GetAllServices(typeof(TService), false); this.TryRegisterServiceDefinitions(allServices, null); var publishedServices = this.VerifyPublishedServices(allServices); var connectionInfo = this.RetrieveConnectionInfo(); lock (this.syncRoot) { var instanceKey = new InstanceKey(singletonService.Value); foreach (var serviceType in publishedServices.ServiceTypes) { if (this.singletonServiceTypeToServiceImpl.ContainsKey(serviceType) || this.singletonServiceTypeToFactory.ContainsKey(serviceType)) { throw new RpcDefinitionException($"A singleton for the type '{serviceType}' has already been published."); } } this.singletonTypeToPublishedServices.Add(typeof(TService), publishedServices); var publishedInstance = new PublishedInstance(singletonService); foreach (var serviceType in publishedServices.ServiceTypes) { this.singletonServiceTypeToServiceImpl.Add(serviceType, publishedInstance); } } return(OwnedObject.Create(new RpcSingletonRef <TService>( connectionInfo), () => this.UnpublishSingletonAsync <TService>())); }
private void ScrubOwnedObject(OwnedObject ownedObject) { if (ownedObject is Entity) { Entity entity = ownedObject as Entity; if (ownedObject.teamId == clientGameManager.MyPlayer.teamId) { //disable visibility updates for teammates since they will always be visible entity.updateVisibility = false; } else { //immediately send visibility=false update to ensure everything starts hidden entity.VisibilityTargetDispatch(null); } } //remove any children that don't need to exist on a client foreach (Transform child in ownedObject.transform) { if (child.CompareTag(CLIENT_SELF_TAG) && ownedObject.playerId != clientGameManager.MyPlayer.id) { Destroy(child.gameObject); } else if (child.CompareTag(CLIENT_TEAM_OR_AUTHORITY_TAG) && ownedObject.teamId != clientGameManager.MyPlayer.teamId) { Destroy(child.gameObject); } } //disable nav mesh agents since they can cause "jiggling" on the client screen if (ownedObject.GetComponent <NavMeshAgent>() != null) { ownedObject.GetComponent <NavMeshAgent>().enabled = false; } }
public RpcObjectRef <TService> GetOrPublishInstance <TService>(TService serviceInstance) where TService : class { if (serviceInstance is null) { throw new ArgumentNullException(nameof(serviceInstance)); } InstanceKey key; lock (this.syncRoot) { key = new InstanceKey(serviceInstance); if (this.serviceImplToId.TryGetValue(key, out var instanceId)) { return(new RpcObjectRef <TService>(this.connectionInfo, instanceId, this.GetPublishedServices(instanceId).ToArray())); } } // Not published, so we try to register the serviceInstance's service definitions // and then publish it. var allServices = RpcBuilderUtil.GetAllServices(serviceInstance.GetType(), true); this.TryRegisterServiceDefinitions(allServices, null); var connectionInfo = this.RetrieveConnectionInfo(); lock (this.syncRoot) { // Let's try again. if (this.serviceImplToId.TryGetValue(key, out var instanceId)) { // Somebody beat us to it. return(new RpcObjectRef <TService>(this.connectionInfo, instanceId, this.GetPublishedServices(instanceId).ToArray())); } var objectId = RpcObjectId.NewId(); var newPublishedServices = this.PublishInstanceCore_Locked(allServices, OwnedObject.CreateUnowned(serviceInstance), objectId, true); return(new RpcObjectRef <TService>(connectionInfo, objectId, newPublishedServices.ToArray())); } }