Initial Commit
This commit is contained in:
parent
53eb92e9af
commit
270ab7d11f
15341 changed files with 700234 additions and 0 deletions
|
@ -0,0 +1,33 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Specialized;
|
||||
using UnityEngine.Scripting;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
// Making this inherit OrderedDictionary for now because metadata
|
||||
// doesn't work well for unordered dictionaries. The ideal solution
|
||||
// would be to rework the MetadataDictionaryAdaptor to not require
|
||||
// the index at all, then make this inherit Dictionary<object, object>
|
||||
|
||||
public sealed class AotDictionary : OrderedDictionary
|
||||
{
|
||||
public AotDictionary() : base() { }
|
||||
public AotDictionary(IEqualityComparer comparer) : base(comparer) { }
|
||||
public AotDictionary(int capacity) : base(capacity) { }
|
||||
public AotDictionary(int capacity, IEqualityComparer comparer) : base(capacity, comparer) { }
|
||||
|
||||
[Preserve]
|
||||
public static void AotStubs()
|
||||
{
|
||||
var dictionary = new AotDictionary();
|
||||
|
||||
dictionary.Add(default(object), default(object));
|
||||
dictionary.Remove(default(object));
|
||||
var item = dictionary[default(object)];
|
||||
dictionary[default(object)] = default(object);
|
||||
dictionary.Contains(default(object));
|
||||
dictionary.Clear();
|
||||
var count = dictionary.Count;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f097bbb63a5fa43369651ebaf0812b0f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,26 @@
|
|||
using System.Collections;
|
||||
using UnityEngine.Scripting;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public sealed class AotList : ArrayList
|
||||
{
|
||||
public AotList() : base() { }
|
||||
public AotList(int capacity) : base(capacity) { }
|
||||
public AotList(ICollection c) : base(c) { }
|
||||
|
||||
[Preserve]
|
||||
public static void AotStubs()
|
||||
{
|
||||
var list = new AotList();
|
||||
|
||||
list.Add(default(object));
|
||||
list.Remove(default(object));
|
||||
var item = list[default(int)];
|
||||
list[default(int)] = default(object);
|
||||
list.Contains(default(object));
|
||||
list.Clear();
|
||||
var count = list.Count;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: a8adccab0e6b44bfa9204ceaad999770
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,159 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public class DebugDictionary<TKey, TValue> : IDictionary<TKey, TValue>, IDictionary
|
||||
{
|
||||
private readonly Dictionary<TKey, TValue> dictionary = new Dictionary<TKey, TValue>();
|
||||
|
||||
public TValue this[TKey key]
|
||||
{
|
||||
get
|
||||
{
|
||||
return dictionary[key];
|
||||
}
|
||||
set
|
||||
{
|
||||
Debug($"Set: {key} => {value}");
|
||||
dictionary[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
object IDictionary.this[object key]
|
||||
{
|
||||
get
|
||||
{
|
||||
return this[(TKey)key];
|
||||
}
|
||||
set
|
||||
{
|
||||
this[(TKey)key] = (TValue)value;
|
||||
}
|
||||
}
|
||||
|
||||
public string label { get; set; } = "Dictionary";
|
||||
|
||||
public bool debug { get; set; } = false;
|
||||
|
||||
public int Count => dictionary.Count;
|
||||
|
||||
object ICollection.SyncRoot => ((ICollection)dictionary).SyncRoot;
|
||||
|
||||
bool ICollection.IsSynchronized => ((ICollection)dictionary).IsSynchronized;
|
||||
|
||||
ICollection IDictionary.Values => ((IDictionary)dictionary).Values;
|
||||
|
||||
bool IDictionary.IsReadOnly => ((IDictionary)dictionary).IsReadOnly;
|
||||
|
||||
bool IDictionary.IsFixedSize => ((IDictionary)dictionary).IsFixedSize;
|
||||
|
||||
bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly => ((ICollection<KeyValuePair<TKey, TValue>>)dictionary).IsReadOnly;
|
||||
|
||||
public ICollection<TKey> Keys => dictionary.Keys;
|
||||
|
||||
ICollection IDictionary.Keys => ((IDictionary)dictionary).Keys;
|
||||
|
||||
public ICollection<TValue> Values => dictionary.Values;
|
||||
|
||||
void ICollection.CopyTo(Array array, int index)
|
||||
{
|
||||
((ICollection)dictionary).CopyTo(array, index);
|
||||
}
|
||||
|
||||
private void Debug(string message)
|
||||
{
|
||||
if (!debug)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(label))
|
||||
{
|
||||
message = $"[{label}] {message}";
|
||||
}
|
||||
|
||||
UnityEngine.Debug.Log(message + "\n");
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return ((IEnumerable)dictionary).GetEnumerator();
|
||||
}
|
||||
|
||||
void IDictionary.Remove(object key)
|
||||
{
|
||||
Remove((TKey)key);
|
||||
}
|
||||
|
||||
bool IDictionary.Contains(object key)
|
||||
{
|
||||
return ContainsKey((TKey)key);
|
||||
}
|
||||
|
||||
void IDictionary.Add(object key, object value)
|
||||
{
|
||||
Add((TKey)key, (TValue)value);
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
Debug("Clear");
|
||||
dictionary.Clear();
|
||||
}
|
||||
|
||||
IDictionaryEnumerator IDictionary.GetEnumerator()
|
||||
{
|
||||
return ((IDictionary)dictionary).GetEnumerator();
|
||||
}
|
||||
|
||||
public bool Contains(KeyValuePair<TKey, TValue> item)
|
||||
{
|
||||
return dictionary.Contains(item);
|
||||
}
|
||||
|
||||
void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item)
|
||||
{
|
||||
((ICollection<KeyValuePair<TKey, TValue>>)dictionary).Add(item);
|
||||
}
|
||||
|
||||
void ICollection<KeyValuePair<TKey, TValue>>.CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
|
||||
{
|
||||
((ICollection<KeyValuePair<TKey, TValue>>)dictionary).CopyTo(array, arrayIndex);
|
||||
}
|
||||
|
||||
bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> item)
|
||||
{
|
||||
return ((ICollection<KeyValuePair<TKey, TValue>>)dictionary).Remove(item);
|
||||
}
|
||||
|
||||
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
|
||||
{
|
||||
return dictionary.GetEnumerator();
|
||||
}
|
||||
|
||||
public bool ContainsKey(TKey key)
|
||||
{
|
||||
return dictionary.ContainsKey(key);
|
||||
}
|
||||
|
||||
public void Add(TKey key, TValue value)
|
||||
{
|
||||
Debug($"Add: {key} => {value}");
|
||||
dictionary.Add(key, value);
|
||||
}
|
||||
|
||||
public bool Remove(TKey key)
|
||||
{
|
||||
Debug($"Remove: {key}");
|
||||
return dictionary.Remove(key);
|
||||
}
|
||||
|
||||
public bool TryGetValue(TKey key, out TValue value)
|
||||
{
|
||||
return dictionary.TryGetValue(key, out value);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 41ca2a75f36964ef7a3a443f34ba6874
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,26 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public class FlexibleDictionary<TKey, TValue> : Dictionary<TKey, TValue>
|
||||
{
|
||||
public new TValue this[TKey key]
|
||||
{
|
||||
get
|
||||
{
|
||||
return base[key];
|
||||
}
|
||||
set
|
||||
{
|
||||
if (ContainsKey(key))
|
||||
{
|
||||
base[key] = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
Add(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 0f23d5c6cf81d46a99f18c2f734bdccc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,38 @@
|
|||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public class GuidCollection<T> : KeyedCollection<Guid, T>, IKeyedCollection<Guid, T> where T : IIdentifiable
|
||||
{
|
||||
protected override Guid GetKeyForItem(T item)
|
||||
{
|
||||
return item.guid;
|
||||
}
|
||||
|
||||
protected override void InsertItem(int index, T item)
|
||||
{
|
||||
Ensure.That(nameof(item)).IsNotNull(item);
|
||||
|
||||
base.InsertItem(index, item);
|
||||
}
|
||||
|
||||
protected override void SetItem(int index, T item)
|
||||
{
|
||||
Ensure.That(nameof(item)).IsNotNull(item);
|
||||
|
||||
base.SetItem(index, item);
|
||||
}
|
||||
|
||||
public bool TryGetValue(Guid key, out T value)
|
||||
{
|
||||
if (Dictionary == null)
|
||||
{
|
||||
value = default(T);
|
||||
return false;
|
||||
}
|
||||
|
||||
return Dictionary.TryGetValue(key, out value);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 106fdba61aee041bb848696298f2a0cb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,13 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public interface IKeyedCollection<TKey, TItem> : ICollection<TItem>
|
||||
{
|
||||
TItem this[TKey key] { get; }
|
||||
TItem this[int index] { get; } // For allocation free enumerators
|
||||
bool TryGetValue(TKey key, out TItem value);
|
||||
bool Contains(TKey key);
|
||||
bool Remove(TKey key);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 838e8a6e5d50f44d6988900179976bf1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,11 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public interface IMergedCollection<T> : ICollection<T>
|
||||
{
|
||||
bool Includes<TI>() where TI : T;
|
||||
bool Includes(Type elementType);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 954150586dd10405f91f4be9407eeff1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,13 @@
|
|||
namespace Unity.VisualScripting
|
||||
{
|
||||
public interface INotifiedCollectionItem
|
||||
{
|
||||
void BeforeAdd();
|
||||
|
||||
void AfterAdd();
|
||||
|
||||
void BeforeRemove();
|
||||
|
||||
void AfterRemove();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: ca4bb37a65b7748358d2789431d7aa49
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,13 @@
|
|||
using System;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public interface INotifyCollectionChanged<T>
|
||||
{
|
||||
event Action<T> ItemAdded;
|
||||
|
||||
event Action<T> ItemRemoved;
|
||||
|
||||
event Action CollectionChanged;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: db8af6900bbbd4c77818f39666021768
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,15 @@
|
|||
namespace Unity.VisualScripting
|
||||
{
|
||||
public interface IProxyableNotifyCollectionChanged<T>
|
||||
{
|
||||
bool ProxyCollectionChange { get; set; }
|
||||
|
||||
void BeforeAdd(T item);
|
||||
|
||||
void AfterAdd(T item);
|
||||
|
||||
void BeforeRemove(T item);
|
||||
|
||||
void AfterRemove(T item);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 067acbd60a2494a05954d63584e9b346
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,62 @@
|
|||
// ==++==
|
||||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
//
|
||||
// ==--==
|
||||
/*============================================================
|
||||
**
|
||||
** Interface: ISet
|
||||
**
|
||||
** <OWNER>kimhamil</OWNER>
|
||||
**
|
||||
**
|
||||
** Purpose: Base interface for all generic sets.
|
||||
**
|
||||
**
|
||||
===========================================================*/
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
/// <summary>
|
||||
/// Generic collection that guarantees the uniqueness of its elements, as defined
|
||||
/// by some comparer. It also supports basic set operations such as Union, Intersection,
|
||||
/// Complement and Exclusive Complement.
|
||||
/// </summary>
|
||||
public interface ISet<T> : ICollection<T>
|
||||
{
|
||||
//Add ITEM to the set, return true if added, false if duplicate
|
||||
new bool Add(T item);
|
||||
|
||||
//Transform this set into its union with the IEnumerable<T> other
|
||||
void UnionWith(IEnumerable<T> other);
|
||||
|
||||
//Transform this set into its intersection with the IEnumberable<T> other
|
||||
void IntersectWith(IEnumerable<T> other);
|
||||
|
||||
//Transform this set so it contains no elements that are also in other
|
||||
void ExceptWith(IEnumerable<T> other);
|
||||
|
||||
//Transform this set so it contains elements initially in this or in other, but not both
|
||||
void SymmetricExceptWith(IEnumerable<T> other);
|
||||
|
||||
//Check if this set is a subset of other
|
||||
bool IsSubsetOf(IEnumerable<T> other);
|
||||
|
||||
//Check if this set is a superset of other
|
||||
bool IsSupersetOf(IEnumerable<T> other);
|
||||
|
||||
//Check if this set is a subset of other, but not the same as it
|
||||
bool IsProperSupersetOf(IEnumerable<T> other);
|
||||
|
||||
//Check if this set is a superset of other, but not the same as it
|
||||
bool IsProperSubsetOf(IEnumerable<T> other);
|
||||
|
||||
//Check if this set has any elements in common with other
|
||||
bool Overlaps(IEnumerable<T> other);
|
||||
|
||||
//Check if this set contains the same and only the same elements as other
|
||||
bool SetEquals(IEnumerable<T> other);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e8bad27d2153d44cba7a1fa7e451d5e6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,150 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public class MergedCollection<T> : IMergedCollection<T>
|
||||
{
|
||||
public MergedCollection()
|
||||
{
|
||||
collections = new Dictionary<Type, ICollection<T>>();
|
||||
}
|
||||
|
||||
private readonly Dictionary<Type, ICollection<T>> collections;
|
||||
|
||||
public int Count
|
||||
{
|
||||
get
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
foreach (var collection in collections.Values)
|
||||
{
|
||||
count += collection.Count;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsReadOnly => false;
|
||||
|
||||
public void Include<TI>(ICollection<TI> collection) where TI : T
|
||||
{
|
||||
collections.Add(typeof(TI), new VariantCollection<T, TI>(collection));
|
||||
}
|
||||
|
||||
public bool Includes<TI>() where TI : T
|
||||
{
|
||||
return Includes(typeof(TI));
|
||||
}
|
||||
|
||||
public bool Includes(Type implementationType)
|
||||
{
|
||||
return GetCollectionForType(implementationType, false) != null;
|
||||
}
|
||||
|
||||
public ICollection<TI> ForType<TI>() where TI : T
|
||||
{
|
||||
return ((VariantCollection<T, TI>)GetCollectionForType(typeof(TI))).implementation;
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
public IEnumerator<T> GetEnumerator()
|
||||
{
|
||||
foreach (var collection in collections.Values)
|
||||
{
|
||||
foreach (var item in collection)
|
||||
{
|
||||
yield return item;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ICollection<T> GetCollectionForItem(T item)
|
||||
{
|
||||
Ensure.That(nameof(item)).IsNotNull(item);
|
||||
|
||||
return GetCollectionForType(item.GetType());
|
||||
}
|
||||
|
||||
private ICollection<T> GetCollectionForType(Type type, bool throwOnFail = true)
|
||||
{
|
||||
if (collections.ContainsKey(type))
|
||||
{
|
||||
return collections[type];
|
||||
}
|
||||
|
||||
foreach (var collectionByType in collections)
|
||||
{
|
||||
if (collectionByType.Key.IsAssignableFrom(type))
|
||||
{
|
||||
return collectionByType.Value;
|
||||
}
|
||||
}
|
||||
|
||||
if (throwOnFail)
|
||||
{
|
||||
throw new InvalidOperationException($"No sub-collection available for type '{type}'.");
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public bool Contains(T item)
|
||||
{
|
||||
return GetCollectionForItem(item).Contains(item);
|
||||
}
|
||||
|
||||
public virtual void Add(T item)
|
||||
{
|
||||
GetCollectionForItem(item).Add(item);
|
||||
}
|
||||
|
||||
public virtual void Clear()
|
||||
{
|
||||
foreach (var collection in collections.Values)
|
||||
{
|
||||
collection.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool Remove(T item)
|
||||
{
|
||||
return GetCollectionForItem(item).Remove(item);
|
||||
}
|
||||
|
||||
public void CopyTo(T[] array, int arrayIndex)
|
||||
{
|
||||
if (array == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(array));
|
||||
}
|
||||
|
||||
if (arrayIndex < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(arrayIndex));
|
||||
}
|
||||
|
||||
if (array.Length - arrayIndex < Count)
|
||||
{
|
||||
throw new ArgumentException();
|
||||
}
|
||||
|
||||
var i = 0;
|
||||
|
||||
foreach (var collection in collections.Values)
|
||||
{
|
||||
collection.CopyTo(array, arrayIndex + i);
|
||||
i += collection.Count;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: e0381bb4e0f05444598e51b5a33edf4d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,320 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public class MergedKeyedCollection<TKey, TItem> : IMergedCollection<TItem>
|
||||
{
|
||||
public MergedKeyedCollection() : base()
|
||||
{
|
||||
collections = new Dictionary<Type, IKeyedCollection<TKey, TItem>>();
|
||||
collectionsLookup = new Dictionary<Type, IKeyedCollection<TKey, TItem>>();
|
||||
}
|
||||
|
||||
protected readonly Dictionary<Type, IKeyedCollection<TKey, TItem>> collections;
|
||||
|
||||
// Used for performance optimization when finding the right collection for a type
|
||||
protected readonly Dictionary<Type, IKeyedCollection<TKey, TItem>> collectionsLookup;
|
||||
|
||||
public TItem this[TKey key]
|
||||
{
|
||||
get
|
||||
{
|
||||
if (key == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(key));
|
||||
}
|
||||
|
||||
foreach (var collectionByType in collections)
|
||||
{
|
||||
if (collectionByType.Value.Contains(key))
|
||||
{
|
||||
return collectionByType.Value[key];
|
||||
}
|
||||
}
|
||||
|
||||
throw new KeyNotFoundException();
|
||||
}
|
||||
}
|
||||
|
||||
public int Count
|
||||
{
|
||||
get
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
foreach (var collectionByType in collections)
|
||||
{
|
||||
count += collectionByType.Value.Count;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsReadOnly => false;
|
||||
|
||||
public bool Includes<TSubItem>() where TSubItem : TItem
|
||||
{
|
||||
return Includes(typeof(TSubItem));
|
||||
}
|
||||
|
||||
public bool Includes(Type elementType)
|
||||
{
|
||||
return GetCollectionForType(elementType, false) != null;
|
||||
}
|
||||
|
||||
public IKeyedCollection<TKey, TSubItem> ForType<TSubItem>() where TSubItem : TItem
|
||||
{
|
||||
return ((VariantKeyedCollection<TItem, TSubItem, TKey>)GetCollectionForType(typeof(TSubItem))).implementation;
|
||||
}
|
||||
|
||||
public virtual void Include<TSubItem>(IKeyedCollection<TKey, TSubItem> collection) where TSubItem : TItem
|
||||
{
|
||||
var type = typeof(TSubItem);
|
||||
var variantCollection = new VariantKeyedCollection<TItem, TSubItem, TKey>(collection);
|
||||
collections.Add(type, variantCollection);
|
||||
collectionsLookup.Add(type, variantCollection);
|
||||
}
|
||||
|
||||
protected IKeyedCollection<TKey, TItem> GetCollectionForItem(TItem item)
|
||||
{
|
||||
Ensure.That(nameof(item)).IsNotNull(item);
|
||||
|
||||
return GetCollectionForType(item.GetType());
|
||||
}
|
||||
|
||||
protected IKeyedCollection<TKey, TItem> GetCollectionForType(Type type, bool throwOnFail = true)
|
||||
{
|
||||
Ensure.That(nameof(type)).IsNotNull(type);
|
||||
|
||||
if (collectionsLookup.TryGetValue(type, out var collection))
|
||||
{
|
||||
return collection;
|
||||
}
|
||||
|
||||
foreach (var collectionByType in collections)
|
||||
{
|
||||
if (collectionByType.Key.IsAssignableFrom(type))
|
||||
{
|
||||
collection = collectionByType.Value;
|
||||
collectionsLookup.Add(type, collection);
|
||||
return collection;
|
||||
}
|
||||
}
|
||||
|
||||
if (throwOnFail)
|
||||
{
|
||||
throw new InvalidOperationException($"No sub-collection available for type '{type}'.");
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected IKeyedCollection<TKey, TItem> GetCollectionForKey(TKey key, bool throwOnFail = true)
|
||||
{
|
||||
// Optim: avoid boxing here.
|
||||
// Ensure.That(nameof(key)).IsNotNull(key);
|
||||
|
||||
foreach (var collectionsByType in collections)
|
||||
{
|
||||
if (collectionsByType.Value.Contains(key))
|
||||
{
|
||||
return collectionsByType.Value;
|
||||
}
|
||||
}
|
||||
|
||||
if (throwOnFail)
|
||||
{
|
||||
throw new InvalidOperationException($"No sub-collection available for key '{key}'.");
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryGetValue(TKey key, out TItem value)
|
||||
{
|
||||
var collection = GetCollectionForKey(key, false);
|
||||
|
||||
value = default(TItem);
|
||||
|
||||
return collection != null && collection.TryGetValue(key, out value);
|
||||
}
|
||||
|
||||
public virtual void Add(TItem item)
|
||||
{
|
||||
GetCollectionForItem(item).Add(item);
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
foreach (var collection in collections.Values)
|
||||
{
|
||||
collection.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
public bool Contains(TItem item)
|
||||
{
|
||||
return GetCollectionForItem(item).Contains(item);
|
||||
}
|
||||
|
||||
public bool Remove(TItem item)
|
||||
{
|
||||
return GetCollectionForItem(item).Remove(item);
|
||||
}
|
||||
|
||||
public void CopyTo(TItem[] array, int arrayIndex)
|
||||
{
|
||||
if (array == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(array));
|
||||
}
|
||||
|
||||
if (arrayIndex < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(arrayIndex));
|
||||
}
|
||||
|
||||
if (array.Length - arrayIndex < Count)
|
||||
{
|
||||
throw new ArgumentException();
|
||||
}
|
||||
|
||||
var i = 0;
|
||||
|
||||
foreach (var collection in collections.Values)
|
||||
{
|
||||
collection.CopyTo(array, arrayIndex + i);
|
||||
i += collection.Count;
|
||||
}
|
||||
}
|
||||
|
||||
public bool Contains(TKey key)
|
||||
{
|
||||
return GetCollectionForKey(key, false) != null;
|
||||
}
|
||||
|
||||
public bool Remove(TKey key)
|
||||
{
|
||||
return GetCollectionForKey(key).Remove(key);
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator<TItem> IEnumerable<TItem>.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
public Enumerator GetEnumerator()
|
||||
{
|
||||
return new Enumerator(this);
|
||||
}
|
||||
|
||||
public struct Enumerator : IEnumerator<TItem>
|
||||
{
|
||||
private Dictionary<Type, IKeyedCollection<TKey, TItem>>.Enumerator collectionsEnumerator;
|
||||
private TItem currentItem;
|
||||
private IKeyedCollection<TKey, TItem> currentCollection;
|
||||
private int indexInCurrentCollection;
|
||||
private bool exceeded;
|
||||
|
||||
public Enumerator(MergedKeyedCollection<TKey, TItem> merged) : this()
|
||||
{
|
||||
collectionsEnumerator = merged.collections.GetEnumerator();
|
||||
}
|
||||
|
||||
public void Dispose() { }
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
// We just started, so we're not in a collection yet
|
||||
if (currentCollection == null)
|
||||
{
|
||||
// Try to find the first collection
|
||||
if (collectionsEnumerator.MoveNext())
|
||||
{
|
||||
// There is at least a collection, start with this one
|
||||
currentCollection = collectionsEnumerator.Current.Value;
|
||||
|
||||
if (currentCollection == null)
|
||||
{
|
||||
throw new InvalidOperationException("Merged sub collection is null.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// There is no collection at all, stop
|
||||
currentItem = default(TItem);
|
||||
exceeded = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if we're within the current collection
|
||||
if (indexInCurrentCollection < currentCollection.Count)
|
||||
{
|
||||
// We are, return this element and move to the next
|
||||
currentItem = currentCollection[indexInCurrentCollection];
|
||||
indexInCurrentCollection++;
|
||||
return true;
|
||||
}
|
||||
|
||||
// We're beyond the current collection, but there may be more,
|
||||
// and because there may be many empty collections, we need to check
|
||||
// them all until we find an element, not just the next one
|
||||
while (collectionsEnumerator.MoveNext())
|
||||
{
|
||||
currentCollection = collectionsEnumerator.Current.Value;
|
||||
indexInCurrentCollection = 0;
|
||||
|
||||
if (currentCollection == null)
|
||||
{
|
||||
throw new InvalidOperationException("Merged sub collection is null.");
|
||||
}
|
||||
|
||||
if (indexInCurrentCollection < currentCollection.Count)
|
||||
{
|
||||
currentItem = currentCollection[indexInCurrentCollection];
|
||||
indexInCurrentCollection++;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// We're beyond all collections, stop
|
||||
currentItem = default(TItem);
|
||||
exceeded = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public TItem Current => currentItem;
|
||||
|
||||
Object IEnumerator.Current
|
||||
{
|
||||
get
|
||||
{
|
||||
if (exceeded)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
return Current;
|
||||
}
|
||||
}
|
||||
|
||||
void IEnumerator.Reset()
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 520c9222b31ec4f5aa5951b64ab04a93
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,252 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
// The advantage of this class is not to provide list accessors
|
||||
// for merged lists (which would be confusing), but rather that unlike
|
||||
// merged collection, it can provide a zero-allocation enumerator.
|
||||
|
||||
// OPTIM note: Dictionary<,>.Values allocated memory the first time, so avoid it if possible
|
||||
public class MergedList<T> : IMergedCollection<T>
|
||||
{
|
||||
public MergedList()
|
||||
{
|
||||
lists = new Dictionary<Type, IList<T>>();
|
||||
}
|
||||
|
||||
protected readonly Dictionary<Type, IList<T>> lists;
|
||||
|
||||
public int Count
|
||||
{
|
||||
get
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
foreach (var listByType in lists)
|
||||
{
|
||||
count += listByType.Value.Count;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsReadOnly => false;
|
||||
|
||||
public virtual void Include<TI>(IList<TI> list) where TI : T
|
||||
{
|
||||
lists.Add(typeof(TI), new VariantList<T, TI>(list));
|
||||
}
|
||||
|
||||
public bool Includes<TI>() where TI : T
|
||||
{
|
||||
return Includes(typeof(TI));
|
||||
}
|
||||
|
||||
public bool Includes(Type elementType)
|
||||
{
|
||||
return GetListForType(elementType, false) != null;
|
||||
}
|
||||
|
||||
public IList<TI> ForType<TI>() where TI : T
|
||||
{
|
||||
return ((VariantList<T, TI>)GetListForType(typeof(TI))).implementation;
|
||||
}
|
||||
|
||||
protected IList<T> GetListForItem(T item)
|
||||
{
|
||||
Ensure.That(nameof(item)).IsNotNull(item);
|
||||
|
||||
return GetListForType(item.GetType());
|
||||
}
|
||||
|
||||
protected IList<T> GetListForType(Type type, bool throwOnFail = true)
|
||||
{
|
||||
if (lists.ContainsKey(type))
|
||||
{
|
||||
return lists[type];
|
||||
}
|
||||
|
||||
foreach (var listByType in lists)
|
||||
{
|
||||
if (listByType.Key.IsAssignableFrom(type))
|
||||
{
|
||||
return listByType.Value;
|
||||
}
|
||||
}
|
||||
|
||||
if (throwOnFail)
|
||||
{
|
||||
throw new InvalidOperationException($"No sub-collection available for type '{type}'.");
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public bool Contains(T item)
|
||||
{
|
||||
return GetListForItem(item).Contains(item);
|
||||
}
|
||||
|
||||
public virtual void Add(T item)
|
||||
{
|
||||
GetListForItem(item).Add(item);
|
||||
}
|
||||
|
||||
public virtual void Clear()
|
||||
{
|
||||
foreach (var listByType in lists)
|
||||
{
|
||||
listByType.Value.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
public virtual bool Remove(T item)
|
||||
{
|
||||
return GetListForItem(item).Remove(item);
|
||||
}
|
||||
|
||||
public void CopyTo(T[] array, int arrayIndex)
|
||||
{
|
||||
if (array == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(array));
|
||||
}
|
||||
|
||||
if (arrayIndex < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(arrayIndex));
|
||||
}
|
||||
|
||||
if (array.Length - arrayIndex < Count)
|
||||
{
|
||||
throw new ArgumentException();
|
||||
}
|
||||
|
||||
var i = 0;
|
||||
|
||||
foreach (var listByType in lists)
|
||||
{
|
||||
var list = listByType.Value;
|
||||
list.CopyTo(array, arrayIndex + i);
|
||||
i += list.Count;
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator<T> IEnumerable<T>.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
public Enumerator GetEnumerator()
|
||||
{
|
||||
return new Enumerator(this);
|
||||
}
|
||||
|
||||
public struct Enumerator : IEnumerator<T>
|
||||
{
|
||||
private Dictionary<Type, IList<T>>.Enumerator listsEnumerator;
|
||||
private T currentItem;
|
||||
private IList<T> currentList;
|
||||
private int indexInCurrentList;
|
||||
private bool exceeded;
|
||||
|
||||
public Enumerator(MergedList<T> merged) : this()
|
||||
{
|
||||
listsEnumerator = merged.lists.GetEnumerator();
|
||||
}
|
||||
|
||||
public void Dispose() { }
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
// We just started, so we're not in a list yet
|
||||
if (currentList == null)
|
||||
{
|
||||
// Try to find the first list
|
||||
if (listsEnumerator.MoveNext())
|
||||
{
|
||||
// There is at least a list, start with this one
|
||||
currentList = listsEnumerator.Current.Value;
|
||||
|
||||
if (currentList == null)
|
||||
{
|
||||
throw new InvalidOperationException("Merged sub list is null.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// There is no list at all, stop
|
||||
currentItem = default(T);
|
||||
exceeded = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if we're within the current list
|
||||
if (indexInCurrentList < currentList.Count)
|
||||
{
|
||||
// We are, return this element and move to the next
|
||||
currentItem = currentList[indexInCurrentList];
|
||||
indexInCurrentList++;
|
||||
return true;
|
||||
}
|
||||
|
||||
// We're beyond the current list, but there may be more,
|
||||
// and because there may be many empty lists, we need to check
|
||||
// them all until we find an element, not just the next one
|
||||
while (listsEnumerator.MoveNext())
|
||||
{
|
||||
currentList = listsEnumerator.Current.Value;
|
||||
indexInCurrentList = 0;
|
||||
|
||||
if (currentList == null)
|
||||
{
|
||||
throw new InvalidOperationException("Merged sub list is null.");
|
||||
}
|
||||
|
||||
if (indexInCurrentList < currentList.Count)
|
||||
{
|
||||
currentItem = currentList[indexInCurrentList];
|
||||
indexInCurrentList++;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// We're beyond all lists, stop
|
||||
currentItem = default(T);
|
||||
exceeded = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public T Current => currentItem;
|
||||
|
||||
Object IEnumerator.Current
|
||||
{
|
||||
get
|
||||
{
|
||||
if (exceeded)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
return Current;
|
||||
}
|
||||
}
|
||||
|
||||
void IEnumerator.Reset()
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 725c1ccd191c1427fb11a5eab7d26b3b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,58 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public struct NoAllocEnumerator<T> : IEnumerator<T>
|
||||
{
|
||||
private readonly IList<T> list;
|
||||
private int index;
|
||||
private T current;
|
||||
private bool exceeded;
|
||||
|
||||
public NoAllocEnumerator(IList<T> list) : this()
|
||||
{
|
||||
this.list = list;
|
||||
}
|
||||
|
||||
public void Dispose() { }
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
if (index < list.Count)
|
||||
{
|
||||
current = list[index];
|
||||
index++;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
index = list.Count + 1;
|
||||
current = default(T);
|
||||
exceeded = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public T Current => current;
|
||||
|
||||
Object IEnumerator.Current
|
||||
{
|
||||
get
|
||||
{
|
||||
if (exceeded)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
return Current;
|
||||
}
|
||||
}
|
||||
|
||||
void IEnumerator.Reset()
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 174d73813488e4011b9b46d8a59ae9d9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,37 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public abstract class NonNullableCollection<T> : Collection<T>
|
||||
{
|
||||
protected override void InsertItem(int index, T item)
|
||||
{
|
||||
if (item == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(item));
|
||||
}
|
||||
|
||||
base.InsertItem(index, item);
|
||||
}
|
||||
|
||||
protected override void SetItem(int index, T item)
|
||||
{
|
||||
if (item == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(item));
|
||||
}
|
||||
|
||||
base.SetItem(index, item);
|
||||
}
|
||||
|
||||
public void AddRange(IEnumerable<T> collection)
|
||||
{
|
||||
foreach (var item in collection)
|
||||
{
|
||||
Add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 23aff2603b7a04000a57f820b6f71951
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,169 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public class NonNullableDictionary<TKey, TValue> : IDictionary<TKey, TValue>, IDictionary
|
||||
{
|
||||
public NonNullableDictionary()
|
||||
{
|
||||
dictionary = new Dictionary<TKey, TValue>();
|
||||
}
|
||||
|
||||
public NonNullableDictionary(int capacity)
|
||||
{
|
||||
dictionary = new Dictionary<TKey, TValue>(capacity);
|
||||
}
|
||||
|
||||
public NonNullableDictionary(IEqualityComparer<TKey> comparer)
|
||||
{
|
||||
dictionary = new Dictionary<TKey, TValue>(comparer);
|
||||
}
|
||||
|
||||
public NonNullableDictionary(IDictionary<TKey, TValue> dictionary)
|
||||
{
|
||||
this.dictionary = new Dictionary<TKey, TValue>(dictionary);
|
||||
}
|
||||
|
||||
public NonNullableDictionary(int capacity, IEqualityComparer<TKey> comparer)
|
||||
{
|
||||
dictionary = new Dictionary<TKey, TValue>(capacity, comparer);
|
||||
}
|
||||
|
||||
public NonNullableDictionary(IDictionary<TKey, TValue> dictionary, IEqualityComparer<TKey> comparer)
|
||||
{
|
||||
this.dictionary = new Dictionary<TKey, TValue>(dictionary, comparer);
|
||||
}
|
||||
|
||||
private readonly Dictionary<TKey, TValue> dictionary;
|
||||
|
||||
public TValue this[TKey key]
|
||||
{
|
||||
get
|
||||
{
|
||||
return dictionary[key];
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
dictionary[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
object IDictionary.this[object key]
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((IDictionary)dictionary)[key];
|
||||
}
|
||||
set
|
||||
{
|
||||
((IDictionary)dictionary)[key] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int Count => dictionary.Count;
|
||||
|
||||
public bool IsSynchronized => ((ICollection)dictionary).IsSynchronized;
|
||||
|
||||
public object SyncRoot => ((ICollection)dictionary).SyncRoot;
|
||||
|
||||
public bool IsReadOnly => false;
|
||||
|
||||
public ICollection<TKey> Keys => dictionary.Keys;
|
||||
|
||||
ICollection IDictionary.Values => ((IDictionary)dictionary).Values;
|
||||
|
||||
ICollection IDictionary.Keys => ((IDictionary)dictionary).Keys;
|
||||
|
||||
public ICollection<TValue> Values => dictionary.Values;
|
||||
|
||||
public bool IsFixedSize => ((IDictionary)dictionary).IsFixedSize;
|
||||
|
||||
public void CopyTo(Array array, int index)
|
||||
{
|
||||
((ICollection)dictionary).CopyTo(array, index);
|
||||
}
|
||||
|
||||
void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item)
|
||||
{
|
||||
((ICollection<KeyValuePair<TKey, TValue>>)dictionary).Add(item);
|
||||
}
|
||||
|
||||
public void Add(TKey key, TValue value)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(value));
|
||||
}
|
||||
|
||||
dictionary.Add(key, value);
|
||||
}
|
||||
|
||||
public void Add(object key, object value)
|
||||
{
|
||||
((IDictionary)dictionary).Add(key, value);
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
dictionary.Clear();
|
||||
}
|
||||
|
||||
public bool Contains(object key)
|
||||
{
|
||||
return ((IDictionary)dictionary).Contains(key);
|
||||
}
|
||||
|
||||
IDictionaryEnumerator IDictionary.GetEnumerator()
|
||||
{
|
||||
return ((IDictionary)dictionary).GetEnumerator();
|
||||
}
|
||||
|
||||
public void Remove(object key)
|
||||
{
|
||||
((IDictionary)dictionary).Remove(key);
|
||||
}
|
||||
|
||||
bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> item)
|
||||
{
|
||||
return ((ICollection<KeyValuePair<TKey, TValue>>)dictionary).Contains(item);
|
||||
}
|
||||
|
||||
public bool ContainsKey(TKey key)
|
||||
{
|
||||
return dictionary.ContainsKey(key);
|
||||
}
|
||||
|
||||
void ICollection<KeyValuePair<TKey, TValue>>.CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
|
||||
{
|
||||
((ICollection<KeyValuePair<TKey, TValue>>)dictionary).CopyTo(array, arrayIndex);
|
||||
}
|
||||
|
||||
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
|
||||
{
|
||||
return dictionary.GetEnumerator();
|
||||
}
|
||||
|
||||
bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> item)
|
||||
{
|
||||
return ((ICollection<KeyValuePair<TKey, TValue>>)dictionary).Remove(item);
|
||||
}
|
||||
|
||||
public bool Remove(TKey key)
|
||||
{
|
||||
return dictionary.Remove(key);
|
||||
}
|
||||
|
||||
public bool TryGetValue(TKey key, out TValue value)
|
||||
{
|
||||
return dictionary.TryGetValue(key, out value);
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return dictionary.GetEnumerator();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 97fbaa55dfb0e45868ec8c2fc00466a0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,145 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public class NonNullableHashSet<T> : ISet<T>
|
||||
{
|
||||
public NonNullableHashSet()
|
||||
{
|
||||
set = new HashSet<T>();
|
||||
}
|
||||
|
||||
public NonNullableHashSet(IEqualityComparer<T> comparer)
|
||||
{
|
||||
set = new HashSet<T>(comparer);
|
||||
}
|
||||
|
||||
public NonNullableHashSet(IEnumerable<T> collection)
|
||||
{
|
||||
set = new HashSet<T>(collection);
|
||||
}
|
||||
|
||||
public NonNullableHashSet(IEnumerable<T> collection, IEqualityComparer<T> comparer)
|
||||
{
|
||||
set = new HashSet<T>(collection, comparer);
|
||||
}
|
||||
|
||||
private readonly HashSet<T> set;
|
||||
|
||||
public int Count => set.Count;
|
||||
|
||||
public bool IsReadOnly => false;
|
||||
|
||||
public bool Add(T item)
|
||||
{
|
||||
if (item == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(item));
|
||||
}
|
||||
|
||||
return set.Add(item);
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
set.Clear();
|
||||
}
|
||||
|
||||
public bool Contains(T item)
|
||||
{
|
||||
if (item == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(item));
|
||||
}
|
||||
|
||||
return set.Contains(item);
|
||||
}
|
||||
|
||||
public void CopyTo(T[] array, int arrayIndex)
|
||||
{
|
||||
set.CopyTo(array, arrayIndex);
|
||||
}
|
||||
|
||||
public void ExceptWith(IEnumerable<T> other)
|
||||
{
|
||||
set.ExceptWith(other);
|
||||
}
|
||||
|
||||
public IEnumerator<T> GetEnumerator()
|
||||
{
|
||||
return set.GetEnumerator();
|
||||
}
|
||||
|
||||
public void IntersectWith(IEnumerable<T> other)
|
||||
{
|
||||
set.IntersectWith(other);
|
||||
}
|
||||
|
||||
public bool IsProperSubsetOf(IEnumerable<T> other)
|
||||
{
|
||||
return set.IsProperSubsetOf(other);
|
||||
}
|
||||
|
||||
public bool IsProperSupersetOf(IEnumerable<T> other)
|
||||
{
|
||||
return set.IsProperSupersetOf(other);
|
||||
}
|
||||
|
||||
public bool IsSubsetOf(IEnumerable<T> other)
|
||||
{
|
||||
return set.IsSubsetOf(other);
|
||||
}
|
||||
|
||||
public bool IsSupersetOf(IEnumerable<T> other)
|
||||
{
|
||||
return set.IsSupersetOf(other);
|
||||
}
|
||||
|
||||
public bool Overlaps(IEnumerable<T> other)
|
||||
{
|
||||
return set.Overlaps(other);
|
||||
}
|
||||
|
||||
public bool Remove(T item)
|
||||
{
|
||||
if (item == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(item));
|
||||
}
|
||||
|
||||
return set.Remove(item);
|
||||
}
|
||||
|
||||
public bool SetEquals(IEnumerable<T> other)
|
||||
{
|
||||
return set.SetEquals(other);
|
||||
}
|
||||
|
||||
public void SymmetricExceptWith(IEnumerable<T> other)
|
||||
{
|
||||
set.SymmetricExceptWith(other);
|
||||
}
|
||||
|
||||
public void UnionWith(IEnumerable<T> other)
|
||||
{
|
||||
set.UnionWith(other);
|
||||
}
|
||||
|
||||
void ICollection<T>.Add(T item)
|
||||
{
|
||||
if (item == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(item));
|
||||
}
|
||||
|
||||
((ICollection<T>)set).Add(item);
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return ((IEnumerable)set).GetEnumerator();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: d87db61d4949f45af99577f40b0ea695
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,179 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public class NonNullableList<T> : IList<T>, IList
|
||||
{
|
||||
public NonNullableList()
|
||||
{
|
||||
list = new List<T>();
|
||||
}
|
||||
|
||||
public NonNullableList(int capacity)
|
||||
{
|
||||
list = new List<T>(capacity);
|
||||
}
|
||||
|
||||
public NonNullableList(IEnumerable<T> collection)
|
||||
{
|
||||
list = new List<T>(collection);
|
||||
}
|
||||
|
||||
private readonly List<T> list;
|
||||
|
||||
public T this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
return list[index];
|
||||
}
|
||||
|
||||
set
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(value));
|
||||
}
|
||||
|
||||
list[index] = value;
|
||||
}
|
||||
}
|
||||
|
||||
object IList.this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
return ((IList)list)[index];
|
||||
}
|
||||
set
|
||||
{
|
||||
((IList)list)[index] = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int Count => list.Count;
|
||||
|
||||
public bool IsSynchronized => ((ICollection)list).IsSynchronized;
|
||||
|
||||
public object SyncRoot => ((ICollection)list).SyncRoot;
|
||||
|
||||
public bool IsReadOnly => false;
|
||||
|
||||
public bool IsFixedSize => ((IList)list).IsFixedSize;
|
||||
|
||||
public void CopyTo(Array array, int index)
|
||||
{
|
||||
((ICollection)list).CopyTo(array, index);
|
||||
}
|
||||
|
||||
public void Add(T item)
|
||||
{
|
||||
if (item == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(item));
|
||||
}
|
||||
|
||||
list.Add(item);
|
||||
}
|
||||
|
||||
public int Add(object value)
|
||||
{
|
||||
return ((IList)list).Add(value);
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
list.Clear();
|
||||
}
|
||||
|
||||
public bool Contains(object value)
|
||||
{
|
||||
return ((IList)list).Contains(value);
|
||||
}
|
||||
|
||||
public int IndexOf(object value)
|
||||
{
|
||||
return ((IList)list).IndexOf(value);
|
||||
}
|
||||
|
||||
public void Insert(int index, object value)
|
||||
{
|
||||
((IList)list).Insert(index, value);
|
||||
}
|
||||
|
||||
public void Remove(object value)
|
||||
{
|
||||
((IList)list).Remove(value);
|
||||
}
|
||||
|
||||
public bool Contains(T item)
|
||||
{
|
||||
if (item == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(item));
|
||||
}
|
||||
|
||||
return list.Contains(item);
|
||||
}
|
||||
|
||||
public void CopyTo(T[] array, int arrayIndex)
|
||||
{
|
||||
list.CopyTo(array, arrayIndex);
|
||||
}
|
||||
|
||||
public IEnumerator<T> GetEnumerator()
|
||||
{
|
||||
return list.GetEnumerator();
|
||||
}
|
||||
|
||||
public int IndexOf(T item)
|
||||
{
|
||||
if (item == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(item));
|
||||
}
|
||||
|
||||
return list.IndexOf(item);
|
||||
}
|
||||
|
||||
public void Insert(int index, T item)
|
||||
{
|
||||
if (item == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(item));
|
||||
}
|
||||
|
||||
list.Insert(index, item);
|
||||
}
|
||||
|
||||
public bool Remove(T item)
|
||||
{
|
||||
if (item == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(item));
|
||||
}
|
||||
|
||||
return list.Remove(item);
|
||||
}
|
||||
|
||||
public void RemoveAt(int index)
|
||||
{
|
||||
list.RemoveAt(index);
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return list.GetEnumerator();
|
||||
}
|
||||
|
||||
public void AddRange(IEnumerable<T> collection)
|
||||
{
|
||||
foreach (var item in collection)
|
||||
{
|
||||
Add(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 43726dbe3dc9b43e7b7757fe847b033a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,99 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public class VariantCollection<TBase, TImplementation> : ICollection<TBase> where TImplementation : TBase
|
||||
{
|
||||
public VariantCollection(ICollection<TImplementation> implementation)
|
||||
{
|
||||
if (implementation == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(implementation));
|
||||
}
|
||||
|
||||
this.implementation = implementation;
|
||||
}
|
||||
|
||||
public ICollection<TImplementation> implementation { get; private set; }
|
||||
|
||||
public int Count => implementation.Count;
|
||||
|
||||
public bool IsReadOnly => implementation.IsReadOnly;
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
public IEnumerator<TBase> GetEnumerator()
|
||||
{
|
||||
foreach (var i in implementation)
|
||||
{
|
||||
yield return i;
|
||||
}
|
||||
}
|
||||
|
||||
public void Add(TBase item)
|
||||
{
|
||||
if (!(item is TImplementation))
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
implementation.Add((TImplementation)item);
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
implementation.Clear();
|
||||
}
|
||||
|
||||
public bool Contains(TBase item)
|
||||
{
|
||||
if (!(item is TImplementation))
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
return implementation.Contains((TImplementation)item);
|
||||
}
|
||||
|
||||
public bool Remove(TBase item)
|
||||
{
|
||||
if (!(item is TImplementation))
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
return implementation.Remove((TImplementation)item);
|
||||
}
|
||||
|
||||
public void CopyTo(TBase[] array, int arrayIndex)
|
||||
{
|
||||
if (array == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(array));
|
||||
}
|
||||
|
||||
if (arrayIndex < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(arrayIndex));
|
||||
}
|
||||
|
||||
if (array.Length - arrayIndex < Count)
|
||||
{
|
||||
throw new ArgumentException();
|
||||
}
|
||||
|
||||
var implementationArray = new TImplementation[Count];
|
||||
implementation.CopyTo(implementationArray, 0);
|
||||
|
||||
for (var i = 0; i < Count; i++)
|
||||
{
|
||||
array[i + arrayIndex] = implementationArray[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 151f0a13a53cb44ae83db5361508f233
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,37 @@
|
|||
namespace Unity.VisualScripting
|
||||
{
|
||||
public class VariantKeyedCollection<TBase, TImplementation, TKey> :
|
||||
VariantCollection<TBase, TImplementation>,
|
||||
IKeyedCollection<TKey, TBase>
|
||||
where TImplementation : TBase
|
||||
{
|
||||
public VariantKeyedCollection(IKeyedCollection<TKey, TImplementation> implementation) : base(implementation)
|
||||
{
|
||||
this.implementation = implementation;
|
||||
}
|
||||
|
||||
public TBase this[TKey key] => implementation[key];
|
||||
|
||||
public new IKeyedCollection<TKey, TImplementation> implementation { get; private set; }
|
||||
|
||||
public bool TryGetValue(TKey key, out TBase value)
|
||||
{
|
||||
TImplementation implementationValue;
|
||||
var result = implementation.TryGetValue(key, out implementationValue);
|
||||
value = implementationValue;
|
||||
return result;
|
||||
}
|
||||
|
||||
public bool Contains(TKey key)
|
||||
{
|
||||
return implementation.Contains(key);
|
||||
}
|
||||
|
||||
public bool Remove(TKey key)
|
||||
{
|
||||
return implementation.Remove(key);
|
||||
}
|
||||
|
||||
TBase IKeyedCollection<TKey, TBase>.this[int index] => implementation[index];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 9e147a4fe5cb14a9cb1eae8b8c321dc0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,143 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public class VariantList<TBase, TImplementation> : IList<TBase> where TImplementation : TBase
|
||||
{
|
||||
public VariantList(IList<TImplementation> implementation)
|
||||
{
|
||||
if (implementation == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(implementation));
|
||||
}
|
||||
|
||||
this.implementation = implementation;
|
||||
}
|
||||
|
||||
public TBase this[int index]
|
||||
{
|
||||
get
|
||||
{
|
||||
return implementation[index];
|
||||
}
|
||||
set
|
||||
{
|
||||
if (!(value is TImplementation))
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
implementation[index] = (TImplementation)value;
|
||||
}
|
||||
}
|
||||
|
||||
public IList<TImplementation> implementation { get; private set; }
|
||||
|
||||
public int Count => implementation.Count;
|
||||
|
||||
public bool IsReadOnly => implementation.IsReadOnly;
|
||||
|
||||
public void Add(TBase item)
|
||||
{
|
||||
if (!(item is TImplementation))
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
implementation.Add((TImplementation)item);
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
implementation.Clear();
|
||||
}
|
||||
|
||||
public bool Contains(TBase item)
|
||||
{
|
||||
if (!(item is TImplementation))
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
return implementation.Contains((TImplementation)item);
|
||||
}
|
||||
|
||||
public bool Remove(TBase item)
|
||||
{
|
||||
if (!(item is TImplementation))
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
return implementation.Remove((TImplementation)item);
|
||||
}
|
||||
|
||||
public void CopyTo(TBase[] array, int arrayIndex)
|
||||
{
|
||||
if (array == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(array));
|
||||
}
|
||||
|
||||
if (arrayIndex < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(arrayIndex));
|
||||
}
|
||||
|
||||
if (array.Length - arrayIndex < Count)
|
||||
{
|
||||
throw new ArgumentException();
|
||||
}
|
||||
|
||||
var implementationArray = new TImplementation[Count];
|
||||
implementation.CopyTo(implementationArray, 0);
|
||||
|
||||
for (var i = 0; i < Count; i++)
|
||||
{
|
||||
array[i + arrayIndex] = implementationArray[i];
|
||||
}
|
||||
}
|
||||
|
||||
public int IndexOf(TBase item)
|
||||
{
|
||||
if (!(item is TImplementation))
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
return implementation.IndexOf((TImplementation)item);
|
||||
}
|
||||
|
||||
public void Insert(int index, TBase item)
|
||||
{
|
||||
if (!(item is TImplementation))
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
implementation.Insert(index, (TImplementation)item);
|
||||
}
|
||||
|
||||
public void RemoveAt(int index)
|
||||
{
|
||||
implementation.RemoveAt(index);
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator<TBase> IEnumerable<TBase>.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
public NoAllocEnumerator<TBase> GetEnumerator()
|
||||
{
|
||||
return new NoAllocEnumerator<TBase>(this);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: b5ebd1fa4eb6941199648d59aaab0b3b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,40 @@
|
|||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
namespace Unity.VisualScripting
|
||||
{
|
||||
public class WatchedList<T> : Collection<T>, INotifyCollectionChanged<T>
|
||||
{
|
||||
public event Action<T> ItemAdded;
|
||||
|
||||
public event Action<T> ItemRemoved;
|
||||
|
||||
public event Action CollectionChanged;
|
||||
|
||||
protected override void InsertItem(int index, T item)
|
||||
{
|
||||
base.InsertItem(index, item);
|
||||
ItemAdded?.Invoke(item);
|
||||
CollectionChanged?.Invoke();
|
||||
}
|
||||
|
||||
protected override void RemoveItem(int index)
|
||||
{
|
||||
if (index < Count)
|
||||
{
|
||||
var item = this[index];
|
||||
base.RemoveItem(index);
|
||||
ItemRemoved?.Invoke(item);
|
||||
CollectionChanged?.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void ClearItems()
|
||||
{
|
||||
while (Count > 0)
|
||||
{
|
||||
RemoveItem(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 4444c1ac4c2c24720ad9edd95152c1b8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Loading…
Add table
Add a link
Reference in a new issue