-
Notifications
You must be signed in to change notification settings - Fork 69
/
AsyncBaseObjectPool.cs
115 lines (94 loc) · 3.4 KB
/
AsyncBaseObjectPool.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading.Tasks;
using AltV.Net.Elements.Entities;
using AltV.Net.Elements.Pools;
namespace AltV.Net.Async
{
public abstract class AsyncBaseObjectPool<TBaseObject> : IBaseObjectPool<TBaseObject>
where TBaseObject : IBaseObject
{
private readonly ConcurrentDictionary<IntPtr, TBaseObject> entities =
new ConcurrentDictionary<IntPtr, TBaseObject>();
private readonly IBaseObjectFactory<TBaseObject> entityFactory;
protected AsyncBaseObjectPool(IBaseObjectFactory<TBaseObject> entityFactory)
{
this.entityFactory = entityFactory;
}
public TBaseObject Create(ICore core, IntPtr entityPointer)
{
if (entityPointer == IntPtr.Zero) return default;
if (entities.TryGetValue(entityPointer, out var baseObject)) return baseObject;
baseObject = entityFactory.Create(core, entityPointer);
Add(baseObject);
return baseObject;
}
public void Add(TBaseObject entity)
{
entities[entity.NativePointer] = entity;
OnAdd(entity);
}
public bool Remove(TBaseObject entity)
{
return Remove(entity.NativePointer);
}
public bool Remove(IntPtr entityPointer)
{
if (!entities.TryRemove(entityPointer, out var entity) || !entity.Exists) return false;
entity.OnRemove();
lock (entity)
{
BaseObjectPool<TBaseObject>.SetEntityNoLongerExists(entity);
}
OnRemove(entity);
return true;
}
public TBaseObject Get(IntPtr entityPointer)
{
return entities.TryGetValue(entityPointer, out var entity) ? entity : default;
}
public TBaseObject GetOrCreate(ICore core, IntPtr entityPointer)
{
if (entityPointer == IntPtr.Zero)
{
return default;
}
if (entities.TryGetValue(entityPointer, out var entity)) return entity;
return Create(core, entityPointer);
}
public IReadOnlyCollection<TBaseObject> GetAllObjects()
{
return (IReadOnlyCollection<TBaseObject>) entities.Values;
}
public KeyValuePair<IntPtr, TBaseObject>[] GetObjectsArray()
{
var arr = new KeyValuePair<IntPtr, TBaseObject>[entities.Count];
var i = 0;
foreach (var (ptr, entity) in entities)
{
arr[i++] = new KeyValuePair<IntPtr, TBaseObject>(ptr, entity);
}
return arr;
}
public abstract void ForEach(IBaseObjectCallback<TBaseObject> baseObjectCallback);
public abstract Task ForEach(IAsyncBaseObjectCallback<TBaseObject> asyncBaseObjectCallback);
public virtual void OnAdd(TBaseObject entity)
{
}
public virtual void OnRemove(TBaseObject entity)
{
}
public void Dispose()
{
foreach (var entity in entities.Values)
{
if (!(entity is IInternalBaseObject internalEntity)) continue;
internalEntity.ClearData();
entity.OnRemove();
OnRemove(entity);
}
entities.Clear();
}
}
}