{"id":13676327,"url":"https://github.com/jacksondunstan/NativeCollections","last_synced_at":"2025-04-29T06:31:43.229Z","repository":{"id":44339299,"uuid":"143677456","full_name":"jacksondunstan/NativeCollections","owner":"jacksondunstan","description":"Native Collection Types for Unity","archived":false,"fork":false,"pushed_at":"2023-08-26T16:58:48.000Z","size":237,"stargazers_count":417,"open_issues_count":5,"forks_count":32,"subscribers_count":15,"default_branch":"master","last_synced_at":"2025-04-05T17:09:28.333Z","etag":null,"topics":["csharp","unity","unity-scripts","unity3d","unity3d-development","unity3d-script"],"latest_commit_sha":null,"homepage":"https://jacksondunstan.com/articles/tag/native-collection","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jacksondunstan.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2018-08-06T04:44:24.000Z","updated_at":"2025-04-04T16:24:51.000Z","dependencies_parsed_at":"2024-01-06T14:59:01.667Z","dependency_job_id":"f7e3e98b-8290-426a-86e6-ecbdef0ef3a8","html_url":"https://github.com/jacksondunstan/NativeCollections","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jacksondunstan%2FNativeCollections","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jacksondunstan%2FNativeCollections/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jacksondunstan%2FNativeCollections/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jacksondunstan%2FNativeCollections/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jacksondunstan","download_url":"https://codeload.github.com/jacksondunstan/NativeCollections/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251450656,"owners_count":21591407,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["csharp","unity","unity-scripts","unity3d","unity3d-development","unity3d-script"],"created_at":"2024-08-02T13:00:22.939Z","updated_at":"2025-04-29T06:31:38.213Z","avatar_url":"https://github.com/jacksondunstan.png","language":"C#","readme":"# Native Collections\n\nA small library of native collections like `NativeArray\u003cT\u003e` suitable to be used with Unity 2018.1 or greater. No additional packages (e.g. ECS or Burst) are required.\n\n[![openupm](https://img.shields.io/npm/v/com.jacksondunstan.native-collections?label=openupm\u0026registry_uri=https://package.openupm.com)](https://openupm.com/packages/com.jacksondunstan.native-collections/)\n\n# Getting Started\n\nClone or download this repository and copy the `JacksonDunstanNativeCollections` directory somewhere inside your Unity project's `Assets` directory.\n\nAdd this as a package to your project by adding the below as an entry to the dependencies in the `/Package/manifest.json` file:\n\n```json\n\"com.jacksondunstan.native-collections\": \"https://github.com/jacksondunstan/NativeCollections.git\"\n```\n\nFor more information on adding git repositories as a package see the [Git support on Package Manager](https://docs.unity3d.com/Manual/upm-git.html) in the Unity Documentation.\n\n# NativeLinkedList\u0026lt;T\u0026gt;\n\nThis is a doubly-linked list backed by parallel arrays. Here's how to use it:\n\n```csharp\n// Create an empty list with capacity for five nodes\nNativeLinkedList\u003cint\u003e list = new NativeLinkedList\u003cint\u003e(5, Allocator.Temp);\n\n// Add some nodes to the list\nlist.InsertAfter(list.Tail, 10);\nlist.InsertAfter(list.Tail, 20);\nlist.InsertAfter(list.Tail, 30);\nlist.InsertAfter(list.Tail, 40);\nlist.InsertAfter(list.Tail, 50);\n\n// Iterate over the list\nforeach (int val in list)\n{\n\tDebug.Log(val);\n}\n\n// Remove a node from the middle\nlist.Remove(list.GetEnumeratorAtIndex(2));\n\n// Insert a node into the middle\nlist.InsertBefore(list.Head.Next, 15);\n\n// Sort the nodes so they can be accessed sequentially\nlist.SortNodeMemoryAddresses();\n\n// Access the nodes sequentially\nfor (int i = 0; i \u003c list.Length; ++i)\n{\n\tDebug.Log(list[i]);\n}\n\n// Dispose the list's native memory\nlist.Dispose();\n```\n\nThere is much more functionality available. See [the source](JacksonDunstanNativeCollections/NativeLinkedList.cs) for more.\n\nTo read about the making of this type, see this [article series](https://jacksondunstan.com/articles/4865).\n\n# NativeChunkedList\u0026lt;T\u0026gt;\n\nThis is a dynamically-resizable list backed by arrays that store \"chunks\" of elements and an array of pointers to those chunks. Here's how to use it:\n\n```csharp\n// Create an empty list with capacity for 4096 elements in 1024 element chunks\nNativeChunkedList\u003cint\u003e list = new NativeChunkedList\u003cint\u003e(\n\t1024,\n\t4096,\n\tAllocator.Temp);\n\n// Add some elements to the list\nlist.Add(10);\nlist.Add(20);\nlist.Add(30);\nlist.Add(40);\nlist.Add(50);\n\n// Iterate over the list\nforeach (int val in list)\n{\n\tDebug.Log(val);\n}\n\n// Remove an element from the middle\nlist.RemoveAt(2);\n\n// Insert an element into the middle\nlist.Insert(1, 15);\n\n// Access the elements sequentially\nforeach (var e in list.Chunks)\n{\n\tforeach (int val in e)\n\t{\n\t\tDebug.Log(val);\n\t}\n}\n\n// Dispose the list's native memory\nlist.Dispose();\n```\n\nThere is much more functionality available. See [the source](JacksonDunstanNativeCollections/NativeChunkedList.cs) for more.\n\nTo read about the making of this type, see this [article series](https://jacksondunstan.com/articles/4963).\n\n# NativeHashSet\u0026lt;T\u0026gt;\n\nThis is a collection of unique keys that aren't mapped to values. Here's how to use it:\n\n```csharp\n// Create an empty set\nNativeHashSet\u003cint\u003e set = new NativeHashSet\u003cint\u003e(100, Allocator.Persistent);\n\n// Add some keys\nset.TryAdd(123);\nset.TryAdd(456);\n\n// Check for containment\nset.Contains(123); // true\nset.Contains(1000); // false\n\n// Remove a key\nset.Remove(123);\n```\n\nThere is much more functionality available. See [the source](JacksonDunstanNativeCollections/NativeHashSet.cs) for more.\n\nTo read about the making of this type, see this [article](https://jacksondunstan.com/articles/5346).\n\n# NativeArray2D\u0026lt;T\u0026gt;\n\nThis is a 2D version of `NativeArray\u003cT\u003e`. Here's how to use it:\n\n```csharp\n// Create a 2x3 empty array\nNativeArray2D\u003cint\u003e array = new NativeArray2D\u003cint\u003e(2, 3, Allocator.Temp);\n\n// Set elements of the array\narray[0, 1] = 123;\narray[1, 2] = 456;\n\n// Get elements of the array\nint val123 = array[0, 1];\nint val456 = array[1, 2]; \n\n// Iterate over the array\nforeach (int val in array)\n{\n\tDebug.Log(val);\n}\n\n// Copy to a managed array\nint[,] managed = new int[2, 3];\narray.CopyTo(managed);\n```\n\nThere is much more functionality available. See [the source](JacksonDunstanNativeCollections/NativeArray2D.cs) for more.\n\nTo read about the making of this type, see this [article](https://jacksondunstan.com/articles/5416).\n\n# NativeIntPtr and NativeLongPtr\n\nThese are pointers to a single `int` or `long`, useful for counters among other purposes. Here's how to use `NativeIntPtr` (`NativeLongPtr` is identical):\n\n```csharp\n// Construct with the zero value\nNativeIntPtr intPtr0 = new NativeIntPtr(Allocator.Temp);\n\n// Construct with a custom value\nNativeIntPtr intPtr = new NativeIntPtr(Allocator.Temp, 123);\n\n// Read and write the value\nintPtr.Value = 20;\nDebug.Log(\"Value: \" + intPtr.Value); // prints \"Value: 20\"\n\n// Get a Parallel for use in an IJobParallelFor\nNativeIntPtr.Parallel parallel = intPtr.GetParallel();\n\n// Perform atomic writes on it\nparallel.Increment();\nparallel.Decrement();\nparallel.Add(100);\n\n// Dispose the native memory\nintPtr0.Dispose();\nintPtr.Dispose();\n```\n\nTo read about the making of this type, see this [article](https://jacksondunstan.com/articles/4940).\n\n# NativePerJobThreadIntPtr and NativePerJobThreadLongPtr\n\nThese are pointers to a single `int` or `long`. Compared to `NativeIntPtr` and `NativeLongPtr`, their `Parallel` versions are much faster to use in `ParallelFor` jobs but use more memory. Here's how to use `NativePerJobThreadIntPtr` (`NativePerJobThreadLongPtr` is identical):\n\n```csharp\n// Construct with the zero value\nNativePerJobThreadIntPtr intPtr0 = new NativePerJobThreadIntPtr(Allocator.Temp);\n\n// Construct with a custom value\nNativePerJobThreadIntPtr intPtr = new NativePerJobThreadIntPtr(Allocator.Temp, 123);\n\n// Read and write the value\nintPtr.Value = 20;\nDebug.Log(\"Value: \" + intPtr.Value); // prints \"Value: 20\"\n\n// Get a Parallel for use in an IJobParallelFor\nNativePerJobThreadIntPtr.Parallel parallel = intPtr.GetParallel();\n\n// Perform atomic writes on it\nparallel.Increment();\nparallel.Decrement();\nparallel.Add(100);\n\n// Dispose the native memory\nintPtr0.Dispose();\nintPtr.Dispose();\n```\n\nTo read about the making of this type, see this [article](https://jacksondunstan.com/articles/4942).\n\n# IJobParallelForRanged\n\nThis is a job type interface similar to `IJobParallelFor` for job types that want to operate on a range of indices from the batch rather than one index at a time. This is especially useful with `NativeChunkedList\u003cT\u003e` as its enumerable and enumerator types can iterate much more efficiently than with random access via the indexer. Here's how to use this job type interface:\n\n```csharp\n[BurstCompile]\nstruct ChunkedListIterateJobParallelFor : IJobParallelForRanged\n{\n\tpublic NativeChunkedList\u003cint\u003e List;\n\tpublic NativePerJobThreadIntPtr.Parallel Sum;\n\n\tpublic void Execute(int startIndex, int endIndex)\n\t{\n\t\tfor (\n\t\t\tvar chunks = List.GetChunksEnumerable(startIndex, endIndex).GetEnumerator();\n\t\t\tchunks.MoveNext();)\n\t\t{\n\t\t\tfor (\n\t\t\t\tvar chunk = chunks.Current.GetEnumerator();\n\t\t\t\tchunk.MoveNext();)\n\t\t\t{\n\t\t\t\tSum.Add(chunk.Current);\n\t\t\t}\n\t\t}\n\t}\n}\n```\n\nTo read about the making of this type, see this [article](https://jacksondunstan.com/articles/4976).\n\n# SharedDisposable\u0026lt;T\u0026gt;\n\nThis allows for easy sharing of `IDisposable` objects such as the above collection types. A reference count is held internally and the object is free when its last reference is released. Here's how to use it:\n\n```csharp\n// Create an IDisposable\nNativeArray\u003cint\u003e array = new NativeArray\u003cint\u003e(1, Allocator.Temp);\n\n// Prepare for sharing. Ref count = 1.\nSharedDisposable\u003cNativeArray\u003cint\u003e\u003e shared = array.Share(Allocator.Temp);\n\n// Share. Ref count = 2.\nSharedDisposable\u003cNativeArray\u003cint\u003e\u003e shared2 = shared.Ref();\n\n// Use a shared reference\nprint(\"Array len: \" + shared2.Value.Length);\n\n// Release a reference. Ref count = 1.\nshared2.Dispose();\n\n// Release the last reference. Ref count = 0.\n// The NativeArray\u003cint\u003e is disposed.\nshared.Dispose();\n\n// 'using' blocks are even more convenient\n// No need to call Dispose()\n// Exception-safe\nusing (SharedDisposable\u003cNativeArray\u003cint\u003e\u003e used = array.Share(Allocator.Temp))\n{\n    using (SharedDisposable\u003cNativeArray\u003cint\u003e\u003e used2 = shared.Ref())\n    {\n    }\n}\n```\n\nTo read about the making of this type, see this [article](https://jacksondunstan.com/articles/5441).\n\n# License\n\n[MIT](LICENSE.md)\n","funding_links":[],"categories":["高性能数据结构和算法","Open Source Repositories","C#","Open Source Packages"],"sub_categories":["FPS","DOTS"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjacksondunstan%2FNativeCollections","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjacksondunstan%2FNativeCollections","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjacksondunstan%2FNativeCollections/lists"}