forked from jacksondunstan/UnityNativeScripting
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathObjectStore.cs
More file actions
138 lines (127 loc) · 3.48 KB
/
Copy pathObjectStore.cs
File metadata and controls
138 lines (127 loc) · 3.48 KB
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
namespace NativeScript
{
/// <summary>
/// Stores objects and allows access to them via an int.
/// This class is thread-safe.
/// </summary>
///
/// <author>
/// JacksonDunstan, http://JacksonDunstan.com/articles/3908
/// </author>
///
/// <license>
/// MIT
/// </license>
public static class ObjectStore
{
// Stored objects. The first is always null.
private static object[] objects;
// Stack of available handles
private static int[] handles;
// Index of the next available handle
private static int nextHandleIndex;
/// <summary>
/// Initialize the object storage and reset the handles
/// </summary>
///
/// <param name="maxObjects">
/// Maximum number of objects to store. Must be positive.
/// </param>
public static void Init(int maxObjects)
{
// Initialize the objects as all null plus room for the
// first to always be null.
objects = new object[maxObjects + 1];
// Initialize the handles stack as 1, 2, 3, ...
handles = new int[maxObjects];
for (
int i = 0, handle = maxObjects;
i < maxObjects;
++i, --handle)
{
handles[i] = handle;
}
nextHandleIndex = maxObjects - 1;
}
/// <summary>
/// Store an object
/// </summary>
///
/// <param name="obj">
/// Object to store. This can be null.
/// </param>
///
/// <returns>
/// An handle to the stored object that can be used with
/// <see cref="Get"/> and <see cref="Remove"/>. If
/// <see cref="Init"/> has not yet been called, a
/// <see cref="NullReferenceException"/> will be thrown.
/// </returns>
public static int Store(object obj)
{
// Null is always zero
if (object.ReferenceEquals(obj, null))
{
return 0;
}
lock (objects)
{
// Pop a handle off the stack
int handle = handles[nextHandleIndex];
nextHandleIndex--;
// Store the object
objects[handle] = obj;
// Return the handle
return handle;
}
}
/// <summary>
/// Get the object for a given handle
/// </summary>
///
/// <param name="handle">
/// Handle of the object to get. If this is less than zero
/// or greater than the maximum number of objects passed to
/// <see cref="Init"/>, this function will throw an
/// <see cref="ArrayIndexOutOfBoundsException"/>. If this
/// is zero, not a handle returned by <see cref="Store"/>,
/// a handle returned by a call to <see cref="Store"/> with
/// a null parameter, or a handle passed to
/// <see cref="Remove"/> and not subsequently returned by
/// <see cref="Store"/>, this function will return null. If
/// <see cref="Init"/> has not yet been called, a
/// <see cref="NullReferenceException"/> will be thrown.
/// </param>
public static object Get(int handle)
{
return objects[handle];
}
/// <summary>
/// Remove a stored object
/// </summary>
///
/// <param name="handle">
/// Handle of the object to Remove. If this is less than
/// zero or greater than the maximum number of objects
/// passed to <see cref="Init"/>, this function will throw
/// an <see cref="ArrayIndexOutOfBoundsException"/>. The
/// handle may be be reused. If <see cref="Init"/> has not
/// yet been called, a <see cref="NullReferenceException"/>
/// will be thrown.
/// </param>
public static void Remove(int handle)
{
if (handle != 0)
{
lock (objects)
{
// Forget the object
objects[handle] = null;
// Push the handle onto the stack
nextHandleIndex++;
handles[nextHandleIndex] = handle;
}
}
}
}
}