Пример #1
0
 /// <inheritdoc />
 public async Task RegisterEntityInterestAsync(NetworkEntityGuid guid)
 {
     using (await InternalGlobalLock.WriterLockAsync().ConfigureAwait(false))
     {
         if (EntityRefCountingMap.ContainsKey(guid.RawGuidValue))
         {
             EntityRefCountingMap[guid.RawGuidValue]++;
         }
         else
         {
             EntityRefCountingMap[guid.RawGuidValue]   = 1;
             EntityLockingObjectMap[guid.RawGuidValue] = new AsyncReaderWriterLock();
         }
     }
 }
Пример #2
0
        /// <inheritdoc />
        public async Task ReleaseEntityInterestAsync(NetworkEntityGuid guid)
        {
            using (await InternalGlobalLock.WriterLockAsync().ConfigureAwait(false))
            {
                if (EntityRefCountingMap.ContainsKey(guid.RawGuidValue))
                {
                    EntityRefCountingMap[guid.RawGuidValue]--;

                    if (EntityRefCountingMap[guid.RawGuidValue] <= 0)
                    {
                        EntityLockingObjectMap.Remove(guid.RawGuidValue, out var locker);
                        EntityRefCountingMap.Remove(guid.RawGuidValue, out int val);
                    }
                }

                //TODO: Should we throw if they try when it doesn't even know the entity?
                return;
            }
        }
Пример #3
0
        /// <inheritdoc />
        public async Task <FinalEntityLockResult> TryAquireFinalEntityLockAsync(NetworkEntityGuid guid)
        {
            IDisposable root      = null;
            IDisposable childLock = null;

            try
            {
                root = await InternalGlobalLock.WriterLockAsync().ConfigureAwait(false);

                if (!EntityRefCountingMap.ContainsKey(guid.RawGuidValue))
                {
                    return(new FinalEntityLockResult());
                }

                if (EntityRefCountingMap[guid.RawGuidValue] == 1)
                {
                    childLock = await EntityLockingObjectMap[guid.RawGuidValue].WriterLockAsync().ConfigureAwait(false);

                    //On the disposable of the lock we should clear up the entity entry.
                    return(new FinalEntityLockResult(new DisposableEventDispatcherDecorator(new AggregateDisposableLock(root, childLock), () =>
                    {
                        EntityRefCountingMap.Remove(guid.RawGuidValue, out var val1);
                        EntityLockingObjectMap.Remove(guid.RawGuidValue, out var val2);
                    })));
                }
            }
            catch (Exception e)
            {
                throw;
            }
            finally
            {
                childLock?.Dispose();
                root?.Dispose();
            }

            return(new FinalEntityLockResult());
        }