Compare commits
221 Commits
dev-extens
...
0.7.1
Author | SHA1 | Date | |
---|---|---|---|
e40c98ae1b | |||
642a9563ba | |||
4a1fa48352 | |||
4dc0767e91 | |||
9e82c04898 | |||
0776eca49d | |||
af01fb2119 | |||
9044631fe7 | |||
3b22d4fce3 | |||
5393ff1451 | |||
e34a9cc868 | |||
440581261e | |||
b78e99c59c | |||
3db8f61e3b | |||
8b64165fb7 | |||
799b1e12da | |||
957270c41a | |||
bc51a45df8 | |||
9b091a0084 | |||
98e35fc6f6 | |||
d83f447e82 | |||
898885b116 | |||
fd05f6c1dd | |||
86da71f2cb | |||
ba2f1d4858 | |||
3687a70aec | |||
8da54093aa | |||
b057ea8074 | |||
e7bc9d0294 | |||
08de91b04d | |||
ea70fbb051 | |||
cee6a08240 | |||
f04b9cfb75 | |||
1dcbc03829 | |||
d89423caf5 | |||
c9b348dd4f | |||
636f45f03f | |||
7fce9591a9 | |||
f65e4f1900 | |||
a4d0e3867a | |||
83b9c27e94 | |||
864ea91be0 | |||
ea02fc22bd | |||
60cc763cd0 | |||
8955b69cdf | |||
a7aff4d625 | |||
22cb8f0cb4 | |||
db07ace927 | |||
094c3fe2a3 | |||
cc156e0d81 | |||
9833052849 | |||
a6a0ac3f9e | |||
82060a6403 | |||
02441eb328 | |||
2fe2a40e74 | |||
754e3be906 | |||
65c225e93b | |||
74ce265016 | |||
2eba0e490f | |||
82f769f798 | |||
a008760918 | |||
832facdf5b | |||
d5ba09cbea | |||
59b4f14fb3 | |||
4d13c06f27 | |||
de72fcf572 | |||
1470dbb5aa | |||
ce31f3e15f | |||
f6741d0acc | |||
910e3ce277 | |||
52adef8e9b | |||
3d7639b94e | |||
b306a9d3d1 | |||
0cc15f0c8e | |||
0959b5cc25 | |||
44c54cd837 | |||
6e553b9ebb | |||
88a46127d7 | |||
4310b67e7b | |||
7deff3c6be | |||
5f4d35b3b3 | |||
5b510fa5da | |||
17042b6664 | |||
3fb123ff30 | |||
ca928eb731 | |||
906c82972b | |||
cee74b9e31 | |||
25b4f3ccb7 | |||
d1b9b9607b | |||
6ccc86c28d | |||
3d75cd9a11 | |||
b30d35c937 | |||
a8231f7c86 | |||
ed60859406 | |||
0d0902735a | |||
5bed3cf05b | |||
5d520609b5 | |||
bf53298706 | |||
3d09ec8c94 | |||
bc083541aa | |||
5b04426cd3 | |||
8d606524fc | |||
5bab0ca648 | |||
fb31e833cb | |||
346040574a | |||
959d07b0a9 | |||
c41d41c881 | |||
f09e3d3545 | |||
12b3373aeb | |||
9480904db7 | |||
bee3401283 | |||
fe4280aa2e | |||
3e273d67ba | |||
fcec43f694 | |||
904581c520 | |||
b983e32d56 | |||
f2aea2bd40 | |||
cc8e1f7ce4 | |||
749e1395bc | |||
21af9582f8 | |||
26dd373e7b | |||
1bd35d2c51 | |||
d275f61602 | |||
f5f1a5de67 | |||
56153f5eed | |||
b4984c0b3a | |||
dad399facf | |||
b536871da7 | |||
bd028c1b72 | |||
fa9303c0a1 | |||
d030c48b4d | |||
beab3d7f8b | |||
0b2ea3ddbc | |||
b143fb49ce | |||
8f211568be | |||
6d276c99ac | |||
72a93721f9 | |||
a1fd420493 | |||
d72afaa75b | |||
2784544884 | |||
c39a02a1c2 | |||
4c397ab2f7 | |||
6b3a9c9f0a | |||
1c1560f17f | |||
0699bc5614 | |||
d86da00258 | |||
d1ad68debe | |||
b937285a74 | |||
69fe03475b | |||
e5956f2b34 | |||
fdb4ab55a3 | |||
e30df8bdbc | |||
251b7bc352 | |||
61b72107ae | |||
d6208f19fb | |||
93d9fdd4b8 | |||
8670482c04 | |||
d2b71e41c9 | |||
29a8ac2136 | |||
a9fc5130bb | |||
b51c7d2352 | |||
56fd0936bb | |||
2b3898655f | |||
1b30d3e62c | |||
bdbb1fcb07 | |||
659f2165ff | |||
a5439430fb | |||
0f683e403c | |||
cf6a7a795b | |||
f664708165 | |||
a7be55f2b0 | |||
398cec1fc5 | |||
a8b9ba0af4 | |||
f54564c567 | |||
a2c5850fcd | |||
f4411629e4 | |||
17d620ff0c | |||
5887b1267a | |||
400723d83b | |||
07babcb0ff | |||
f7bfe07660 | |||
3690adf5dd | |||
48349b598d | |||
d6e3d3ad00 | |||
c57c82bdd1 | |||
4bc921d47e | |||
8907dd19b0 | |||
2221658e7a | |||
916c55b4b2 | |||
3d8a4a64a9 | |||
6cb36a7064 | |||
1fc5ea8ac6 | |||
6fd8e44d10 | |||
ff19b45a9f | |||
f467832115 | |||
0a25b5260d | |||
c877437ab6 | |||
676d19f452 | |||
fd7c1e6635 | |||
c98536e8ab | |||
a013d59379 | |||
2e69035618 | |||
072703efe7 | |||
0c796c4d7a | |||
ee4b0c5483 | |||
ba7a458e7c | |||
06d9df304e | |||
578e10bbd7 | |||
c685e634d5 | |||
824f401b77 | |||
aafc326f95 | |||
88a6410439 | |||
d6e1b19d32 | |||
6fa459e5d3 | |||
bde6216295 | |||
e03dbef5ff | |||
e2c683567e | |||
89f391f040 | |||
92a3d5018f | |||
d510fec57b | |||
c5214dd477 |
@@ -1,6 +1,9 @@
|
||||
# Remove the line below if you want to inherit .editorconfig settings from higher directories
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
|
||||
# C# files
|
||||
[*.cs]
|
||||
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
|
||||
namespace Cryville.Common {
|
||||
/// <summary>
|
||||
|
@@ -13,7 +13,7 @@ namespace Cryville.Common {
|
||||
public static Binder CreateBinderOfType(Type type) {
|
||||
var l = type.GetCustomAttributes(typeof(BinderAttribute), true);
|
||||
if (l.Length > 0) {
|
||||
return (Binder)ReflectionHelper.InvokeEmptyConstructor(
|
||||
return (Binder)Activator.CreateInstance(
|
||||
((BinderAttribute)l[0]).BinderType
|
||||
);
|
||||
}
|
||||
|
@@ -1,65 +0,0 @@
|
||||
namespace Cryville.Common.Buffers {
|
||||
/// <summary>
|
||||
/// A resource pool that allows reusing instances of arrays of type <typeparamref name="T" />.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The item type of the arrays in the pool.</typeparam>
|
||||
public class ArrayPool<T> {
|
||||
private class Bucket : ObjectPool<T[]> {
|
||||
readonly int _size;
|
||||
public Bucket(int size, int capacity) : base(capacity) {
|
||||
_size = size;
|
||||
}
|
||||
protected override T[] Construct() {
|
||||
return new T[_size];
|
||||
}
|
||||
}
|
||||
readonly Bucket[] _buckets;
|
||||
/// <summary>
|
||||
/// Creates an instance of the <see cref="ArrayPool{T}" /> class with the default maximum list size and bucket capacity.
|
||||
/// </summary>
|
||||
public ArrayPool() : this(0x40000000, 256) { }
|
||||
/// <summary>
|
||||
/// Creates an instance of the <see cref="ArrayPool{T}" /> class.
|
||||
/// </summary>
|
||||
/// <param name="maxSize">The maximum size of the arrays in the pool.</param>
|
||||
/// <param name="capacityPerBucket">The capacity of each bucket. The pool groups arrays of similar sizes into buckets for faster access.</param>
|
||||
public ArrayPool(int maxSize, int capacityPerBucket) {
|
||||
if (maxSize < 16) maxSize = 16;
|
||||
int num = GetID(maxSize) + 1;
|
||||
_buckets = new Bucket[num];
|
||||
for (int i = 0; i < num; i++) {
|
||||
_buckets[i] = new Bucket(GetSize(i), capacityPerBucket);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Rents an array that is at least the specified size from the pool.
|
||||
/// </summary>
|
||||
/// <param name="size">The minimum size of the array.</param>
|
||||
/// <returns>An array of type <see cref="T" /> that is at least the specified size.</returns>
|
||||
public T[] Rent(int size) {
|
||||
int len2 = size;
|
||||
if (len2 < 16) len2 = 16;
|
||||
var arr = _buckets[GetID(len2)].Rent();
|
||||
return arr;
|
||||
}
|
||||
/// <summary>
|
||||
/// Returns a rented array to the pool.
|
||||
/// </summary>
|
||||
/// <param name="arr">The array to return.</param>
|
||||
public void Return(T[] arr) {
|
||||
int len2 = arr.Length;
|
||||
if (len2 < 16) len2 = 16;
|
||||
_buckets[GetID(len2)].Return(arr);
|
||||
}
|
||||
static int GetID(int size) {
|
||||
size -= 1;
|
||||
size >>= 4;
|
||||
int num = 0;
|
||||
for (; size != 0; size >>= 1) num++;
|
||||
return num;
|
||||
}
|
||||
static int GetSize(int id) {
|
||||
return 0x10 << id;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,90 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Cryville.Common.Buffers {
|
||||
/// <summary>
|
||||
/// A set of resource pools categorized by a category type.
|
||||
/// </summary>
|
||||
/// <typeparam name="TCategory">The category type.</typeparam>
|
||||
/// <typeparam name="TObject">The type of the objects in the pool.</typeparam>
|
||||
public abstract class CategorizedPool<TCategory, TObject> where TObject : class {
|
||||
/// <summary>
|
||||
/// The set of underlying pools.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>The <see cref="Rent(TCategory)" /> and <see cref="Return(TCategory, TObject)" /> method select an underlying pool directly from this set with the category as the key. When overridden, this set must be available since construction.</para>
|
||||
/// </remarks>
|
||||
protected abstract IReadOnlyDictionary<TCategory, ObjectPool<TObject>> Buckets { get; }
|
||||
/// <summary>
|
||||
/// The count of objects rented from the set of pools.
|
||||
/// </summary>
|
||||
public int RentedCount { get; private set; }
|
||||
/// <summary>
|
||||
/// Rents an object from the pool.
|
||||
/// </summary>
|
||||
/// <param name="category">The category.</param>
|
||||
/// <returns>The rented object.</returns>
|
||||
public TObject Rent(TCategory category) {
|
||||
var obj = Buckets[category].Rent();
|
||||
RentedCount++;
|
||||
return obj;
|
||||
}
|
||||
/// <summary>
|
||||
/// Returns a rented object to the pool.
|
||||
/// </summary>
|
||||
/// <param name="category">The category.</param>
|
||||
/// <param name="obj">The object to return.</param>
|
||||
public void Return(TCategory category, TObject obj) {
|
||||
Buckets[category].Return(obj);
|
||||
--RentedCount;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// A utility to access a categorized pool, representing a single unit that uses a shared categorized pool.
|
||||
/// </summary>
|
||||
/// <typeparam name="TCategory">The category type.</typeparam>
|
||||
/// <typeparam name="TObject">The type of the objects in the pool.</typeparam>
|
||||
public class CategorizedPoolAccessor<TCategory, TObject> where TObject : class {
|
||||
readonly CategorizedPool<TCategory, TObject> _pool;
|
||||
static readonly SimpleObjectPool<Dictionary<TObject, TCategory>> _dictPool
|
||||
= new SimpleObjectPool<Dictionary<TObject, TCategory>>(1024);
|
||||
Dictionary<TObject, TCategory> _rented;
|
||||
/// <summary>
|
||||
/// Creates an instance of the <see cref="CategorizedPoolAccessor{TCategory, TObject}" /> class.
|
||||
/// </summary>
|
||||
/// <param name="pool">The categorized pool.</param>
|
||||
public CategorizedPoolAccessor(CategorizedPool<TCategory, TObject> pool) {
|
||||
_pool = pool;
|
||||
}
|
||||
/// <summary>
|
||||
/// Rents an object from the pool.
|
||||
/// </summary>
|
||||
/// <param name="category">The category.</param>
|
||||
/// <returns>The rented object.</returns>
|
||||
public TObject Rent(TCategory category) {
|
||||
var obj = _pool.Rent(category);
|
||||
if (_rented == null) _rented = _dictPool.Rent();
|
||||
_rented.Add(obj, category);
|
||||
return obj;
|
||||
}
|
||||
/// <summary>
|
||||
/// Returns a rented object to the pool.
|
||||
/// </summary>
|
||||
/// <param name="obj">The object to return.</param>
|
||||
public void Return(TObject obj) {
|
||||
_pool.Return(_rented[obj], obj);
|
||||
_rented.Remove(obj);
|
||||
}
|
||||
/// <summary>
|
||||
/// Returns all objects rented by this accessor to the pool.
|
||||
/// </summary>
|
||||
public void ReturnAll() {
|
||||
if (_rented == null) return;
|
||||
foreach (var obj in _rented) {
|
||||
_pool.Return(obj.Value, obj.Key);
|
||||
}
|
||||
_rented.Clear();
|
||||
_dictPool.Return(_rented);
|
||||
_rented = null;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,71 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Cryville.Common.Buffers {
|
||||
/// <summary>
|
||||
/// A resource pool that allows reusing instances of lists of type <typeparamref name="T" />.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The item type of the lists in the pool.</typeparam>
|
||||
public class ListPool<T> {
|
||||
private class Bucket : ObjectPool<List<T>> {
|
||||
readonly int _size;
|
||||
public Bucket(int size, int capacity) : base(capacity) {
|
||||
_size = size;
|
||||
}
|
||||
protected override List<T> Construct() {
|
||||
return new List<T>(_size);
|
||||
}
|
||||
}
|
||||
readonly Bucket[] _buckets;
|
||||
/// <summary>
|
||||
/// Creates an instance of the <see cref="ListPool{T}" /> class with the default maximum list size and bucket capacity.
|
||||
/// </summary>
|
||||
public ListPool() : this(0x40000000, 256) { }
|
||||
/// <summary>
|
||||
/// Creates an instance of the <see cref="ListPool{T}" /> class.
|
||||
/// </summary>
|
||||
/// <param name="maxSize">The maximum size of the lists in the pool.</param>
|
||||
/// <param name="capacityPerBucket">The capacity of each bucket. The pool groups lists of similar sizes into buckets for faster access.</param>
|
||||
public ListPool(int maxSize, int capacityPerBucket) {
|
||||
if (maxSize < 16) maxSize = 16;
|
||||
int num = GetID(maxSize) + 1;
|
||||
_buckets = new Bucket[num];
|
||||
for (int i = 0; i < num; i++) {
|
||||
_buckets[i] = new Bucket(GetSize(i), capacityPerBucket);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Rents a list of the specified size from the pool. The size of the list must not be changed when it is rented.
|
||||
/// </summary>
|
||||
/// <param name="size">The size of the list.</param>
|
||||
/// <returns>A <see cref="List{T}" /> of the specified size.</returns>
|
||||
public List<T> Rent(int size) {
|
||||
int len2 = size;
|
||||
if (len2 < 16) len2 = 16;
|
||||
var list = _buckets[GetID(len2)].Rent();
|
||||
if (list.Count < size)
|
||||
for (int i = list.Count; i < size; i++) list.Add(default(T));
|
||||
else if (list.Count > size)
|
||||
list.RemoveRange(size, list.Count - size);
|
||||
return list;
|
||||
}
|
||||
/// <summary>
|
||||
/// Returns a rented list to the pool.
|
||||
/// </summary>
|
||||
/// <param name="list">The list to return.</param>
|
||||
public void Return(List<T> list) {
|
||||
int len2 = list.Capacity;
|
||||
if (len2 < 16) len2 = 16;
|
||||
_buckets[GetID(len2)].Return(list);
|
||||
}
|
||||
static int GetID(int size) {
|
||||
size -= 1;
|
||||
size >>= 4;
|
||||
int num = 0;
|
||||
for (; size != 0; size >>= 1) num++;
|
||||
return num;
|
||||
}
|
||||
static int GetSize(int id) {
|
||||
return 0x10 << id;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,52 +0,0 @@
|
||||
namespace Cryville.Common.Buffers {
|
||||
/// <summary>
|
||||
/// A resource pool that allows reusing instances of type <typeparamref name="T" />.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the objects in the pool.</typeparam>
|
||||
public abstract class ObjectPool<T> where T : class {
|
||||
int _index;
|
||||
readonly T[] _objs;
|
||||
/// <summary>
|
||||
/// Creates an instance of the <see cref="ObjectPool{T}" /> class.
|
||||
/// </summary>
|
||||
/// <param name="capacity">The capacity of the pool.</param>
|
||||
public ObjectPool(int capacity) {
|
||||
_objs = new T[capacity];
|
||||
}
|
||||
/// <summary>
|
||||
/// The count of objects rented from the pool.
|
||||
/// </summary>
|
||||
public int RentedCount { get { return _index; } }
|
||||
/// <summary>
|
||||
/// Rents a object from the pool.
|
||||
/// </summary>
|
||||
/// <returns>The rented object.</returns>
|
||||
public T Rent() {
|
||||
T obj = null;
|
||||
if (_index < _objs.Length) {
|
||||
obj = _objs[_index];
|
||||
_objs[_index++] = null;
|
||||
}
|
||||
if (obj == null) obj = Construct();
|
||||
else Reset(obj);
|
||||
return obj;
|
||||
}
|
||||
/// <summary>
|
||||
/// Returns a rented object to the pool.
|
||||
/// </summary>
|
||||
/// <param name="obj">The object to return.</param>
|
||||
public void Return(T obj) {
|
||||
if (_index > 0) _objs[--_index] = obj;
|
||||
}
|
||||
/// <summary>
|
||||
/// Constructs a new instance of type <typeparamref name="T" />.
|
||||
/// </summary>
|
||||
/// <returns>The new instance.</returns>
|
||||
protected abstract T Construct();
|
||||
/// <summary>
|
||||
/// Resets an object.
|
||||
/// </summary>
|
||||
/// <param name="obj">The object.</param>
|
||||
protected virtual void Reset(T obj) { }
|
||||
}
|
||||
}
|
@@ -1,16 +0,0 @@
|
||||
namespace Cryville.Common.Buffers {
|
||||
/// <summary>
|
||||
/// A resource pool that allows reusing instances of type <typeparamref name="T" />, which has a parameterless constructor.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the objects in the pool.</typeparam>
|
||||
public class SimpleObjectPool<T> : ObjectPool<T> where T : class, new() {
|
||||
/// <summary>
|
||||
/// Creates an instance of the <see cref="SimpleObjectPool{T}" /> class.
|
||||
/// </summary>
|
||||
/// <param name="capacity">The capacity of the pool.</param>
|
||||
public SimpleObjectPool(int capacity) : base(capacity) { }
|
||||
protected override T Construct() {
|
||||
return new T();
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b8cd439340f088d4eb83711a5bc6384d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,135 +0,0 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Cryville.Common.Buffers {
|
||||
/// <summary>
|
||||
/// An auto-resized <see cref="char" /> array as a variable-length string used as a target that is modified frequently.
|
||||
/// </summary>
|
||||
public class TargetString : IEnumerable<char> {
|
||||
public event Action OnUpdate;
|
||||
char[] _arr;
|
||||
bool _invalidated;
|
||||
/// <summary>
|
||||
/// Creates an instance of the <see cref="TargetString" /> class with a capacity of 16.
|
||||
/// </summary>
|
||||
public TargetString() : this(16) { }
|
||||
/// <summary>
|
||||
/// Creates an instance of the <see cref="TargetString" /> class.
|
||||
/// </summary>
|
||||
/// <param name="capacity">The initial capacity of the string.</param>
|
||||
/// <exception cref="ArgumentOutOfRangeException"><paramref name="capacity" /> is less than or equal to 0.</exception>
|
||||
public TargetString(int capacity) {
|
||||
if (capacity <= 0) throw new ArgumentOutOfRangeException("capacity");
|
||||
_arr = new char[capacity];
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets or sets one of the characters in the string.
|
||||
/// </summary>
|
||||
/// <param name="index">The zero-based index of the character.</param>
|
||||
/// <returns>The character at the given index.</returns>
|
||||
/// <exception cref="ArgumentOutOfRangeException"><paramref name="index" /> is less than 0 or not less than <see cref="Length" />.</exception>
|
||||
/// <remarks>
|
||||
/// <para>Set <see cref="Length" /> to a desired value before updating the characters.</para>
|
||||
/// <para>Call <see cref=" Validate" /> after all the characters are updated.</para>
|
||||
/// </remarks>
|
||||
public char this[int index] {
|
||||
get {
|
||||
if (index < 0 || index >= m_length)
|
||||
throw new ArgumentOutOfRangeException("index");
|
||||
return _arr[index];
|
||||
}
|
||||
set {
|
||||
if (index < 0 || index >= m_length)
|
||||
throw new ArgumentOutOfRangeException("index");
|
||||
if (_arr[index] == value) return;
|
||||
_arr[index] = value;
|
||||
_invalidated = true;
|
||||
}
|
||||
}
|
||||
int m_length;
|
||||
/// <summary>
|
||||
/// The length of the string.
|
||||
/// </summary>
|
||||
/// <exception cref="ArgumentOutOfRangeException">The value specified for a set operation is less than 0.</exception>
|
||||
public int Length {
|
||||
get {
|
||||
return m_length;
|
||||
}
|
||||
set {
|
||||
if (Length < 0) throw new ArgumentOutOfRangeException("length");
|
||||
if (m_length == value) return;
|
||||
if (_arr.Length < value) {
|
||||
var len = _arr.Length;
|
||||
while (len < value) len *= 2;
|
||||
var arr2 = new char[len];
|
||||
Array.Copy(_arr, arr2, m_length);
|
||||
_arr = arr2;
|
||||
}
|
||||
m_length = value;
|
||||
_invalidated = true;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Validates the string.
|
||||
/// </summary>
|
||||
public void Validate() {
|
||||
if (!_invalidated) return;
|
||||
_invalidated = false;
|
||||
var ev = OnUpdate;
|
||||
if (ev != null) ev.Invoke();
|
||||
}
|
||||
internal char[] TrustedAsArray() { return _arr; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns an enumerator that iterates through the <see cref="TargetString" />.
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="Enumerator" /> for the <see cref="TargetString" />.</returns>
|
||||
public Enumerator GetEnumerator() {
|
||||
return new Enumerator(this);
|
||||
}
|
||||
IEnumerator<char> IEnumerable<char>.GetEnumerator() {
|
||||
return new Enumerator(this);
|
||||
}
|
||||
IEnumerator IEnumerable.GetEnumerator() {
|
||||
return new Enumerator(this);
|
||||
}
|
||||
|
||||
public struct Enumerator : IEnumerator<char> {
|
||||
readonly TargetString _self;
|
||||
int _index;
|
||||
internal Enumerator(TargetString self) {
|
||||
_self = self;
|
||||
_index = -1;
|
||||
}
|
||||
|
||||
public char Current {
|
||||
get {
|
||||
if (_index < 0)
|
||||
throw new InvalidOperationException(_index == -1 ? "Enum not started" : "Enum ended");
|
||||
return _self[_index];
|
||||
}
|
||||
}
|
||||
|
||||
object IEnumerator.Current { get { return Current; } }
|
||||
|
||||
public void Dispose() {
|
||||
_index = -2;
|
||||
}
|
||||
|
||||
public bool MoveNext() {
|
||||
if (_index == -2) return false;
|
||||
_index++;
|
||||
if (_index >= _self.Length) {
|
||||
_index = -2;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Reset() {
|
||||
_index = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f0fc34ac257793d4883a9cfcdb6941b9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,8 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Cryville.Common.Collections.Generic {
|
||||
public interface IPairList<TKey, TValue> : IList<KeyValuePair<TKey, TValue>> {
|
||||
void Add(TKey key, TValue value);
|
||||
void Insert(int index, TKey key, TValue value);
|
||||
}
|
||||
}
|
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 73fb17b484b343242bcce27c15ed7d44
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,46 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Cryville.Common.Collections.Generic {
|
||||
[DebuggerDisplay("Count = {Count}"), DebuggerTypeProxy(typeof(PairCollectionDebugView<,>))]
|
||||
public struct PairCollection<TKey, TValue> : IDisposable {
|
||||
public void Dispose() { }
|
||||
readonly IPairList<TKey, TValue> _pairList;
|
||||
readonly IDictionary<TKey, TValue> _dictionary;
|
||||
public PairCollection(object collection) : this() {
|
||||
var type = collection.GetType();
|
||||
if (typeof(IPairList<TKey, TValue>).IsAssignableFrom(type)) _pairList = (IPairList<TKey, TValue>)collection;
|
||||
else if (typeof(IDictionary<TKey, TValue>).IsAssignableFrom(type)) _dictionary = (IDictionary<TKey, TValue>)collection;
|
||||
else throw new ArgumentException("Parameter is not a pair collection");
|
||||
}
|
||||
public int Count {
|
||||
get {
|
||||
if (_pairList != null) return _pairList.Count;
|
||||
else return _dictionary.Count;
|
||||
}
|
||||
}
|
||||
public void Add(TKey key, TValue value) {
|
||||
if (_pairList != null) _pairList.Add(key, value);
|
||||
else _dictionary.Add(key, value);
|
||||
}
|
||||
public void CopyTo(KeyValuePair<TKey, TValue>[] array, int index) {
|
||||
if (_pairList != null) _pairList.CopyTo(array, index);
|
||||
else _dictionary.CopyTo(array, index);
|
||||
}
|
||||
}
|
||||
internal class PairCollectionDebugView<TKey, TValue> {
|
||||
readonly PairCollection<TKey, TValue> _self;
|
||||
public PairCollectionDebugView(PairCollection<TKey, TValue> self) {
|
||||
_self = self;
|
||||
}
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
|
||||
public KeyValuePair<TKey, TValue>[] Items {
|
||||
get {
|
||||
KeyValuePair<TKey, TValue>[] array = new KeyValuePair<TKey, TValue>[_self.Count];
|
||||
_self.CopyTo(array, 0);
|
||||
return array;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2517e8f040bd36f46948e5fafaf5335c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,48 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Cryville.Common.Collections.Generic {
|
||||
[DebuggerDisplay("Count = {Count}"), DebuggerTypeProxy(typeof(PairListDebugView<,>))]
|
||||
public class PairList<TKey, TValue> : List<KeyValuePair<TKey, TValue>>, IPairList<TKey, TValue>, IPairList {
|
||||
public void Add(TKey key, TValue value) {
|
||||
Add(new KeyValuePair<TKey, TValue>(key, value));
|
||||
}
|
||||
|
||||
public void Add(object key, object value) {
|
||||
try {
|
||||
Add((TKey)key, (TValue)value);
|
||||
}
|
||||
catch (InvalidCastException) {
|
||||
throw new ArgumentException("Wrong key type or value type");
|
||||
}
|
||||
}
|
||||
|
||||
public void Insert(int index, TKey key, TValue value) {
|
||||
Insert(index, new KeyValuePair<TKey, TValue>(key, value));
|
||||
}
|
||||
|
||||
public void Insert(int index, object key, object value) {
|
||||
try {
|
||||
Insert(index, (TKey)key, (TValue)value);
|
||||
}
|
||||
catch (InvalidCastException) {
|
||||
throw new ArgumentException("Wrong key type or value type");
|
||||
}
|
||||
}
|
||||
}
|
||||
internal class PairListDebugView<TKey, TValue> {
|
||||
readonly PairList<TKey, TValue> _self;
|
||||
public PairListDebugView(PairList<TKey, TValue> self) {
|
||||
_self = self;
|
||||
}
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
|
||||
public KeyValuePair<TKey, TValue>[] Items {
|
||||
get {
|
||||
KeyValuePair<TKey, TValue>[] array = new KeyValuePair<TKey, TValue>[_self.Count];
|
||||
_self.CopyTo(array, 0);
|
||||
return array;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d9ed5ea8b7b1a934287e7ec5971166c0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,8 +0,0 @@
|
||||
using System.Collections;
|
||||
|
||||
namespace Cryville.Common.Collections {
|
||||
public interface IPairList : IList {
|
||||
void Add(object key, object value);
|
||||
void Insert(int index, object key, object value);
|
||||
}
|
||||
}
|
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 046617672d437de4ab7e644a55defd3b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,47 +0,0 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Cryville.Common.Collections {
|
||||
[DebuggerDisplay("Count = {Count}"), DebuggerTypeProxy(typeof(PairCollectionDebugView))]
|
||||
public struct PairCollection : IDisposable {
|
||||
public void Dispose() { }
|
||||
readonly IPairList _pairList;
|
||||
readonly IDictionary _dictionary;
|
||||
public PairCollection(object collection) : this() {
|
||||
var type = collection.GetType();
|
||||
if (typeof(IPairList).IsAssignableFrom(type)) _pairList = (IPairList)collection;
|
||||
else if (typeof(IDictionary).IsAssignableFrom(type)) _dictionary = (IDictionary)collection;
|
||||
else throw new ArgumentException("Parameter is not a pair collection");
|
||||
}
|
||||
public int Count {
|
||||
get {
|
||||
if (_pairList != null) return _pairList.Count;
|
||||
else return _dictionary.Count;
|
||||
}
|
||||
}
|
||||
public void Add(object key, object value) {
|
||||
if (_pairList != null) _pairList.Add(key, value);
|
||||
else _dictionary.Add(key, value);
|
||||
}
|
||||
public void CopyTo(KeyValuePair<object, object>[] array, int index) {
|
||||
if (_pairList != null) _pairList.CopyTo(array, index);
|
||||
else _dictionary.CopyTo(array, index);
|
||||
}
|
||||
}
|
||||
internal class PairCollectionDebugView {
|
||||
readonly PairCollection _self;
|
||||
public PairCollectionDebugView(PairCollection self) {
|
||||
_self = self;
|
||||
}
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
|
||||
public KeyValuePair<object, object>[] Items {
|
||||
get {
|
||||
KeyValuePair<object, object>[] array = new KeyValuePair<object, object>[_self.Count];
|
||||
_self.CopyTo(array, 0);
|
||||
return array;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1f87dfb8f6a1f5640b6deae741cd715c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,29 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Cryville.Common.Collections {
|
||||
[DebuggerDisplay("Count = {Count}"), DebuggerTypeProxy(typeof(PairListDebugView))]
|
||||
public class PairList : List<KeyValuePair<object, object>>, IPairList {
|
||||
public void Add(object key, object value) {
|
||||
Add(new KeyValuePair<object, object>(key, value));
|
||||
}
|
||||
|
||||
public void Insert(int index, object key, object value) {
|
||||
Insert(index, new KeyValuePair<object, object>(key, value));
|
||||
}
|
||||
}
|
||||
internal class PairListDebugView {
|
||||
readonly PairList _self;
|
||||
public PairListDebugView(PairList self) {
|
||||
_self = self;
|
||||
}
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
|
||||
public KeyValuePair<object, object>[] Items {
|
||||
get {
|
||||
KeyValuePair<object, object>[] array = new KeyValuePair<object, object>[_self.Count];
|
||||
_self.CopyTo(array, 0);
|
||||
return array;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 57fc9f037c1fda5449e2a365a835c82c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
|
||||
namespace Cryville.Common.ComponentModel {
|
||||
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
|
||||
|
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
|
||||
namespace Cryville.Common.ComponentModel {
|
||||
[AttributeUsage(AttributeTargets.Property, Inherited = false)]
|
||||
|
@@ -1,14 +1,14 @@
|
||||
using System;
|
||||
using System;
|
||||
|
||||
namespace Cryville.Common.ComponentModel {
|
||||
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
|
||||
public class RangeAttribute : Attribute {
|
||||
public RangeAttribute(float min, float max) {
|
||||
public RangeAttribute(double min, double max) {
|
||||
Min = min;
|
||||
Max = max;
|
||||
}
|
||||
|
||||
public float Min { get; set; }
|
||||
public float Max { get; set; }
|
||||
public double Min { get; set; }
|
||||
public double Max { get; set; }
|
||||
}
|
||||
}
|
||||
|
@@ -1,11 +1,11 @@
|
||||
using System;
|
||||
using System;
|
||||
|
||||
namespace Cryville.Common.ComponentModel {
|
||||
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
|
||||
public class StepAttribute : Attribute {
|
||||
public StepAttribute(float step) {
|
||||
public StepAttribute(double step) {
|
||||
Step = step;
|
||||
}
|
||||
public float Step { get; set; }
|
||||
public double Step { get; set; }
|
||||
}
|
||||
}
|
||||
|
26
Assets/Cryville/Common/Coroutine.cs
Normal file
26
Assets/Cryville/Common/Coroutine.cs
Normal file
@@ -0,0 +1,26 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Cryville.Common {
|
||||
public class Coroutine {
|
||||
readonly IEnumerator<float> _enumerator;
|
||||
readonly Stopwatch _stopwatch = new Stopwatch();
|
||||
public float Progress { get; private set; }
|
||||
public Coroutine(IEnumerator<float> enumerator) {
|
||||
_enumerator = enumerator;
|
||||
}
|
||||
public bool TickOnce() {
|
||||
if (!_enumerator.MoveNext()) return false;
|
||||
Progress = _enumerator.Current;
|
||||
return true;
|
||||
}
|
||||
public bool Tick(double minTime) {
|
||||
_stopwatch.Restart();
|
||||
while (_stopwatch.Elapsed.TotalSeconds < minTime) {
|
||||
if (!_enumerator.MoveNext()) return false;
|
||||
Progress = _enumerator.Current;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2745c44c3cc32be4ab3a43888c14b9a1
|
||||
guid: 387adc7d494be0147b7cb930bc2e726b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
|
||||
namespace Cryville.Common {
|
||||
public class FileStringAttribute : Attribute {
|
||||
|
@@ -1,4 +1,4 @@
|
||||
using Cryville.Common.IO;
|
||||
using Cryville.Common.IO;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
@@ -1,4 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
using Cryville.Common.Culture;
|
||||
using Cryville.Common.Culture;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@@ -6,295 +6,295 @@ using System.Linq;
|
||||
namespace Cryville.Common.Font {
|
||||
public abstract class FontMatcher {
|
||||
protected FontManager Manager { get; private set; }
|
||||
public FontMatcher(FontManager manafer) { Manager = manafer; }
|
||||
public FontMatcher(FontManager manager) { Manager = manager; }
|
||||
public abstract IEnumerable<Typeface> MatchScript(string script = null, bool distinctFamily = false);
|
||||
}
|
||||
public class FallbackListFontMatcher : FontMatcher {
|
||||
public Dictionary<string, List<string>> MapScriptToTypefaces = new Dictionary<string, List<string>>();
|
||||
public void LoadDefaultWindowsFallbackList() {
|
||||
if (Environment.OSVersion.Platform != PlatformID.Win32NT) return;
|
||||
MapScriptToTypefaces.Clear();
|
||||
ScriptUtils.FillKeysWithScripts(MapScriptToTypefaces, () => new List<string>());
|
||||
public static Dictionary<string, List<string>> GetDefaultWindowsFallbackMap() {
|
||||
var map = new Dictionary<string, List<string>>();
|
||||
ScriptUtils.FillKeysWithScripts(map, () => new List<string>());
|
||||
// Reference: https://github.com/chromium/chromium/blob/main/third_party/blink/renderer/platform/fonts/win/font_fallback_win.cc
|
||||
MapScriptToTypefaces["zyyy"].Insert(0, "SimSun"); // Custom
|
||||
MapScriptToTypefaces["zyyy"].Insert(0, "SimHei"); // Custom
|
||||
MapScriptToTypefaces["zyyy"].Insert(0, "Microsoft YaHei"); // Custom
|
||||
MapScriptToTypefaces["zyyy"].Insert(0, "Arial");
|
||||
MapScriptToTypefaces["zyyy"].Insert(0, "Times New Roman");
|
||||
MapScriptToTypefaces["zyyy"].Insert(0, "Segoe UI"); // Custom
|
||||
MapScriptToTypefaces["arab"].Insert(0, "Tahoma");
|
||||
MapScriptToTypefaces["cyrl"].Insert(0, "Times New Roman");
|
||||
MapScriptToTypefaces["grek"].Insert(0, "Times New Roman");
|
||||
MapScriptToTypefaces["hebr"].Insert(0, "David");
|
||||
MapScriptToTypefaces["jpan"].Insert(0, "MS PGothic");
|
||||
MapScriptToTypefaces["latn"].Insert(0, "Times New Roman");
|
||||
MapScriptToTypefaces["hans"].Insert(0, "SimSun");
|
||||
MapScriptToTypefaces["hans"].Insert(0, "SimHei"); // Custom
|
||||
MapScriptToTypefaces["thai"].Insert(0, "Tahoma");
|
||||
MapScriptToTypefaces["hans"].Insert(0, "PMingLiU");
|
||||
map["zyyy"].Insert(0, "SimSun"); // Custom
|
||||
map["zyyy"].Insert(0, "SimHei"); // Custom
|
||||
map["zyyy"].Insert(0, "Microsoft YaHei"); // Custom
|
||||
map["zyyy"].Insert(0, "Arial");
|
||||
map["zyyy"].Insert(0, "Times New Roman");
|
||||
map["zyyy"].Insert(0, "Segoe UI"); // Custom
|
||||
map["arab"].Insert(0, "Tahoma");
|
||||
map["cyrl"].Insert(0, "Times New Roman");
|
||||
map["grek"].Insert(0, "Times New Roman");
|
||||
map["hebr"].Insert(0, "David");
|
||||
map["jpan"].Insert(0, "MS PGothic");
|
||||
map["latn"].Insert(0, "Times New Roman");
|
||||
map["hans"].Insert(0, "SimSun");
|
||||
map["hans"].Insert(0, "SimHei"); // Custom
|
||||
map["thai"].Insert(0, "Tahoma");
|
||||
map["hans"].Insert(0, "PMingLiU");
|
||||
// Reference: https://learn.microsoft.com/en-us/globalization/input/font-support
|
||||
var ver = Environment.OSVersion.Version;
|
||||
if (ver >= new Version(5, 0)) { // Windows 2000
|
||||
MapScriptToTypefaces["armn"].Insert(0, "Sylfaen");
|
||||
MapScriptToTypefaces["deva"].Insert(0, "Mangal");
|
||||
MapScriptToTypefaces["geor"].Insert(0, "Sylfaen");
|
||||
MapScriptToTypefaces["taml"].Insert(0, "Latha");
|
||||
map["armn"].Insert(0, "Sylfaen");
|
||||
map["deva"].Insert(0, "Mangal");
|
||||
map["geor"].Insert(0, "Sylfaen");
|
||||
map["taml"].Insert(0, "Latha");
|
||||
}
|
||||
if (ver >= new Version(5, 1)) { // Windows XP
|
||||
MapScriptToTypefaces["gujr"].Insert(0, "Shruti");
|
||||
MapScriptToTypefaces["guru"].Insert(0, "Raavi");
|
||||
MapScriptToTypefaces["knda"].Insert(0, "Tunga");
|
||||
MapScriptToTypefaces["syrc"].Insert(0, "Estrangelo Edessa");
|
||||
MapScriptToTypefaces["telu"].Insert(0, "Gautami");
|
||||
MapScriptToTypefaces["thaa"].Insert(0, "MV Boli");
|
||||
map["gujr"].Insert(0, "Shruti");
|
||||
map["guru"].Insert(0, "Raavi");
|
||||
map["knda"].Insert(0, "Tunga");
|
||||
map["syrc"].Insert(0, "Estrangelo Edessa");
|
||||
map["telu"].Insert(0, "Gautami");
|
||||
map["thaa"].Insert(0, "MV Boli");
|
||||
// SP2
|
||||
MapScriptToTypefaces["beng"].Insert(0, "Vrinda");
|
||||
MapScriptToTypefaces["mlym"].Insert(0, "Kartika");
|
||||
map["beng"].Insert(0, "Vrinda");
|
||||
map["mlym"].Insert(0, "Kartika");
|
||||
}
|
||||
if (ver >= new Version(6, 0)) { // Windows Vista
|
||||
MapScriptToTypefaces["cans"].Insert(0, "Euphemia");
|
||||
MapScriptToTypefaces["cher"].Insert(0, "Plantagenet");
|
||||
MapScriptToTypefaces["ethi"].Insert(0, "Nyala");
|
||||
MapScriptToTypefaces["khmr"].Insert(0, "DaunPenh MoolBoran");
|
||||
MapScriptToTypefaces["laoo"].Insert(0, "DokChampa");
|
||||
MapScriptToTypefaces["mong"].Insert(0, "Mongolian Baiti");
|
||||
MapScriptToTypefaces["orya"].Insert(0, "Kalinga");
|
||||
MapScriptToTypefaces["sinh"].Insert(0, "Iskoola Pota");
|
||||
MapScriptToTypefaces["tibt"].Insert(0, "Microsoft Himalaya");
|
||||
MapScriptToTypefaces["yiii"].Insert(0, "Microsoft Yi Baiti");
|
||||
MapScriptToTypefaces["arab"].Insert(0, "Segoe UI");
|
||||
MapScriptToTypefaces["cyrl"].Insert(0, "Segoe UI");
|
||||
MapScriptToTypefaces["grek"].Insert(0, "Segoe UI");
|
||||
MapScriptToTypefaces["latn"].Insert(0, "Segoe UI");
|
||||
MapScriptToTypefaces["hans"].Add("SimSun-ExtB");
|
||||
MapScriptToTypefaces["hant"].Add("MingLiU-ExtB");
|
||||
MapScriptToTypefaces["hant"].Add("MingLiU_HKSCS-ExtB");
|
||||
MapScriptToTypefaces["arab"].Add("Microsoft Uighur");
|
||||
MapScriptToTypefaces["zmth"].Insert(0, "Cambria Math");
|
||||
map["cans"].Insert(0, "Euphemia");
|
||||
map["cher"].Insert(0, "Plantagenet");
|
||||
map["ethi"].Insert(0, "Nyala");
|
||||
map["khmr"].Insert(0, "DaunPenh MoolBoran");
|
||||
map["laoo"].Insert(0, "DokChampa");
|
||||
map["mong"].Insert(0, "Mongolian Baiti");
|
||||
map["orya"].Insert(0, "Kalinga");
|
||||
map["sinh"].Insert(0, "Iskoola Pota");
|
||||
map["tibt"].Insert(0, "Microsoft Himalaya");
|
||||
map["yiii"].Insert(0, "Microsoft Yi Baiti");
|
||||
map["arab"].Insert(0, "Segoe UI");
|
||||
map["cyrl"].Insert(0, "Segoe UI");
|
||||
map["grek"].Insert(0, "Segoe UI");
|
||||
map["latn"].Insert(0, "Segoe UI");
|
||||
map["hans"].Add("SimSun-ExtB");
|
||||
map["hant"].Add("MingLiU-ExtB");
|
||||
map["hant"].Add("MingLiU_HKSCS-ExtB");
|
||||
map["arab"].Add("Microsoft Uighur");
|
||||
map["zmth"].Insert(0, "Cambria Math");
|
||||
// Reference: https://en.wikipedia.org/wiki/List_of_CJK_fonts
|
||||
MapScriptToTypefaces["jpan"].Insert(0, "Meiryo");
|
||||
MapScriptToTypefaces["hans"].Insert(0, "Microsoft YaHei");
|
||||
map["jpan"].Insert(0, "Meiryo");
|
||||
map["hans"].Insert(0, "Microsoft YaHei");
|
||||
}
|
||||
if (ver >= new Version(6, 1)) { // Windows 7
|
||||
MapScriptToTypefaces["brai"].Insert(0, "Segoe UI Symbol");
|
||||
MapScriptToTypefaces["dsrt"].Insert(0, "Segoe UI Symbol");
|
||||
MapScriptToTypefaces["talu"].Insert(0, "Microsoft New Tai Lue");
|
||||
MapScriptToTypefaces["ogam"].Insert(0, "Segoe UI Symbol");
|
||||
MapScriptToTypefaces["osma"].Insert(0, "Ebrima");
|
||||
MapScriptToTypefaces["phag"].Insert(0, "Microsoft PhagsPa");
|
||||
MapScriptToTypefaces["runr"].Insert(0, "Segoe UI Symbol");
|
||||
MapScriptToTypefaces["zsym"].Insert(0, "Segoe UI Symbol");
|
||||
MapScriptToTypefaces["tale"].Insert(0, "Microsoft Tai Le");
|
||||
MapScriptToTypefaces["tfng"].Insert(0, "Ebrima");
|
||||
MapScriptToTypefaces["vaii"].Insert(0, "Ebrima");
|
||||
map["brai"].Insert(0, "Segoe UI Symbol");
|
||||
map["dsrt"].Insert(0, "Segoe UI Symbol");
|
||||
map["talu"].Insert(0, "Microsoft New Tai Lue");
|
||||
map["ogam"].Insert(0, "Segoe UI Symbol");
|
||||
map["osma"].Insert(0, "Ebrima");
|
||||
map["phag"].Insert(0, "Microsoft PhagsPa");
|
||||
map["runr"].Insert(0, "Segoe UI Symbol");
|
||||
map["zsym"].Insert(0, "Segoe UI Symbol");
|
||||
map["tale"].Insert(0, "Microsoft Tai Le");
|
||||
map["tfng"].Insert(0, "Ebrima");
|
||||
map["vaii"].Insert(0, "Ebrima");
|
||||
}
|
||||
if (ver >= new Version(6, 2)) { // Windows 8
|
||||
MapScriptToTypefaces["glag"].Insert(0, "Segoe UI Symbol");
|
||||
MapScriptToTypefaces["goth"].Insert(0, "Segoe UI Symbol");
|
||||
MapScriptToTypefaces["hang"].Add("Malgun Gothic");
|
||||
MapScriptToTypefaces["ital"].Insert(0, "Segoe UI Symbol");
|
||||
MapScriptToTypefaces["lisu"].Insert(0, "Segoe UI");
|
||||
MapScriptToTypefaces["mymr"].Insert(0, "Myanmar Text");
|
||||
MapScriptToTypefaces["nkoo"].Insert(0, "Ebrima");
|
||||
MapScriptToTypefaces["orkh"].Insert(0, "Segoe UI Symbol");
|
||||
MapScriptToTypefaces["ethi"].Insert(0, "Ebrima");
|
||||
MapScriptToTypefaces["cans"].Insert(0, "Gadugi");
|
||||
MapScriptToTypefaces["hant"].Insert(0, "Microsoft JhengHei UI");
|
||||
MapScriptToTypefaces["hans"].Insert(0, "Microsoft YaHei UI");
|
||||
MapScriptToTypefaces["beng"].Insert(0, "Nirmala UI");
|
||||
MapScriptToTypefaces["deva"].Insert(0, "Nirmala UI");
|
||||
MapScriptToTypefaces["gujr"].Insert(0, "Nirmala UI");
|
||||
MapScriptToTypefaces["guru"].Insert(0, "Nirmala UI"); // NOT DOCUMENTED, UNVERIFIED
|
||||
MapScriptToTypefaces["knda"].Insert(0, "Nirmala UI"); // NOT DOCUMENTED, UNVERIFIED
|
||||
MapScriptToTypefaces["mlym"].Insert(0, "Nirmala UI");
|
||||
MapScriptToTypefaces["orya"].Insert(0, "Nirmala UI");
|
||||
MapScriptToTypefaces["sinh"].Insert(0, "Nirmala UI"); // NOT DOCUMENTED, UNVERIFIED
|
||||
MapScriptToTypefaces["taml"].Insert(0, "Nirmala UI"); // NOT DOCUMENTED, UNVERIFIED
|
||||
MapScriptToTypefaces["telu"].Insert(0, "Nirmala UI");
|
||||
MapScriptToTypefaces["armn"].Insert(0, "Segoe UI");
|
||||
MapScriptToTypefaces["geor"].Insert(0, "Segoe UI");
|
||||
MapScriptToTypefaces["hebr"].Insert(0, "Segoe UI");
|
||||
map["glag"].Insert(0, "Segoe UI Symbol");
|
||||
map["goth"].Insert(0, "Segoe UI Symbol");
|
||||
map["hang"].Add("Malgun Gothic");
|
||||
map["ital"].Insert(0, "Segoe UI Symbol");
|
||||
map["lisu"].Insert(0, "Segoe UI");
|
||||
map["mymr"].Insert(0, "Myanmar Text");
|
||||
map["nkoo"].Insert(0, "Ebrima");
|
||||
map["orkh"].Insert(0, "Segoe UI Symbol");
|
||||
map["ethi"].Insert(0, "Ebrima");
|
||||
map["cans"].Insert(0, "Gadugi");
|
||||
map["hant"].Insert(0, "Microsoft JhengHei UI");
|
||||
map["hans"].Insert(0, "Microsoft YaHei UI");
|
||||
map["beng"].Insert(0, "Nirmala UI");
|
||||
map["deva"].Insert(0, "Nirmala UI");
|
||||
map["gujr"].Insert(0, "Nirmala UI");
|
||||
map["guru"].Insert(0, "Nirmala UI"); // NOT DOCUMENTED, UNVERIFIED
|
||||
map["knda"].Insert(0, "Nirmala UI"); // NOT DOCUMENTED, UNVERIFIED
|
||||
map["mlym"].Insert(0, "Nirmala UI");
|
||||
map["orya"].Insert(0, "Nirmala UI");
|
||||
map["sinh"].Insert(0, "Nirmala UI"); // NOT DOCUMENTED, UNVERIFIED
|
||||
map["taml"].Insert(0, "Nirmala UI"); // NOT DOCUMENTED, UNVERIFIED
|
||||
map["telu"].Insert(0, "Nirmala UI");
|
||||
map["armn"].Insert(0, "Segoe UI");
|
||||
map["geor"].Insert(0, "Segoe UI");
|
||||
map["hebr"].Insert(0, "Segoe UI");
|
||||
}
|
||||
if (ver >= new Version(6, 3)) { // Windows 8.1
|
||||
MapScriptToTypefaces["bugi"].Insert(0, "Leelawadee UI");
|
||||
MapScriptToTypefaces["copt"].Insert(0, "Segoe UI Symbol");
|
||||
MapScriptToTypefaces["java"].Insert(0, "Javanese Text");
|
||||
MapScriptToTypefaces["merc"].Insert(0, "Segoe UI Symbol");
|
||||
MapScriptToTypefaces["olck"].Insert(0, "Nirmala UI");
|
||||
MapScriptToTypefaces["sora"].Insert(0, "Nirmala UI");
|
||||
MapScriptToTypefaces["khmr"].Insert(0, "Leelawadee UI");
|
||||
MapScriptToTypefaces["laoo"].Insert(0, "Leelawadee UI");
|
||||
MapScriptToTypefaces["thai"].Insert(0, "Leelawadee UI");
|
||||
MapScriptToTypefaces["zsye"].Insert(0, "Segoe UI Emoji");
|
||||
map["bugi"].Insert(0, "Leelawadee UI");
|
||||
map["copt"].Insert(0, "Segoe UI Symbol");
|
||||
map["java"].Insert(0, "Javanese Text");
|
||||
map["merc"].Insert(0, "Segoe UI Symbol");
|
||||
map["olck"].Insert(0, "Nirmala UI");
|
||||
map["sora"].Insert(0, "Nirmala UI");
|
||||
map["khmr"].Insert(0, "Leelawadee UI");
|
||||
map["laoo"].Insert(0, "Leelawadee UI");
|
||||
map["thai"].Insert(0, "Leelawadee UI");
|
||||
map["zsye"].Insert(0, "Segoe UI Emoji");
|
||||
}
|
||||
if (ver >= new Version(10, 0)) { // Windows 10
|
||||
MapScriptToTypefaces["brah"].Insert(0, "Segoe UI Historic");
|
||||
MapScriptToTypefaces["cari"].Insert(0, "Segoe UI Historic");
|
||||
MapScriptToTypefaces["cprt"].Insert(0, "Segoe UI Historic");
|
||||
MapScriptToTypefaces["egyp"].Insert(0, "Segoe UI Historic");
|
||||
MapScriptToTypefaces["armi"].Insert(0, "Segoe UI Historic");
|
||||
MapScriptToTypefaces["phli"].Insert(0, "Segoe UI Historic");
|
||||
MapScriptToTypefaces["prti"].Insert(0, "Segoe UI Historic");
|
||||
MapScriptToTypefaces["khar"].Insert(0, "Segoe UI Historic");
|
||||
MapScriptToTypefaces["lyci"].Insert(0, "Segoe UI Historic");
|
||||
MapScriptToTypefaces["lydi"].Insert(0, "Segoe UI Historic");
|
||||
MapScriptToTypefaces["phnx"].Insert(0, "Segoe UI Historic");
|
||||
MapScriptToTypefaces["xpeo"].Insert(0, "Segoe UI Historic");
|
||||
MapScriptToTypefaces["sarb"].Insert(0, "Segoe UI Historic");
|
||||
MapScriptToTypefaces["shaw"].Insert(0, "Segoe UI Historic");
|
||||
MapScriptToTypefaces["xsux"].Insert(0, "Segoe UI Historic");
|
||||
MapScriptToTypefaces["ugar"].Insert(0, "Segoe UI Historic");
|
||||
map["brah"].Insert(0, "Segoe UI Historic");
|
||||
map["cari"].Insert(0, "Segoe UI Historic");
|
||||
map["cprt"].Insert(0, "Segoe UI Historic");
|
||||
map["egyp"].Insert(0, "Segoe UI Historic");
|
||||
map["armi"].Insert(0, "Segoe UI Historic");
|
||||
map["phli"].Insert(0, "Segoe UI Historic");
|
||||
map["prti"].Insert(0, "Segoe UI Historic");
|
||||
map["khar"].Insert(0, "Segoe UI Historic");
|
||||
map["lyci"].Insert(0, "Segoe UI Historic");
|
||||
map["lydi"].Insert(0, "Segoe UI Historic");
|
||||
map["phnx"].Insert(0, "Segoe UI Historic");
|
||||
map["xpeo"].Insert(0, "Segoe UI Historic");
|
||||
map["sarb"].Insert(0, "Segoe UI Historic");
|
||||
map["shaw"].Insert(0, "Segoe UI Historic");
|
||||
map["xsux"].Insert(0, "Segoe UI Historic");
|
||||
map["ugar"].Insert(0, "Segoe UI Historic");
|
||||
// Segoe UI Symbol -> Segoe UI Historic
|
||||
MapScriptToTypefaces["glag"].Insert(0, "Segoe UI Historic");
|
||||
MapScriptToTypefaces["goth"].Insert(0, "Segoe UI Historic");
|
||||
MapScriptToTypefaces["merc"].Insert(0, "Segoe UI Historic");
|
||||
MapScriptToTypefaces["ogam"].Insert(0, "Segoe UI Historic");
|
||||
MapScriptToTypefaces["ital"].Insert(0, "Segoe UI Historic");
|
||||
MapScriptToTypefaces["orkh"].Insert(0, "Segoe UI Historic");
|
||||
MapScriptToTypefaces["runr"].Insert(0, "Segoe UI Historic");
|
||||
map["glag"].Insert(0, "Segoe UI Historic");
|
||||
map["goth"].Insert(0, "Segoe UI Historic");
|
||||
map["merc"].Insert(0, "Segoe UI Historic");
|
||||
map["ogam"].Insert(0, "Segoe UI Historic");
|
||||
map["ital"].Insert(0, "Segoe UI Historic");
|
||||
map["orkh"].Insert(0, "Segoe UI Historic");
|
||||
map["runr"].Insert(0, "Segoe UI Historic");
|
||||
//
|
||||
MapScriptToTypefaces["jpan"].Insert(0, "Yu Gothic UI");
|
||||
MapScriptToTypefaces["zsym"].Add("Segoe MDL2 Assets");
|
||||
map["jpan"].Insert(0, "Yu Gothic UI");
|
||||
map["zsym"].Add("Segoe MDL2 Assets");
|
||||
}
|
||||
return map;
|
||||
}
|
||||
public void LoadDefaultAndroidFallbackList() {
|
||||
if (Environment.OSVersion.Platform != PlatformID.Unix) return;
|
||||
MapScriptToTypefaces.Clear();
|
||||
ScriptUtils.FillKeysWithScripts(MapScriptToTypefaces, () => new List<string>());
|
||||
MapScriptToTypefaces["zyyy"].Insert(0, "Noto Sans CJK TC"); // TODO Modify default fallback
|
||||
MapScriptToTypefaces["zyyy"].Insert(0, "Noto Sans CJK JP");
|
||||
MapScriptToTypefaces["zyyy"].Insert(0, "Noto Sans CJK SC");
|
||||
MapScriptToTypefaces["zyyy"].Insert(0, "Roboto");
|
||||
MapScriptToTypefaces["zsye"].Insert(0, "Noto Color Emoji");
|
||||
MapScriptToTypefaces["zsye"].Add("Noto Color Emoji Flags");
|
||||
MapScriptToTypefaces["arab"].Insert(0, "Noto Naskh Arabic");
|
||||
MapScriptToTypefaces["adlm"].Insert(0, "Noto Sans Adlam");
|
||||
MapScriptToTypefaces["ahom"].Insert(0, "Noto Sans Ahom");
|
||||
MapScriptToTypefaces["hluw"].Insert(0, "Noto Sans Anatolian Hieroglyphs");
|
||||
MapScriptToTypefaces["armn"].Insert(0, "Noto Sans Armenian");
|
||||
MapScriptToTypefaces["avst"].Insert(0, "Noto Sans Avestan");
|
||||
MapScriptToTypefaces["bali"].Insert(0, "Noto Sans Balinese");
|
||||
MapScriptToTypefaces["bamu"].Insert(0, "Noto Sans Bamum");
|
||||
MapScriptToTypefaces["bass"].Insert(0, "Noto Sans Bassa Vah");
|
||||
MapScriptToTypefaces["batk"].Insert(0, "Noto Sans Batak");
|
||||
MapScriptToTypefaces["beng"].Insert(0, "Noto Sans Bengali");
|
||||
MapScriptToTypefaces["bhks"].Insert(0, "Noto Sans Bhaiksuki");
|
||||
MapScriptToTypefaces["brah"].Insert(0, "Noto Sans Brahmi");
|
||||
MapScriptToTypefaces["bugi"].Insert(0, "Noto Sans Buginese");
|
||||
MapScriptToTypefaces["buhd"].Insert(0, "Noto Sans Buhid");
|
||||
MapScriptToTypefaces["jpan"].Insert(0, "Noto Sans CJK JP");
|
||||
MapScriptToTypefaces["kore"].Insert(0, "Noto Sans CJK KR");
|
||||
MapScriptToTypefaces["hans"].Insert(0, "Noto Sans CJK SC");
|
||||
MapScriptToTypefaces["hant"].Insert(0, "Noto Sans CJK TC");
|
||||
MapScriptToTypefaces["hant"].Add("Noto Sans CJK HK");
|
||||
MapScriptToTypefaces["cans"].Insert(0, "Noto Sans Canadian Aboriginal");
|
||||
MapScriptToTypefaces["cari"].Insert(0, "Noto Sans Carian");
|
||||
MapScriptToTypefaces["cakm"].Insert(0, "Noto Sans Chakma");
|
||||
MapScriptToTypefaces["cham"].Insert(0, "Noto Sans Cham");
|
||||
MapScriptToTypefaces["cher"].Insert(0, "Noto Sans Cherokee");
|
||||
MapScriptToTypefaces["copt"].Insert(0, "Noto Sans Coptic");
|
||||
MapScriptToTypefaces["xsux"].Insert(0, "Noto Sans Cuneiform");
|
||||
MapScriptToTypefaces["cprt"].Insert(0, "Noto Sans Cypriot");
|
||||
MapScriptToTypefaces["dsrt"].Insert(0, "Noto Sans Deseret");
|
||||
MapScriptToTypefaces["deva"].Insert(0, "Noto Sans Devanagari");
|
||||
MapScriptToTypefaces["egyp"].Insert(0, "Noto Sans Egyptian Hieroglyphs");
|
||||
MapScriptToTypefaces["elba"].Insert(0, "Noto Sans Elbasan");
|
||||
MapScriptToTypefaces["ethi"].Insert(0, "Noto Sans Ethiopic");
|
||||
MapScriptToTypefaces["geor"].Insert(0, "Noto Sans Georgian");
|
||||
MapScriptToTypefaces["glag"].Insert(0, "Noto Sans Glagolitic");
|
||||
MapScriptToTypefaces["goth"].Insert(0, "Noto Sans Gothic");
|
||||
MapScriptToTypefaces["gran"].Insert(0, "Noto Sans Grantha");
|
||||
MapScriptToTypefaces["gujr"].Insert(0, "Noto Sans Gujarati");
|
||||
MapScriptToTypefaces["gong"].Insert(0, "Noto Sans Gunjala Gondi");
|
||||
MapScriptToTypefaces["guru"].Insert(0, "Noto Sans Gurmukhi");
|
||||
MapScriptToTypefaces["rohg"].Insert(0, "Noto Sans Hanifi Rohingya");
|
||||
MapScriptToTypefaces["hano"].Insert(0, "Noto Sans Hanunoo");
|
||||
MapScriptToTypefaces["hatr"].Insert(0, "Noto Sans Hatran");
|
||||
MapScriptToTypefaces["hebr"].Insert(0, "Noto Sans Hebrew");
|
||||
MapScriptToTypefaces["armi"].Insert(0, "Noto Sans Imperial Aramaic");
|
||||
MapScriptToTypefaces["phli"].Insert(0, "Noto Sans Inscriptional Pahlavi");
|
||||
MapScriptToTypefaces["prti"].Insert(0, "Noto Sans Inscriptional Parthian");
|
||||
MapScriptToTypefaces["java"].Insert(0, "Noto Sans Javanese");
|
||||
MapScriptToTypefaces["kthi"].Insert(0, "Noto Sans Kaithi");
|
||||
MapScriptToTypefaces["knda"].Insert(0, "Noto Sans Kannada");
|
||||
MapScriptToTypefaces["kali"].Insert(0, "Noto Sans KayahLi");
|
||||
MapScriptToTypefaces["khar"].Insert(0, "Noto Sans Kharoshthi");
|
||||
MapScriptToTypefaces["khmr"].Insert(0, "Noto Sans Khmer");
|
||||
MapScriptToTypefaces["khoj"].Insert(0, "Noto Sans Khojki");
|
||||
MapScriptToTypefaces["laoo"].Insert(0, "Noto Sans Lao");
|
||||
MapScriptToTypefaces["lepc"].Insert(0, "Noto Sans Lepcha");
|
||||
MapScriptToTypefaces["limb"].Insert(0, "Noto Sans Limbu");
|
||||
MapScriptToTypefaces["lina"].Insert(0, "Noto Sans Linear A");
|
||||
MapScriptToTypefaces["linb"].Insert(0, "Noto Sans Linear B");
|
||||
MapScriptToTypefaces["lisu"].Insert(0, "Noto Sans Lisu");
|
||||
MapScriptToTypefaces["lyci"].Insert(0, "Noto Sans Lycian");
|
||||
MapScriptToTypefaces["lydi"].Insert(0, "Noto Sans Lydian");
|
||||
MapScriptToTypefaces["mlym"].Insert(0, "Noto Sans Malayalam");
|
||||
MapScriptToTypefaces["mand"].Insert(0, "Noto Sans Mandiac");
|
||||
MapScriptToTypefaces["mani"].Insert(0, "Noto Sans Manichaean");
|
||||
MapScriptToTypefaces["marc"].Insert(0, "Noto Sans Marchen");
|
||||
MapScriptToTypefaces["gonm"].Insert(0, "Noto Sans Masaram Gondi");
|
||||
MapScriptToTypefaces["medf"].Insert(0, "Noto Sans Medefaidrin");
|
||||
MapScriptToTypefaces["mtei"].Insert(0, "Noto Sans Meetei Mayek");
|
||||
MapScriptToTypefaces["merc"].Insert(0, "Noto Sans Meroitic");
|
||||
MapScriptToTypefaces["mero"].Insert(0, "Noto Sans Meroitic");
|
||||
MapScriptToTypefaces["plrd"].Insert(0, "Noto Sans Miao");
|
||||
MapScriptToTypefaces["modi"].Insert(0, "Noto Sans Modi");
|
||||
MapScriptToTypefaces["mong"].Insert(0, "Noto Sans Mongolian");
|
||||
MapScriptToTypefaces["mroo"].Insert(0, "Noto Sans Mro");
|
||||
MapScriptToTypefaces["mult"].Insert(0, "Noto Sans Multani");
|
||||
MapScriptToTypefaces["mymr"].Insert(0, "Noto Sans Myanmar");
|
||||
MapScriptToTypefaces["nkoo"].Insert(0, "Noto Sans Nko");
|
||||
MapScriptToTypefaces["nbat"].Insert(0, "Noto Sans Nabataean");
|
||||
MapScriptToTypefaces["talu"].Insert(0, "Noto Sans New Tai Lue");
|
||||
MapScriptToTypefaces["newa"].Insert(0, "Noto Sans Newa");
|
||||
MapScriptToTypefaces["ogam"].Insert(0, "Noto Sans Ogham");
|
||||
MapScriptToTypefaces["olck"].Insert(0, "Noto Sans Ol Chiki");
|
||||
MapScriptToTypefaces["ital"].Insert(0, "Noto Sans Old Italian");
|
||||
MapScriptToTypefaces["narb"].Insert(0, "Noto Sans Old North Arabian");
|
||||
MapScriptToTypefaces["perm"].Insert(0, "Noto Sans Old Permic");
|
||||
MapScriptToTypefaces["xpeo"].Insert(0, "Noto Sans Old Persian");
|
||||
MapScriptToTypefaces["sarb"].Insert(0, "Noto Sans Old South Arabian");
|
||||
MapScriptToTypefaces["orkh"].Insert(0, "Noto Sans Old Turkic");
|
||||
MapScriptToTypefaces["orya"].Insert(0, "Noto Sans Oriya");
|
||||
MapScriptToTypefaces["osge"].Insert(0, "Noto Sans Osage");
|
||||
MapScriptToTypefaces["osma"].Insert(0, "Noto Sans Osmanya");
|
||||
MapScriptToTypefaces["hmng"].Insert(0, "Noto Sans Pahawh Hmong");
|
||||
MapScriptToTypefaces["palm"].Insert(0, "Noto Sans Palmyrene");
|
||||
MapScriptToTypefaces["pauc"].Insert(0, "Noto Sans Pau Cin Hau");
|
||||
MapScriptToTypefaces["phag"].Insert(0, "Noto Sans Phags Pa");
|
||||
MapScriptToTypefaces["phnx"].Insert(0, "Noto Sans Phoenician");
|
||||
MapScriptToTypefaces["rjng"].Insert(0, "Noto Sans Rejang");
|
||||
MapScriptToTypefaces["runr"].Insert(0, "Noto Sans Runic");
|
||||
MapScriptToTypefaces["samr"].Insert(0, "Noto Sans Samaritan");
|
||||
MapScriptToTypefaces["saur"].Insert(0, "Noto Sans Saurashtra");
|
||||
MapScriptToTypefaces["shrd"].Insert(0, "Noto Sans Sharada");
|
||||
MapScriptToTypefaces["shaw"].Insert(0, "Noto Sans Shavian");
|
||||
MapScriptToTypefaces["sinh"].Insert(0, "Noto Sans Sinhala");
|
||||
MapScriptToTypefaces["sora"].Insert(0, "Noto Sans Sora Sompeng");
|
||||
MapScriptToTypefaces["soyo"].Insert(0, "Noto Sans Soyombo");
|
||||
MapScriptToTypefaces["sund"].Insert(0, "Noto Sans Sundanese");
|
||||
MapScriptToTypefaces["sylo"].Insert(0, "Noto Sans Syloti Nagri");
|
||||
MapScriptToTypefaces["zsym"].Insert(0, "Noto Sans Symbols");
|
||||
MapScriptToTypefaces["syrn"].Insert(0, "Noto Sans Syriac Eastern");
|
||||
MapScriptToTypefaces["syre"].Insert(0, "Noto Sans Syriac Estrangela");
|
||||
MapScriptToTypefaces["syrj"].Insert(0, "Noto Sans Syriac Western");
|
||||
MapScriptToTypefaces["tglg"].Insert(0, "Noto Sans Tagalog");
|
||||
MapScriptToTypefaces["tagb"].Insert(0, "Noto Sans Tagbanwa");
|
||||
MapScriptToTypefaces["tale"].Insert(0, "Noto Sans Tai Le");
|
||||
MapScriptToTypefaces["lana"].Insert(0, "Noto Sans Tai Tham");
|
||||
MapScriptToTypefaces["tavt"].Insert(0, "Noto Sans Tai Viet");
|
||||
MapScriptToTypefaces["takr"].Insert(0, "Noto Sans Takri");
|
||||
MapScriptToTypefaces["taml"].Insert(0, "Noto Sans Tamil");
|
||||
MapScriptToTypefaces["telu"].Insert(0, "Noto Sans Telugu");
|
||||
MapScriptToTypefaces["thaa"].Insert(0, "Noto Sans Thaana");
|
||||
MapScriptToTypefaces["thai"].Insert(0, "Noto Sans Thai");
|
||||
MapScriptToTypefaces["tfng"].Insert(0, "Noto Sans Tifinagh");
|
||||
MapScriptToTypefaces["ugar"].Insert(0, "Noto Sans Ugaritic");
|
||||
MapScriptToTypefaces["vaii"].Insert(0, "Noto Sans Vai");
|
||||
MapScriptToTypefaces["wcho"].Insert(0, "Noto Sans Wancho");
|
||||
MapScriptToTypefaces["wara"].Insert(0, "Noto Sans Warang Citi");
|
||||
MapScriptToTypefaces["yiii"].Insert(0, "Noto Sans Yi");
|
||||
public static Dictionary<string, List<string>> GetDefaultAndroidFallbackMap() {
|
||||
var map = new Dictionary<string, List<string>>();
|
||||
ScriptUtils.FillKeysWithScripts(map, () => new List<string>());
|
||||
map["zyyy"].Insert(0, "Noto Sans CJK TC"); // TODO Modify default fallback
|
||||
map["zyyy"].Insert(0, "Noto Sans CJK JP");
|
||||
map["zyyy"].Insert(0, "Noto Sans CJK SC");
|
||||
map["zyyy"].Insert(0, "Roboto");
|
||||
map["zsye"].Insert(0, "Noto Color Emoji");
|
||||
map["zsye"].Add("Noto Color Emoji Flags");
|
||||
map["arab"].Insert(0, "Noto Naskh Arabic");
|
||||
map["adlm"].Insert(0, "Noto Sans Adlam");
|
||||
map["ahom"].Insert(0, "Noto Sans Ahom");
|
||||
map["hluw"].Insert(0, "Noto Sans Anatolian Hieroglyphs");
|
||||
map["armn"].Insert(0, "Noto Sans Armenian");
|
||||
map["avst"].Insert(0, "Noto Sans Avestan");
|
||||
map["bali"].Insert(0, "Noto Sans Balinese");
|
||||
map["bamu"].Insert(0, "Noto Sans Bamum");
|
||||
map["bass"].Insert(0, "Noto Sans Bassa Vah");
|
||||
map["batk"].Insert(0, "Noto Sans Batak");
|
||||
map["beng"].Insert(0, "Noto Sans Bengali");
|
||||
map["bhks"].Insert(0, "Noto Sans Bhaiksuki");
|
||||
map["brah"].Insert(0, "Noto Sans Brahmi");
|
||||
map["bugi"].Insert(0, "Noto Sans Buginese");
|
||||
map["buhd"].Insert(0, "Noto Sans Buhid");
|
||||
map["jpan"].Insert(0, "Noto Sans CJK JP");
|
||||
map["kore"].Insert(0, "Noto Sans CJK KR");
|
||||
map["hans"].Insert(0, "Noto Sans CJK SC");
|
||||
map["hant"].Insert(0, "Noto Sans CJK TC");
|
||||
map["hant"].Add("Noto Sans CJK HK");
|
||||
map["cans"].Insert(0, "Noto Sans Canadian Aboriginal");
|
||||
map["cari"].Insert(0, "Noto Sans Carian");
|
||||
map["cakm"].Insert(0, "Noto Sans Chakma");
|
||||
map["cham"].Insert(0, "Noto Sans Cham");
|
||||
map["cher"].Insert(0, "Noto Sans Cherokee");
|
||||
map["copt"].Insert(0, "Noto Sans Coptic");
|
||||
map["xsux"].Insert(0, "Noto Sans Cuneiform");
|
||||
map["cprt"].Insert(0, "Noto Sans Cypriot");
|
||||
map["dsrt"].Insert(0, "Noto Sans Deseret");
|
||||
map["deva"].Insert(0, "Noto Sans Devanagari");
|
||||
map["egyp"].Insert(0, "Noto Sans Egyptian Hieroglyphs");
|
||||
map["elba"].Insert(0, "Noto Sans Elbasan");
|
||||
map["ethi"].Insert(0, "Noto Sans Ethiopic");
|
||||
map["geor"].Insert(0, "Noto Sans Georgian");
|
||||
map["glag"].Insert(0, "Noto Sans Glagolitic");
|
||||
map["goth"].Insert(0, "Noto Sans Gothic");
|
||||
map["gran"].Insert(0, "Noto Sans Grantha");
|
||||
map["gujr"].Insert(0, "Noto Sans Gujarati");
|
||||
map["gong"].Insert(0, "Noto Sans Gunjala Gondi");
|
||||
map["guru"].Insert(0, "Noto Sans Gurmukhi");
|
||||
map["rohg"].Insert(0, "Noto Sans Hanifi Rohingya");
|
||||
map["hano"].Insert(0, "Noto Sans Hanunoo");
|
||||
map["hatr"].Insert(0, "Noto Sans Hatran");
|
||||
map["hebr"].Insert(0, "Noto Sans Hebrew");
|
||||
map["armi"].Insert(0, "Noto Sans Imperial Aramaic");
|
||||
map["phli"].Insert(0, "Noto Sans Inscriptional Pahlavi");
|
||||
map["prti"].Insert(0, "Noto Sans Inscriptional Parthian");
|
||||
map["java"].Insert(0, "Noto Sans Javanese");
|
||||
map["kthi"].Insert(0, "Noto Sans Kaithi");
|
||||
map["knda"].Insert(0, "Noto Sans Kannada");
|
||||
map["kali"].Insert(0, "Noto Sans KayahLi");
|
||||
map["khar"].Insert(0, "Noto Sans Kharoshthi");
|
||||
map["khmr"].Insert(0, "Noto Sans Khmer");
|
||||
map["khoj"].Insert(0, "Noto Sans Khojki");
|
||||
map["laoo"].Insert(0, "Noto Sans Lao");
|
||||
map["lepc"].Insert(0, "Noto Sans Lepcha");
|
||||
map["limb"].Insert(0, "Noto Sans Limbu");
|
||||
map["lina"].Insert(0, "Noto Sans Linear A");
|
||||
map["linb"].Insert(0, "Noto Sans Linear B");
|
||||
map["lisu"].Insert(0, "Noto Sans Lisu");
|
||||
map["lyci"].Insert(0, "Noto Sans Lycian");
|
||||
map["lydi"].Insert(0, "Noto Sans Lydian");
|
||||
map["mlym"].Insert(0, "Noto Sans Malayalam");
|
||||
map["mand"].Insert(0, "Noto Sans Mandiac");
|
||||
map["mani"].Insert(0, "Noto Sans Manichaean");
|
||||
map["marc"].Insert(0, "Noto Sans Marchen");
|
||||
map["gonm"].Insert(0, "Noto Sans Masaram Gondi");
|
||||
map["medf"].Insert(0, "Noto Sans Medefaidrin");
|
||||
map["mtei"].Insert(0, "Noto Sans Meetei Mayek");
|
||||
map["merc"].Insert(0, "Noto Sans Meroitic");
|
||||
map["mero"].Insert(0, "Noto Sans Meroitic");
|
||||
map["plrd"].Insert(0, "Noto Sans Miao");
|
||||
map["modi"].Insert(0, "Noto Sans Modi");
|
||||
map["mong"].Insert(0, "Noto Sans Mongolian");
|
||||
map["mroo"].Insert(0, "Noto Sans Mro");
|
||||
map["mult"].Insert(0, "Noto Sans Multani");
|
||||
map["mymr"].Insert(0, "Noto Sans Myanmar");
|
||||
map["nkoo"].Insert(0, "Noto Sans Nko");
|
||||
map["nbat"].Insert(0, "Noto Sans Nabataean");
|
||||
map["talu"].Insert(0, "Noto Sans New Tai Lue");
|
||||
map["newa"].Insert(0, "Noto Sans Newa");
|
||||
map["ogam"].Insert(0, "Noto Sans Ogham");
|
||||
map["olck"].Insert(0, "Noto Sans Ol Chiki");
|
||||
map["ital"].Insert(0, "Noto Sans Old Italian");
|
||||
map["narb"].Insert(0, "Noto Sans Old North Arabian");
|
||||
map["perm"].Insert(0, "Noto Sans Old Permic");
|
||||
map["xpeo"].Insert(0, "Noto Sans Old Persian");
|
||||
map["sarb"].Insert(0, "Noto Sans Old South Arabian");
|
||||
map["orkh"].Insert(0, "Noto Sans Old Turkic");
|
||||
map["orya"].Insert(0, "Noto Sans Oriya");
|
||||
map["osge"].Insert(0, "Noto Sans Osage");
|
||||
map["osma"].Insert(0, "Noto Sans Osmanya");
|
||||
map["hmng"].Insert(0, "Noto Sans Pahawh Hmong");
|
||||
map["palm"].Insert(0, "Noto Sans Palmyrene");
|
||||
map["pauc"].Insert(0, "Noto Sans Pau Cin Hau");
|
||||
map["phag"].Insert(0, "Noto Sans Phags Pa");
|
||||
map["phnx"].Insert(0, "Noto Sans Phoenician");
|
||||
map["rjng"].Insert(0, "Noto Sans Rejang");
|
||||
map["runr"].Insert(0, "Noto Sans Runic");
|
||||
map["samr"].Insert(0, "Noto Sans Samaritan");
|
||||
map["saur"].Insert(0, "Noto Sans Saurashtra");
|
||||
map["shrd"].Insert(0, "Noto Sans Sharada");
|
||||
map["shaw"].Insert(0, "Noto Sans Shavian");
|
||||
map["sinh"].Insert(0, "Noto Sans Sinhala");
|
||||
map["sora"].Insert(0, "Noto Sans Sora Sompeng");
|
||||
map["soyo"].Insert(0, "Noto Sans Soyombo");
|
||||
map["sund"].Insert(0, "Noto Sans Sundanese");
|
||||
map["sylo"].Insert(0, "Noto Sans Syloti Nagri");
|
||||
map["zsym"].Insert(0, "Noto Sans Symbols");
|
||||
map["syrn"].Insert(0, "Noto Sans Syriac Eastern");
|
||||
map["syre"].Insert(0, "Noto Sans Syriac Estrangela");
|
||||
map["syrj"].Insert(0, "Noto Sans Syriac Western");
|
||||
map["tglg"].Insert(0, "Noto Sans Tagalog");
|
||||
map["tagb"].Insert(0, "Noto Sans Tagbanwa");
|
||||
map["tale"].Insert(0, "Noto Sans Tai Le");
|
||||
map["lana"].Insert(0, "Noto Sans Tai Tham");
|
||||
map["tavt"].Insert(0, "Noto Sans Tai Viet");
|
||||
map["takr"].Insert(0, "Noto Sans Takri");
|
||||
map["taml"].Insert(0, "Noto Sans Tamil");
|
||||
map["telu"].Insert(0, "Noto Sans Telugu");
|
||||
map["thaa"].Insert(0, "Noto Sans Thaana");
|
||||
map["thai"].Insert(0, "Noto Sans Thai");
|
||||
map["tfng"].Insert(0, "Noto Sans Tifinagh");
|
||||
map["ugar"].Insert(0, "Noto Sans Ugaritic");
|
||||
map["vaii"].Insert(0, "Noto Sans Vai");
|
||||
map["wcho"].Insert(0, "Noto Sans Wancho");
|
||||
map["wara"].Insert(0, "Noto Sans Warang Citi");
|
||||
map["yiii"].Insert(0, "Noto Sans Yi");
|
||||
return map;
|
||||
}
|
||||
public FallbackListFontMatcher(FontManager manager) : base(manager) { }
|
||||
public override IEnumerable<Typeface> MatchScript(string script = null, bool distinctFamily = false) {
|
||||
|
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
@@ -1,4 +1,4 @@
|
||||
using System.IO;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace Cryville.Common.Font {
|
||||
|
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
|
@@ -1,15 +1,15 @@
|
||||
using System;
|
||||
using System;
|
||||
|
||||
namespace Cryville.Common {
|
||||
public struct Identifier : IEquatable<Identifier> {
|
||||
public static Identifier Empty = new Identifier(0);
|
||||
public int Key { get; private set; }
|
||||
public object Name { get { return IdentifierManager.SharedInstance.Retrieve(Key); } }
|
||||
public object Name { get { return IdentifierManager.Shared.Retrieve(Key); } }
|
||||
public Identifier(int key) {
|
||||
Key = key;
|
||||
}
|
||||
public Identifier(object name) {
|
||||
Key = IdentifierManager.SharedInstance.Request(name);
|
||||
Key = IdentifierManager.Shared.Request(name);
|
||||
}
|
||||
public override bool Equals(object obj) {
|
||||
if (obj == null || !(obj is Identifier)) return false;
|
||||
|
@@ -1,52 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Cryville.Common {
|
||||
/// <summary>
|
||||
/// A manager that assigns each given identifiers a unique integer ID.
|
||||
/// </summary>
|
||||
public class IdentifierManager {
|
||||
/// <summary>
|
||||
/// A shared instance of the <see cref="IdentifierManager" /> class.
|
||||
/// </summary>
|
||||
public static IdentifierManager SharedInstance = new IdentifierManager();
|
||||
|
||||
readonly Dictionary<object, int> _idents = new Dictionary<object, int>();
|
||||
readonly List<object> _ids = new List<object>();
|
||||
|
||||
readonly object _syncRoot = new object();
|
||||
|
||||
/// <summary>
|
||||
/// Creates an instance of the <see cref="IdentifierManager" /> class.
|
||||
/// </summary>
|
||||
public IdentifierManager() {
|
||||
Request(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Requests an integer ID for an identifier.
|
||||
/// </summary>
|
||||
/// <param name="ident">The identifier.</param>
|
||||
/// <returns>The integer ID.</returns>
|
||||
public int Request(object ident) {
|
||||
lock (_syncRoot) {
|
||||
int id;
|
||||
if (!_idents.TryGetValue(ident, out id)) {
|
||||
_idents.Add(ident, id = _idents.Count);
|
||||
_ids.Add(ident);
|
||||
}
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the identifier assigned with an integer ID.
|
||||
/// </summary>
|
||||
/// <param name="id">The integer ID.</param>
|
||||
/// <returns>The identifier.</returns>
|
||||
public object Retrieve(int id) {
|
||||
lock (_syncRoot) {
|
||||
return _ids[id];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 478086496f56eaf46be4df4e2ad37fee
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,128 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
|
||||
namespace Cryville.Common {
|
||||
/// <summary>
|
||||
/// A logger.
|
||||
/// </summary>
|
||||
public abstract class Logger {
|
||||
static readonly Dictionary<string, Logger> Instances = new Dictionary<string, Logger>();
|
||||
static readonly Dictionary<string, StreamWriter> Files = new Dictionary<string, StreamWriter>();
|
||||
static string logPath = null;
|
||||
/// <summary>
|
||||
/// Sets the path where the log files shall be stored.
|
||||
/// </summary>
|
||||
/// <param name="path">The path.</param>
|
||||
public static void SetLogPath(string path) {
|
||||
logPath = path;
|
||||
var dir = new DirectoryInfo(path);
|
||||
if (!dir.Exists) dir.Create();
|
||||
}
|
||||
/// <summary>
|
||||
/// Logs to the specified logger.
|
||||
/// </summary>
|
||||
/// <param name="key">The key of the logger.</param>
|
||||
/// <param name="level">The severity level.</param>
|
||||
/// <param name="module">The module that is logging.</param>
|
||||
/// <param name="format">The format string.</param>
|
||||
/// <param name="args">The arguments for formatting.</param>
|
||||
public static void Log(string key, int level, string module, string format, params object[] args) {
|
||||
if (!Instances.ContainsKey(key)) return;
|
||||
Instances[key].Log(level, module, string.Format(format, args));
|
||||
if (Files.ContainsKey(key)) Files[key].WriteLine("[{0:O}] [{1}] <{2}> {3}", DateTime.UtcNow, level, module, string.Format(format, args));
|
||||
}
|
||||
/// <summary>
|
||||
/// Adds a created logger to the shared logger manager.
|
||||
/// </summary>
|
||||
/// <param name="key">The key of the logger.</param>
|
||||
/// <param name="logger">The logger.</param>
|
||||
public static void Create(string key, Logger logger) {
|
||||
Instances[key] = logger;
|
||||
if (logPath != null) {
|
||||
Files[key] = new StreamWriter(logPath + "/" + ((int)DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds).ToString(CultureInfo.InvariantCulture) + "-" + key + ".log") {
|
||||
AutoFlush = true
|
||||
};
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Closes all loggers and related file streams.
|
||||
/// </summary>
|
||||
public static void Close() {
|
||||
Instances.Clear();
|
||||
foreach (var f in Files) f.Value.Dispose();
|
||||
Files.Clear();
|
||||
}
|
||||
/// <summary>
|
||||
/// Logs to the logger.
|
||||
/// </summary>
|
||||
/// <param name="level">The severity level.</param>
|
||||
/// <param name="module">The module that is logging.</param>
|
||||
/// <param name="msg">The message.</param>
|
||||
public virtual void Log(int level, string module, string msg) { }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="Logger" /> that calls a callback function on log.
|
||||
/// </summary>
|
||||
public class InstantLogger : Logger {
|
||||
readonly Action<int, string, string> callback;
|
||||
/// <summary>
|
||||
/// Creates an instance of the <see cref="InstantLogger" /> class.
|
||||
/// </summary>
|
||||
/// <param name="callback">The callback function.</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="callback" /> is <see langword="null" />.</exception>
|
||||
public InstantLogger(Action<int, string, string> callback) {
|
||||
if (callback == null)
|
||||
throw new ArgumentNullException("callback");
|
||||
this.callback = callback;
|
||||
}
|
||||
/// <inheritdoc />
|
||||
public override void Log(int level, string module, string msg) {
|
||||
base.Log(level, module, msg);
|
||||
callback(level, module, msg);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A <see cref="Logger" /> that buffers the logs for enumeration.
|
||||
/// </summary>
|
||||
public class BufferedLogger : Logger {
|
||||
readonly List<LogEntry> buffer = new List<LogEntry>();
|
||||
/// <summary>
|
||||
/// Creates an instance of the <see cref="BufferedLogger" /> class.
|
||||
/// </summary>
|
||||
public BufferedLogger() { }
|
||||
/// <inheritdoc />
|
||||
public override void Log(int level, string module, string msg) {
|
||||
base.Log(level, module, msg);
|
||||
lock (buffer) {
|
||||
buffer.Add(new LogEntry(level, module, msg));
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Enumerates the buffered logs.
|
||||
/// </summary>
|
||||
/// <param name="callback">The callback function to receive the logs.</param>
|
||||
public void Enumerate(Action<int, string, string> callback) {
|
||||
lock (buffer) {
|
||||
foreach (var i in buffer) {
|
||||
callback(i.level, i.module, i.msg);
|
||||
}
|
||||
}
|
||||
buffer.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
struct LogEntry {
|
||||
public int level;
|
||||
public string module;
|
||||
public string msg;
|
||||
public LogEntry(int level, string module, string msg) {
|
||||
this.level = level;
|
||||
this.module = module;
|
||||
this.msg = msg;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,12 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1c1729cfde78f1c479c9f7eb166e0107
|
||||
timeCreated: 1611126212
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,44 +1,27 @@
|
||||
using SMath = System.Math;
|
||||
using SMath = System.Math;
|
||||
|
||||
namespace Cryville.Common.Math {
|
||||
// Ported from https://github.com/arian/cubic-bezier/blob/master/index.js
|
||||
public static class CubicBezier {
|
||||
public static float Evaluate(float t, float x1, float y1, float x2, float y2, float epsilon) {
|
||||
float x = t, t0, t1, t2, tx, d2, i;
|
||||
for (t2 = x, i = 0; i < 8; i++) {
|
||||
tx = CurveX(t2, x1, x2) - x;
|
||||
if (SMath.Abs(tx) < epsilon) return CurveY(t2, y1, y2);
|
||||
d2 = DerivativeCurveX(t2, x1, x2);
|
||||
if (SMath.Abs(d2) < 1e-6) break;
|
||||
t2 -= tx / d2;
|
||||
}
|
||||
float x = t, t0 = 0, t1 = 1, t2 = x;
|
||||
|
||||
t0 = 0; t1 = 1; t2 = x;
|
||||
|
||||
if (t2 < t0) return CurveY(t0, y1, y2);
|
||||
if (t2 > t1) return CurveY(t1, y1, y2);
|
||||
if (t2 < t0) return Curve(t0, y1, y2);
|
||||
if (t2 > t1) return Curve(t1, y1, y2);
|
||||
|
||||
while (t0 < t1) {
|
||||
tx = CurveX(t2, x1, x2);
|
||||
if (SMath.Abs(tx - x) < epsilon) return CurveY(t2, y1, y2);
|
||||
float tx = Curve(t2, x1, x2);
|
||||
if (SMath.Abs(tx - x) < epsilon) return Curve(t2, y1, y2);
|
||||
if (x > tx) t0 = t2;
|
||||
else t1 = t2;
|
||||
t2 = (t1 - t0) * .5f + t0;
|
||||
}
|
||||
|
||||
return CurveY(t2, y1, y2);
|
||||
return Curve(t2, y1, y2);
|
||||
}
|
||||
static float CurveX(float t, float x1, float x2) {
|
||||
static float Curve(float t, float p1, float p2) {
|
||||
float v = 1 - t;
|
||||
return 3 * v * v * t * x1 + 3 * v * t * t * x2 + t * t * t;
|
||||
}
|
||||
static float CurveY(float t, float y1, float y2) {
|
||||
float v = 1 - t;
|
||||
return 3 * v * v * t * y1 + 3 * v * t * t * y2 + t * t * t;
|
||||
}
|
||||
static float DerivativeCurveX(float t, float x1, float x2) {
|
||||
float v = 1 - t;
|
||||
return 3 * (2 * (t - 1) * t + v * v) * x1 + 3 * (-t * t * t + 2 * v * t) * x2;
|
||||
return 3 * v * v * t * p1 + 3 * v * t * t * p2 + t * t * t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
|
||||
namespace Cryville.Common.Math {
|
||||
/// <summary>
|
||||
|
@@ -1,4 +1,4 @@
|
||||
using UnsafeIL;
|
||||
using UnsafeIL;
|
||||
|
||||
namespace Cryville.Common.Math {
|
||||
/// <summary>
|
||||
|
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 53f4e3167a1eee2478b0abc6302aee8f
|
||||
guid: 1a624371d4108614b9cdc4acca1499e2
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
@@ -1,14 +1,14 @@
|
||||
using Cryville.Common.Logging;
|
||||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Sockets;
|
||||
using System.Text;
|
||||
|
||||
namespace Cryville.Common.Network {
|
||||
public class HttpClient {
|
||||
namespace Cryville.Common.Network.Http11 {
|
||||
public class Http11Client : IDisposable {
|
||||
private readonly string _directHost;
|
||||
protected string DirectHost { get { return _directHost; } }
|
||||
|
||||
@@ -18,29 +18,17 @@ namespace Cryville.Common.Network {
|
||||
readonly Uri _baseUri;
|
||||
readonly int origPort;
|
||||
|
||||
protected string Version = "HTTP/1.1";
|
||||
protected const string Version = "HTTP/1.1";
|
||||
protected TcpClient TcpClient { get; private set; }
|
||||
protected Stream RawTcpStream {
|
||||
get {
|
||||
return TcpClient.GetStream();
|
||||
}
|
||||
}
|
||||
protected virtual Stream Stream {
|
||||
get {
|
||||
return TcpClient.GetStream();
|
||||
}
|
||||
}
|
||||
protected virtual string WindowsProxyProtocolName {
|
||||
get {
|
||||
return "http";
|
||||
}
|
||||
}
|
||||
protected Stream RawTcpStream { get { return TcpClient.GetStream(); } }
|
||||
protected virtual Stream Stream { get { return TcpClient.GetStream(); } }
|
||||
protected virtual string WindowsProxyProtocolName { get { return "http"; } }
|
||||
|
||||
private readonly bool _proxied = false;
|
||||
|
||||
public Dictionary<string, string> Headers { get; set; }
|
||||
|
||||
public HttpClient(Uri baseUri, int port = 80) {
|
||||
public Http11Client(Uri baseUri, int port = 80) {
|
||||
_directHost = baseUri.Host;
|
||||
_directPort = port;
|
||||
_baseUri = baseUri;
|
||||
@@ -60,18 +48,29 @@ namespace Cryville.Common.Network {
|
||||
public virtual void Close() {
|
||||
TcpClient.Close();
|
||||
}
|
||||
|
||||
public HttpResponse Request(string method, Uri uri, string body = null, Encoding encoding = null) {
|
||||
|
||||
public void Dispose() {
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
public virtual void Dispose(bool disposing) {
|
||||
if (disposing) {
|
||||
Close();
|
||||
}
|
||||
}
|
||||
|
||||
public Http11Response Request(string method, Uri uri, string body = null, Encoding encoding = null) {
|
||||
string struri = GetUri(uri).PathAndQuery;
|
||||
return Request(Stream, method, struri, body, encoding);
|
||||
}
|
||||
|
||||
public HttpResponse Request(Stream stream, string method, string uri, string body = null, Encoding encoding = null) {
|
||||
var headers = new Dictionary<string, string>();
|
||||
Http11Response Request(Stream stream, string method, string uri, string body = null, Encoding encoding = null) {
|
||||
var headers = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
foreach (var h in Headers)
|
||||
headers.Add(h.Key, h.Value);
|
||||
headers["Host"] = _baseUri.Host;
|
||||
byte[] payload = new byte[0];
|
||||
byte[] payload = null;
|
||||
if (body != null) {
|
||||
if (encoding == null)
|
||||
encoding = Encoding.UTF8;
|
||||
@@ -79,22 +78,24 @@ namespace Cryville.Common.Network {
|
||||
headers.Add("Content-Encoding", encoding.EncodingName);
|
||||
headers.Add("Content-Length", payload.Length.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
string request_line = string.Format(
|
||||
"{0} {1} {2}\r\n", method, uri, Version
|
||||
);
|
||||
string header_fields = string.Concat((
|
||||
from h in headers select h.Key + ":" + h.Value + "\r\n"
|
||||
).ToArray());
|
||||
byte[] buffer0 = Encoding.ASCII.GetBytes(string.Format(
|
||||
"{0}{1}\r\n", request_line, header_fields
|
||||
));
|
||||
byte[] buffer1 = new byte[buffer0.Length + payload.Length];
|
||||
Array.Copy(buffer0, buffer1, buffer0.Length);
|
||||
Array.Copy(payload, 0, buffer1, buffer0.Length, payload.Length);
|
||||
Logger.Log("main", 0, "Network", Encoding.UTF8.GetString(buffer1));
|
||||
stream.Write(buffer1, 0, buffer1.Length);
|
||||
stream.Flush();
|
||||
var response = new HttpResponse(stream);
|
||||
using (var writer = new StreamWriter(stream, Encoding.ASCII, 1024, true)) {
|
||||
writer.Write(method);
|
||||
writer.Write(' ');
|
||||
writer.Write(uri);
|
||||
writer.Write(' ');
|
||||
writer.Write(Version);
|
||||
writer.Write("\r\n");
|
||||
foreach (var header in headers) {
|
||||
writer.Write(header.Key);
|
||||
writer.Write(':');
|
||||
writer.Write(header.Value);
|
||||
writer.Write("\r\n");
|
||||
}
|
||||
writer.Write("\r\n");
|
||||
if (payload != null) writer.Write(payload);
|
||||
writer.Flush();
|
||||
}
|
||||
var response = new Http11Response(stream);
|
||||
Logger.Log("main", 0, "Network", "{0}", response);
|
||||
return response;
|
||||
}
|
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ec18f22479042d747b88c093aa90c5c0
|
||||
guid: 5a795e416e54c69418de1a3c27a88932
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
@@ -1,30 +1,41 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace Cryville.Common.Network {
|
||||
public class HttpResponse {
|
||||
namespace Cryville.Common.Network.Http11 {
|
||||
public class Http11Response : IDisposable {
|
||||
static readonly char[] spchar = new char[]{ ' ' };
|
||||
public string HttpVersion { get; private set; }
|
||||
public string StatusCode { get; private set; }
|
||||
public string ReasonPhase { get; private set; }
|
||||
public Dictionary<string, string> Headers { get; private set; }
|
||||
public HttpResponseStream MessageBody { get; private set; }
|
||||
internal HttpResponse(Stream stream) {
|
||||
public Http11ResponseStream MessageBody { get; private set; }
|
||||
internal Http11Response(Stream stream) {
|
||||
var reader = new BinaryReader(stream, Encoding.ASCII);
|
||||
var statu_line = ReadLine(reader).Split(spchar, 3);
|
||||
HttpVersion = statu_line[0];
|
||||
StatusCode = statu_line[1];
|
||||
ReasonPhase = statu_line[2];
|
||||
Logger.Log("main", 0, "Network", "Receive Response: {0} {1} {2}", HttpVersion, StatusCode, ReasonPhase);
|
||||
Headers = new Dictionary<string, string>();
|
||||
Headers = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
while (ParseHeader(reader, Headers)) ;
|
||||
if (Headers.ContainsKey("content-length")) {
|
||||
int length = int.Parse(Headers["content-length"]);
|
||||
MessageBody = new HttpResponseBlockStream(reader, length);
|
||||
MessageBody = new Http11ResponseBlockStream(reader, length);
|
||||
}
|
||||
else if (Headers.ContainsKey("transfer-encoding") && Headers["transfer-encoding"] == "chunked") {
|
||||
MessageBody = new HttpResponseChunkedStream(reader);
|
||||
MessageBody = new Http11ResponseChunkedStream(reader);
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
public virtual void Dispose(bool disposing) {
|
||||
if (disposing) {
|
||||
MessageBody.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,12 +47,11 @@ namespace Cryville.Common.Network {
|
||||
// TODO Multiline header
|
||||
var header = ReadLine(reader);
|
||||
if (header == "") return false;
|
||||
var s = header.Split(':');
|
||||
var s = header.Split(':', 2);
|
||||
string field_name = s[0].Trim().ToLower();
|
||||
string field_value = s[1].Trim();
|
||||
if (headers.ContainsKey(field_name)) headers[field_name] += "," + field_value;
|
||||
else headers.Add(field_name, field_value);
|
||||
Logger.Log("main", 0, "Network", "Receive Header {0}: {1}", field_name, field_value);
|
||||
return true;
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: df66519fa93e1b94ea5bb1702cc91b3f
|
||||
guid: 71234dd1c93d47b4893750686b2333a3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
@@ -1,11 +1,11 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace Cryville.Common.Network {
|
||||
public abstract class HttpResponseStream : Stream {
|
||||
namespace Cryville.Common.Network.Http11 {
|
||||
public abstract class Http11ResponseStream : Stream {
|
||||
public override bool CanRead { get { return true; } }
|
||||
|
||||
public override bool CanSeek { get { return false; } }
|
||||
@@ -36,11 +36,11 @@ namespace Cryville.Common.Network {
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class HttpResponseBlockStream : HttpResponseStream {
|
||||
internal sealed class Http11ResponseBlockStream : Http11ResponseStream {
|
||||
readonly BinaryReader _reader;
|
||||
readonly int _length;
|
||||
int _pos = 0;
|
||||
internal HttpResponseBlockStream(BinaryReader reader, int length) {
|
||||
internal Http11ResponseBlockStream(BinaryReader reader, int length) {
|
||||
_reader = reader;
|
||||
_length = length;
|
||||
}
|
||||
@@ -50,7 +50,6 @@ namespace Cryville.Common.Network {
|
||||
if (recv_len == 0) return 0;
|
||||
while (recv < recv_len) {
|
||||
recv += _reader.Read(buffer, offset + recv, count - recv);
|
||||
Logger.Log("main", 0, "Network", "Message body received: {0}/{1}/{2}", recv, recv_len, _length);
|
||||
}
|
||||
_pos += recv_len;
|
||||
return recv_len;
|
||||
@@ -62,36 +61,34 @@ namespace Cryville.Common.Network {
|
||||
}
|
||||
}
|
||||
|
||||
internal sealed class HttpResponseChunkedStream : HttpResponseStream {
|
||||
internal sealed class Http11ResponseChunkedStream : Http11ResponseStream {
|
||||
readonly BinaryReader _reader;
|
||||
byte[] _chunk = null;
|
||||
int _pos = 0;
|
||||
internal HttpResponseChunkedStream(BinaryReader reader) {
|
||||
internal Http11ResponseChunkedStream(BinaryReader reader) {
|
||||
_reader = reader;
|
||||
ReadChunk();
|
||||
}
|
||||
public void ReadChunk() {
|
||||
if (_chunk != null && _chunk.Length == 0) return;
|
||||
string[] chunkHeader = HttpResponse.ReadLine(_reader).Split(';');
|
||||
// int chunkSize = Array.IndexOf(LEN, chunkHeader[0].ToLower()[0]);
|
||||
int chunkSize = int.Parse(chunkHeader[0], NumberStyles.HexNumber);
|
||||
if (chunkSize == -1)
|
||||
string[] chunkHeader = Http11Response.ReadLine(_reader).Split(';');
|
||||
int chunkSize;
|
||||
if (!int.TryParse(chunkHeader[0], NumberStyles.HexNumber, CultureInfo.InvariantCulture, out chunkSize))
|
||||
throw new IOException("Corrupted chunk received");
|
||||
if (chunkSize == 0) {
|
||||
_chunk = new byte[0];
|
||||
// TODO TE Header, now just discard
|
||||
var headers = new Dictionary<string, string>();
|
||||
while (HttpResponse.ParseHeader(_reader, headers)) ;
|
||||
while (Http11Response.ParseHeader(_reader, headers)) ;
|
||||
return;
|
||||
}
|
||||
_chunk = new byte[chunkSize];
|
||||
int recv = 0;
|
||||
while (recv < chunkSize) {
|
||||
recv += _reader.Read(_chunk, recv, chunkSize - recv);
|
||||
Logger.Log("main", 0, "Network", "Message chunk received: {0}/{1}", recv, chunkSize);
|
||||
}
|
||||
_pos = 0;
|
||||
if (HttpResponse.ReadLine(_reader) != "")
|
||||
if (Http11Response.ReadLine(_reader) != "")
|
||||
throw new IOException("Corrupted chunk received");
|
||||
}
|
||||
public override int Read(byte[] buffer, int offset, int count) {
|
||||
@@ -130,4 +127,4 @@ namespace Cryville.Common.Network {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,5 +1,5 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2b7b45ff20c33ac47b476371673b037c
|
||||
guid: 49a8d5b9869e5bb42bafbe71f84fecc5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
@@ -1,8 +1,8 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Cryville.Common.Network {
|
||||
public class HttpsClient : HttpClient {
|
||||
namespace Cryville.Common.Network.Http11 {
|
||||
public class Https11Client : Http11Client {
|
||||
readonly TlsClient _tlsClient;
|
||||
|
||||
protected override Stream Stream {
|
||||
@@ -16,7 +16,7 @@ namespace Cryville.Common.Network {
|
||||
}
|
||||
}
|
||||
|
||||
public HttpsClient(Uri baseUri) : base(baseUri, 443) {
|
||||
public Https11Client(Uri baseUri) : base(baseUri, 443) {
|
||||
_tlsClient = new TlsClient(RawTcpStream, baseUri.Host);
|
||||
}
|
||||
|
11
Assets/Cryville/Common/Network/Http11/Https11Client.cs.meta
Normal file
11
Assets/Cryville/Common/Network/Http11/Https11Client.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c5c233e6228ce204fa1a9724c48ac8fe
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,12 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5ea931bf5488011468f3d1243a038874
|
||||
timeCreated: 1622589817
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,12 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 07e8215a93e3eb1418685009f0c58dcd
|
||||
timeCreated: 1622596274
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,12 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f191de447a708da4f9d230e6545ce0a6
|
||||
timeCreated: 1635470462
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,12 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9b35290e0e147a342acc29a20c8fceaf
|
||||
timeCreated: 1622503538
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -2,6 +2,7 @@ using Org.BouncyCastle.Security;
|
||||
using Org.BouncyCastle.Tls;
|
||||
using Org.BouncyCastle.Tls.Crypto;
|
||||
using Org.BouncyCastle.Tls.Crypto.Impl.BC;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
@@ -9,7 +10,7 @@ using System.Text;
|
||||
using BcTlsClient = Org.BouncyCastle.Tls.TlsClient;
|
||||
|
||||
namespace Cryville.Common.Network {
|
||||
public class TlsClient {
|
||||
public class TlsClient : IDisposable {
|
||||
readonly TlsClientProtocol _protocol;
|
||||
readonly BcTlsClient _tlsClient;
|
||||
public Stream Stream { get; private set; }
|
||||
@@ -27,6 +28,17 @@ namespace Cryville.Common.Network {
|
||||
_protocol.Close();
|
||||
}
|
||||
|
||||
public void Dispose() {
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
public virtual void Dispose(bool disposing) {
|
||||
if (disposing) {
|
||||
Close();
|
||||
}
|
||||
}
|
||||
|
||||
private class InternalTlsClient : DefaultTlsClient {
|
||||
readonly string _host;
|
||||
|
||||
@@ -71,20 +83,6 @@ namespace Cryville.Common.Network {
|
||||
public override TlsAuthentication GetAuthentication() {
|
||||
return new NullTlsAuthentication();
|
||||
}
|
||||
|
||||
public override void NotifyAlertReceived(short alertLevel, short alertDescription) {
|
||||
Logger.Log("main", 0, "Network/TLS", "TLS Alert {0} {1}", alertLevel, alertDescription);
|
||||
}
|
||||
|
||||
public override void NotifyServerVersion(ProtocolVersion serverVersion) {
|
||||
base.NotifyServerVersion(serverVersion);
|
||||
Logger.Log("main", 0, "Network/TLS", "NotifyServerVersion {0}", serverVersion);
|
||||
}
|
||||
|
||||
public override void NotifySelectedCipherSuite(int selectedCipherSuite) {
|
||||
base.NotifySelectedCipherSuite(selectedCipherSuite);
|
||||
Logger.Log("main", 0, "Network/TLS", "NotifySelectedCipherSuite {0}", selectedCipherSuite);
|
||||
}
|
||||
}
|
||||
|
||||
private class NullTlsAuthentication : TlsAuthentication {
|
||||
|
@@ -1,11 +1,11 @@
|
||||
using System;
|
||||
using System;
|
||||
|
||||
namespace Cryville.Common.Pdt {
|
||||
/// <summary>
|
||||
/// Indicates that the attributed member is an element list.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>An element list is a <see cref="System.Collections.IDictionary" /> or <see cref="Cryville.Common.Collections.Generic.IPairList" /> that represents a collection of PDT elements. There must be at most one element list in a class.</para>
|
||||
/// <para>An element list is a <see cref="System.Collections.IDictionary" /> or <see cref="Cryville.Common.Collections.IPairList" /> that represents a collection of PDT elements. There must be at most one element list in a class.</para>
|
||||
/// </remarks>
|
||||
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
|
||||
public class ElementListAttribute : Attribute { }
|
||||
@@ -14,7 +14,7 @@ namespace Cryville.Common.Pdt {
|
||||
/// Indicates that the attributed member is a property list.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>A property list is a <see cref="System.Collections.IDictionary" /> or <see cref="Cryville.Common.Collections.Generic.IPairList" /> that represents a collection of PDT properties. There must be at most one property list in a class.</para>
|
||||
/// <para>A property list is a <see cref="System.Collections.IDictionary" /> or <see cref="Cryville.Common.Collections.IPairList" /> that represents a collection of PDT properties. There must be at most one property list in a class.</para>
|
||||
/// </remarks>
|
||||
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
|
||||
public class PropertyListAttribute : Attribute { }
|
||||
|
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
@@ -17,32 +17,30 @@ namespace Cryville.Common.Pdt {
|
||||
readonly StackFrame[] _stack = new StackFrame[256];
|
||||
readonly byte[] _mem = new byte[0x100000];
|
||||
bool _revokepttconst;
|
||||
LinkedListNode<PdtInstruction> _rip;
|
||||
/// <summary>
|
||||
/// Evaluates an expression and passes the result to a target operator.
|
||||
/// </summary>
|
||||
/// <param name="target">The target operator.</param>
|
||||
/// <param name="exp">The expression to evaluate.</param>
|
||||
public void Evaluate(PdtOperator target, PdtExpression exp) {
|
||||
_framecount = 0;
|
||||
_goffset = 0;
|
||||
_revokepttconst = false;
|
||||
for (_rip = exp.Instructions.First; _rip != null; _rip = _rip.Next)
|
||||
_rip.Value.Execute(this);
|
||||
Operate(target, _framecount, true);
|
||||
if (exp.IsPotentialConstant) {
|
||||
exp.IsConstant = exp.IsPotentialConstant = !_revokepttconst;
|
||||
/// <returns>Whether the evaluaton succeeded.</returns>
|
||||
public bool Evaluate(PdtOperator target, PdtExpression exp) {
|
||||
var prevFrameCount = _framecount;
|
||||
try {
|
||||
_revokepttconst = false;
|
||||
for (var ip = exp.Instructions.First; ip != null; ip = ip.Next)
|
||||
ip.Value.Execute(this, ref ip);
|
||||
if (exp.IsPotentialConstant) {
|
||||
exp.IsConstant = exp.IsPotentialConstant = !_revokepttconst;
|
||||
}
|
||||
var ret = Operate(target, _framecount - prevFrameCount, true);
|
||||
return ret;
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new EvaluationFailureException(exp, ex);
|
||||
}
|
||||
finally {
|
||||
for (var i = prevFrameCount; i < _framecount; i++) DiscardStack();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Patches an expression with a lefthand variable and a compound operator.
|
||||
/// </summary>
|
||||
/// <param name="target">The name of the lefthand variable.</param>
|
||||
/// <param name="op">The name of the compound operator.</param>
|
||||
/// <param name="exp">The expression.</param>
|
||||
public void PatchCompound(int target, int op, PdtExpression exp) {
|
||||
exp.Instructions.AddFirst(new PdtInstruction.PushVariable(target));
|
||||
exp.Instructions.AddLast(new PdtInstruction.Operate(op, 2));
|
||||
}
|
||||
/// <summary>
|
||||
/// Optimizes an expression by merging its instructions.
|
||||
@@ -54,12 +52,14 @@ namespace Cryville.Common.Pdt {
|
||||
List<PdtInstruction.Collapse> ct;
|
||||
var cols = new Dictionary<LinkedListNode<PdtInstruction>, List<PdtInstruction.Collapse>>();
|
||||
var il = exp.Instructions;
|
||||
for (_rip = il.First; _rip != null; _rip = _rip == null ? il.First : _rip.Next) {
|
||||
var i = _rip.Value;
|
||||
var ip = il.First;
|
||||
while (ip != null) {
|
||||
bool nextFlag = false;
|
||||
var i = ip.Value;
|
||||
if (i is PdtInstruction.Operate) {
|
||||
int fc0 = _framecount;
|
||||
int fc1 = ((PdtInstruction.Operate)i).Signature.ParamCount;
|
||||
try { i.Execute(this); } catch (Exception) { }
|
||||
try { i.Execute(this, ref ip); } catch (Exception) { }
|
||||
if (fc0 - _framecount == fc1) {
|
||||
unsafe {
|
||||
fixed (StackFrame* frame = &_stack[_framecount++]) {
|
||||
@@ -71,29 +71,38 @@ namespace Cryville.Common.Pdt {
|
||||
}
|
||||
else {
|
||||
var frame = _stack[_framecount - 1];
|
||||
_rip = il.AddAfter(_rip, new PdtInstruction.PushConstant(frame.Type, _mem, frame.Offset, frame.Length));
|
||||
for (var j = 0; j <= fc1; j++) il.Remove(_rip.Previous);
|
||||
if (frame.Type != PdtInternalType.Error) {
|
||||
ReplaceIP(il, ref ip, new PdtInstruction.PushConstant(frame.Type, _mem, frame.Offset, frame.Length), cols);
|
||||
for (var j = 0; j < fc1; j++) il.Remove(ip.Previous);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (i is PdtInstruction.Collapse) {
|
||||
var t = (PdtInstruction.Collapse)i;
|
||||
try {
|
||||
var pins = _rip;
|
||||
i.Execute(this);
|
||||
if (_rip == pins) {
|
||||
_rip = _rip.Next;
|
||||
il.Remove(_rip.Previous);
|
||||
il.Remove(_rip.Previous);
|
||||
_rip = _rip.Previous;
|
||||
var pins = ip;
|
||||
i.Execute(this, ref ip);
|
||||
if (_stack[_framecount - 1].Type == PdtInternalType.Error) {
|
||||
throw new EvaluationFailureException();
|
||||
}
|
||||
if (ip == pins) {
|
||||
ip = ip.Next;
|
||||
il.Remove(ip.Previous);
|
||||
il.Remove(ip.Previous);
|
||||
ip = ip.Previous;
|
||||
if (ip == null) {
|
||||
ip = il.First;
|
||||
nextFlag = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
_rip = pins.Previous;
|
||||
while (_rip.Next != t.Target) il.Remove(_rip.Next);
|
||||
il.Remove(_rip.Next);
|
||||
ip = pins.Previous;
|
||||
while (ip.Next != t.Target) il.Remove(ip.Next);
|
||||
il.Remove(ip.Next);
|
||||
if (cols.TryGetValue(t.Target, out ct)) {
|
||||
foreach (var u in ct) u.Target = _rip;
|
||||
foreach (var u in ct) u.Target = ip;
|
||||
cols.Remove(t.Target);
|
||||
cols.Add(_rip, ct);
|
||||
cols.Add(ip, ct);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -103,15 +112,14 @@ namespace Cryville.Common.Pdt {
|
||||
}
|
||||
}
|
||||
else if (i is PdtInstruction.PushVariable) {
|
||||
i.Execute(this);
|
||||
i.Execute(this, ref ip);
|
||||
var frame = _stack[_framecount - 1];
|
||||
if (frame.Type != PdtInternalType.Undefined && frame.Type != PdtInternalType.Error) {
|
||||
_rip = il.AddAfter(_rip, new PdtInstruction.PushConstant(frame.Type, _mem, frame.Offset, frame.Length));
|
||||
il.Remove(_rip.Previous);
|
||||
ReplaceIP(il, ref ip, new PdtInstruction.PushConstant(frame.Type, _mem, frame.Offset, frame.Length), cols);
|
||||
}
|
||||
}
|
||||
else i.Execute(this);
|
||||
if (_rip != null && cols.TryGetValue(_rip, out ct)) {
|
||||
else i.Execute(this, ref ip);
|
||||
if (ip != null && cols.TryGetValue(ip, out ct)) {
|
||||
unsafe {
|
||||
fixed (StackFrame* frame = &_stack[_framecount - 1]) {
|
||||
frame->Type = PdtInternalType.Error;
|
||||
@@ -120,19 +128,24 @@ namespace Cryville.Common.Pdt {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!nextFlag) ip = ip.Next;
|
||||
}
|
||||
exp.IsConstant = true;
|
||||
exp.IsPotentialConstant = true;
|
||||
for (var ins = il.First; ins != null; ins = ins.Next) {
|
||||
if (!(ins.Value is PdtInstruction.PushConstant)) {
|
||||
exp.IsConstant = false;
|
||||
}
|
||||
else if (!(ins.Value is PdtInstruction.PushVariable)) {
|
||||
exp.IsPotentialConstant = false;
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
void ReplaceIP(LinkedList<PdtInstruction> il, ref LinkedListNode<PdtInstruction> ip, PdtInstruction ins, Dictionary<LinkedListNode<PdtInstruction>, List<PdtInstruction.Collapse>> cols) {
|
||||
List<PdtInstruction.Collapse> cins;
|
||||
if (cols.TryGetValue(ip, out cins)) cols.Remove(ip);
|
||||
ip = il.AddAfter(ip, ins);
|
||||
il.Remove(ip.Previous);
|
||||
if (cins != null) cols.Add(ip, cins);
|
||||
}
|
||||
/// <summary>
|
||||
/// Revokes the potential constant mark of the current expression.
|
||||
/// </summary>
|
||||
@@ -184,23 +197,36 @@ namespace Cryville.Common.Pdt {
|
||||
/// <returns>An operator of the specific name.</returns>
|
||||
/// <remarks>The parameter count of the returned operator does not necessarily equal to <paramref name="pc" />.</remarks>
|
||||
protected abstract PdtOperator GetOperator(PdtOperatorSignature sig);
|
||||
unsafe void Operate(PdtOperator op, int pc, bool noset = false) {
|
||||
unsafe bool Operate(PdtOperator op, int pc, bool noset = false) {
|
||||
fixed (byte* pmem = _mem) {
|
||||
op.Begin(this, pc);
|
||||
for (int i = 0; i < pc; i++) {
|
||||
var frame = _stack[--_framecount];
|
||||
if (frame.Type == PdtInternalType.Error) {
|
||||
_framecount -= pc - i - 1;
|
||||
_stack[_framecount++] = new StackFrame { Type = PdtInternalType.Error, Offset = -1, Length = 0 };
|
||||
return false;
|
||||
}
|
||||
op.LoadOperand(new PdtVariableMemory(frame.Type, pmem + frame.Offset, frame.Length));
|
||||
_goffset -= frame.Length;
|
||||
}
|
||||
op.Call(pmem + _goffset, noset);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
internal unsafe void Collapse(int name, LinkedListNode<PdtInstruction> target) {
|
||||
internal unsafe void Collapse(int name, ref LinkedListNode<PdtInstruction> self, LinkedListNode<PdtInstruction> target) {
|
||||
fixed (byte* pmem = _mem) {
|
||||
var frame = _stack[--_framecount];
|
||||
_goffset -= frame.Length;
|
||||
if (frame.Type == PdtInternalType.Error) {
|
||||
_stack[_framecount++] = new StackFrame { Type = PdtInternalType.Error, Offset = -1, Length = 0 };
|
||||
self = target;
|
||||
return;
|
||||
}
|
||||
if (Collapse(name, new PdtVariableMemory(frame.Type, pmem + frame.Offset, frame.Length))) {
|
||||
_framecount++;
|
||||
_rip = target;
|
||||
_goffset += frame.Length;
|
||||
self = target;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -226,7 +252,7 @@ namespace Cryville.Common.Pdt {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The exception that is thrown when the evalution of a <see cref="PdtExpression" /> fails.
|
||||
/// The exception that is thrown when the evaluation of a <see cref="PdtExpression" /> fails.
|
||||
/// </summary>
|
||||
public class EvaluationFailureException : Exception {
|
||||
/// <inheritdoc />
|
||||
@@ -237,5 +263,16 @@ namespace Cryville.Common.Pdt {
|
||||
public EvaluationFailureException(string message, Exception innerException) : base(message, innerException) { }
|
||||
/// <inheritdoc />
|
||||
protected EvaluationFailureException(SerializationInfo info, StreamingContext context) : base(info, context) { }
|
||||
/// <summary>
|
||||
/// Creates an instance of the <see cref="EvaluationFailureException" /> class with the failing expression.
|
||||
/// </summary>
|
||||
/// <param name="exp">The failing expression.</param>
|
||||
public EvaluationFailureException(PdtExpression exp) : base("Evaluation failed for the expression: " + exp.ToString()) { }
|
||||
/// <summary>
|
||||
/// Creates an instance of the <see cref="EvaluationFailureException" /> class with the failing expression and the inner exception.
|
||||
/// </summary>
|
||||
/// <param name="exp">The failing expression.</param>
|
||||
/// <param name="innerException">The inner exception.</param>
|
||||
public EvaluationFailureException(PdtExpression exp, Exception innerException) : base("Evaluation failed for the expression: " + exp.ToString(), innerException) { }
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
@@ -7,6 +7,18 @@ namespace Cryville.Common.Pdt {
|
||||
/// PDT expression.
|
||||
/// </summary>
|
||||
public class PdtExpression {
|
||||
/// <summary>
|
||||
/// The empty expression.
|
||||
/// </summary>
|
||||
public static readonly PdtExpression Empty;
|
||||
static PdtExpression() {
|
||||
var ins = new LinkedList<PdtInstruction>();
|
||||
ins.AddLast(new PdtInstruction.PushConstant(
|
||||
PdtInternalType.Number, BitConverter.GetBytes(1f)
|
||||
));
|
||||
Empty = new PdtExpression(ins);
|
||||
}
|
||||
|
||||
internal LinkedList<PdtInstruction> Instructions;
|
||||
/// <summary>
|
||||
/// Whether the value of this expression is constant.
|
||||
@@ -27,9 +39,19 @@ namespace Cryville.Common.Pdt {
|
||||
}
|
||||
return r;
|
||||
}
|
||||
/// <summary>
|
||||
/// Patches an expression with a lefthand variable and a compound operator.
|
||||
/// </summary>
|
||||
/// <param name="target">The name of the lefthand variable.</param>
|
||||
/// <param name="op">The name of the compound operator.</param>
|
||||
/// <param name="exp">The expression.</param>
|
||||
public static void PatchCompound(int target, int op, PdtExpression exp) {
|
||||
exp.Instructions.AddFirst(new PdtInstruction.PushVariable(target));
|
||||
exp.Instructions.AddLast(new PdtInstruction.Operate(op, 2));
|
||||
}
|
||||
}
|
||||
internal abstract class PdtInstruction {
|
||||
internal abstract void Execute(PdtEvaluatorBase etor);
|
||||
internal abstract void Execute(PdtEvaluatorBase etor, ref LinkedListNode<PdtInstruction> self);
|
||||
public class PushConstant : PdtInstruction {
|
||||
public int Type { get; private set; }
|
||||
public byte[] Value { get; private set; }
|
||||
@@ -42,7 +64,7 @@ namespace Cryville.Common.Pdt {
|
||||
Value = new byte[len];
|
||||
Array.Copy(buffer, offset, Value, 0, len);
|
||||
}
|
||||
internal override void Execute(PdtEvaluatorBase etor) {
|
||||
internal override void Execute(PdtEvaluatorBase etor, ref LinkedListNode<PdtInstruction> self) {
|
||||
etor.PushConstant(Type, Value);
|
||||
}
|
||||
public override string ToString() {
|
||||
@@ -53,12 +75,12 @@ namespace Cryville.Common.Pdt {
|
||||
public int Name { get; private set; }
|
||||
public bool Forced { get; private set; }
|
||||
public PushVariable(int name, bool forced = false) { Name = name; Forced = forced; }
|
||||
public PushVariable(string name, bool forced = false) : this(IdentifierManager.SharedInstance.Request(name)) { Forced = forced; }
|
||||
internal override void Execute(PdtEvaluatorBase etor) {
|
||||
public PushVariable(string name, bool forced = false) : this(IdentifierManager.Shared.Request(name)) { Forced = forced; }
|
||||
internal override void Execute(PdtEvaluatorBase etor, ref LinkedListNode<PdtInstruction> self) {
|
||||
etor.PushVariable(Name, Forced);
|
||||
}
|
||||
public override string ToString() {
|
||||
return string.Format(Forced ? "pushv ?{0}" : "pushv {0}", IdentifierManager.SharedInstance.Retrieve(Name));
|
||||
return string.Format(Forced ? "pushv ?{0}" : "pushv {0}", IdentifierManager.Shared.Retrieve(Name));
|
||||
}
|
||||
}
|
||||
public class Operate : PdtInstruction {
|
||||
@@ -69,7 +91,7 @@ namespace Cryville.Common.Pdt {
|
||||
public Operate(string name, int paramCount) {
|
||||
Signature = new PdtOperatorSignature(name, paramCount);
|
||||
}
|
||||
internal override void Execute(PdtEvaluatorBase etor) {
|
||||
internal override void Execute(PdtEvaluatorBase etor, ref LinkedListNode<PdtInstruction> self) {
|
||||
etor.Operate(Signature);
|
||||
}
|
||||
public override string ToString() {
|
||||
@@ -80,14 +102,14 @@ namespace Cryville.Common.Pdt {
|
||||
public int Name { get; private set; }
|
||||
public LinkedListNode<PdtInstruction> Target { get; internal set; }
|
||||
public Collapse(string name, LinkedListNode<PdtInstruction> target) {
|
||||
Name = IdentifierManager.SharedInstance.Request(name);
|
||||
Name = IdentifierManager.Shared.Request(name);
|
||||
Target = target;
|
||||
}
|
||||
internal override void Execute(PdtEvaluatorBase etor) {
|
||||
etor.Collapse(Name, Target);
|
||||
internal override void Execute(PdtEvaluatorBase etor, ref LinkedListNode<PdtInstruction> self) {
|
||||
etor.Collapse(Name, ref self, Target);
|
||||
}
|
||||
public override string ToString() {
|
||||
return string.Format("col {0}{{{1}}}", IdentifierManager.SharedInstance.Retrieve(Name), Target.Value);
|
||||
return string.Format("col {0}{{{1}}}", IdentifierManager.Shared.Retrieve(Name), Target.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -115,15 +137,6 @@ namespace Cryville.Common.Pdt {
|
||||
{ '$', -1 },
|
||||
};
|
||||
|
||||
static readonly PdtExpression _emptyexp;
|
||||
static PdtInterpreter() {
|
||||
var ins = new LinkedList<PdtInstruction>();
|
||||
ins.AddLast(new PdtInstruction.PushConstant(
|
||||
PdtInternalType.Number, BitConverter.GetBytes(1f)
|
||||
));
|
||||
_emptyexp = new PdtExpression(ins);
|
||||
}
|
||||
|
||||
PdtExpToken GetToken() {
|
||||
ws();
|
||||
var result = new PdtExpToken {
|
||||
@@ -195,7 +208,7 @@ namespace Cryville.Common.Pdt {
|
||||
default: pc++; break;
|
||||
}
|
||||
}
|
||||
else if (OP_TYPE[t2.Value[0]] == 1) {
|
||||
if (OP_TYPE[t2.Value[0]] == 1) {
|
||||
colp = new Dictionary<LinkedListNode<PdtInstruction>, string> { { ins.Last, t2.Value } };
|
||||
}
|
||||
t1 = t2;
|
||||
|
59
Assets/Cryville/Common/Pdt/PdtFragmentInterpreter.cs
Normal file
59
Assets/Cryville/Common/Pdt/PdtFragmentInterpreter.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Cryville.Common.Pdt {
|
||||
/// <summary>
|
||||
/// Interpreter for fragments in Property Definition Tree (PDT) file format.
|
||||
/// </summary>
|
||||
public class PdtFragmentInterpreter : PdtInterpreter {
|
||||
public PdtFragmentInterpreter() : base(null, new EmptyBinder()) { }
|
||||
|
||||
/// <summary>
|
||||
/// Sets the new source string for the fragment interpreter and resets the position.
|
||||
/// </summary>
|
||||
/// <param name="value">The new source string.</param>
|
||||
public void SetSource(string value) {
|
||||
Source = value;
|
||||
Position = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The binder.
|
||||
/// </summary>
|
||||
public Binder Binder {
|
||||
get { return _binder; }
|
||||
set { _binder = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads the current character and increments the position.
|
||||
/// </summary>
|
||||
/// <returns>The current character.</returns>
|
||||
/// <exception cref="IndexOutOfRangeException">The end of the source string is reached.</exception>
|
||||
public new char GetChar() { return base.GetChar(); }
|
||||
/// <summary>
|
||||
/// Reads an identifier.
|
||||
/// </summary>
|
||||
/// <returns>An identifier.</returns>
|
||||
/// <exception cref="IndexOutOfRangeException">The end of the source string is reached.</exception>
|
||||
public new string GetIdentifier() { return base.GetIdentifier(); }
|
||||
/// <summary>
|
||||
/// Reads a number.
|
||||
/// </summary>
|
||||
/// <returns>A number.</returns>
|
||||
/// <exception cref="IndexOutOfRangeException">The end of the source string is reached.</exception>
|
||||
public new string GetNumber() { return base.GetNumber(); }
|
||||
/// <summary>
|
||||
/// Reads a string.
|
||||
/// </summary>
|
||||
/// <returns>A string.</returns>
|
||||
/// <exception cref="IndexOutOfRangeException">The end of the source string is reached.</exception>
|
||||
public new string GetString() { return base.GetString(); }
|
||||
/// <summary>
|
||||
/// Reads an expression.
|
||||
/// </summary>
|
||||
/// <returns>An expression.</returns>
|
||||
/// <exception cref="IndexOutOfRangeException">The end of the source string is reached.</exception>
|
||||
public new PdtExpression GetExp() { return base.GetExp(); }
|
||||
}
|
||||
}
|
11
Assets/Cryville/Common/Pdt/PdtFragmentInterpreter.cs.meta
Normal file
11
Assets/Cryville/Common/Pdt/PdtFragmentInterpreter.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f7088ba23ed4b424eadaf664be48e376
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,4 +1,4 @@
|
||||
namespace Cryville.Common.Pdt {
|
||||
namespace Cryville.Common.Pdt {
|
||||
/// <summary>
|
||||
/// The identifiers of the internal types of PDT.
|
||||
/// </summary>
|
||||
|
@@ -1,10 +1,12 @@
|
||||
using Cryville.Common.Collections;
|
||||
using Cryville.Common.Collections;
|
||||
using Cryville.Common.Logging;
|
||||
using Cryville.Common.Reflection;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text.RegularExpressions;
|
||||
using CMath = System.Math;
|
||||
|
||||
namespace Cryville.Common.Pdt {
|
||||
/// <summary>
|
||||
@@ -61,12 +63,12 @@ namespace Cryville.Common.Pdt {
|
||||
/// <summary>
|
||||
/// The source string.
|
||||
/// </summary>
|
||||
public string Source { get; private set; }
|
||||
Binder _binder;
|
||||
public string Source { get; protected set; }
|
||||
protected Binder _binder;
|
||||
/// <summary>
|
||||
/// The current position in the string being parsed by the interpreter.
|
||||
/// </summary>
|
||||
public int Position { get; private set; }
|
||||
public int Position { get; protected set; }
|
||||
#pragma warning disable IDE1006
|
||||
/// <summary>
|
||||
/// The character at the current position.
|
||||
@@ -228,8 +230,8 @@ namespace Cryville.Common.Pdt {
|
||||
if (!flag) throw new FormatException("Format directive not found");
|
||||
}
|
||||
object InterpretObject(Type type) {
|
||||
var result = ReflectionHelper.InvokeEmptyConstructor(type);
|
||||
bool dictflag = typeof(IDictionary).IsAssignableFrom(type);
|
||||
var result = Activator.CreateInstance(type);
|
||||
bool pcflag = PairCollection.IsPairCollection(type);
|
||||
while (true) {
|
||||
try { ws(); }
|
||||
catch (IndexOutOfRangeException) { return result; }
|
||||
@@ -241,69 +243,54 @@ namespace Cryville.Common.Pdt {
|
||||
char c = GetChar();
|
||||
switch (c) {
|
||||
case '{':
|
||||
if (dictflag) {
|
||||
var ktype = type.GetGenericArguments()[0];
|
||||
var ptype = type.GetGenericArguments()[1];
|
||||
object key = _binder.ChangeType(pkey, ktype, null);
|
||||
object value = InterpretObject(ptype);
|
||||
((IDictionary)result).Add(key, value);
|
||||
}
|
||||
else {
|
||||
MemberInfo prop = null;
|
||||
bool flag = false;
|
||||
if (pkey is string) prop = ReflectionHelper.GetMember(type, (string)pkey);
|
||||
if (prop == null) flag = ReflectionHelper.TryFindMemberWithAttribute<ElementListAttribute>(type, out prop);
|
||||
if (prop == null) throw new MissingMemberException(string.Format("The property \"{0}\" is not found", pkey));
|
||||
Type ptype = ReflectionHelper.GetMemberType(prop);
|
||||
if (flag) {
|
||||
using (var collection = new PairCollection(ReflectionHelper.GetValue(prop, result))) {
|
||||
var ktype = ptype.GetGenericArguments()[0];
|
||||
var vtype = ptype.GetGenericArguments()[1];
|
||||
object key = _binder.ChangeType(pkey, ktype, null);
|
||||
object value = InterpretObject(vtype);
|
||||
collection.Add(key, value);
|
||||
}
|
||||
}
|
||||
else ReflectionHelper.SetValue(prop, result, InterpretObject(ptype));
|
||||
}
|
||||
InterpretObjectInternal<ElementListAttribute>(pcflag, type, pkey, result, type => InterpretObject(type));
|
||||
break;
|
||||
case ':':
|
||||
case ';':
|
||||
var exp = c == ';' ? _emptyexp : GetExp();
|
||||
if (dictflag) {
|
||||
var ktype = type.GetGenericArguments()[0];
|
||||
var vtype = type.GetGenericArguments()[1];
|
||||
object key = _binder.ChangeType(pkey, ktype, null);
|
||||
object value = _binder.ChangeType(exp, vtype, null);
|
||||
((IDictionary)result).Add(key, value);
|
||||
}
|
||||
else {
|
||||
MemberInfo prop = null;
|
||||
bool flag = false;
|
||||
if (pkey is string) prop = ReflectionHelper.GetMember(type, (string)pkey);
|
||||
if (prop == null) flag = ReflectionHelper.TryFindMemberWithAttribute<PropertyListAttribute>(type, out prop);
|
||||
if (prop == null) throw new MissingMemberException(string.Format("The property \"{0}\" is not found", pkey));
|
||||
var ptype = ReflectionHelper.GetMemberType(prop);
|
||||
if (flag) {
|
||||
using (var collection = new PairCollection(ReflectionHelper.GetValue(prop, result))) {
|
||||
var ktype = ptype.GetGenericArguments()[0];
|
||||
var vtype = ptype.GetGenericArguments()[1];
|
||||
object key = _binder.ChangeType(pkey, ktype, null);
|
||||
object value = _binder.ChangeType(exp, vtype, null);
|
||||
collection.Add(key, value);
|
||||
}
|
||||
}
|
||||
else {
|
||||
object value = _binder.ChangeType(exp, ptype, null);
|
||||
ReflectionHelper.SetValue(prop, result, value, _binder);
|
||||
}
|
||||
}
|
||||
var exp = c == ';' ? PdtExpression.Empty : GetExp();
|
||||
InterpretObjectInternal<PropertyListAttribute>(pcflag, type, pkey, result, type => _binder.ChangeType(exp, type, null));
|
||||
break;
|
||||
default:
|
||||
throw new InvalidOperationException("Internal error: Invalid key interpretation");
|
||||
}
|
||||
}
|
||||
}
|
||||
void InterpretObjectInternal<T>(bool pcflag, Type type, object pkey, object result, Func<Type, object> vfunc) where T : Attribute {
|
||||
if (pcflag) {
|
||||
using (var collection = new PairCollection(result)) {
|
||||
var ktype = type.GetGenericArguments()[0];
|
||||
var ptype = type.GetGenericArguments()[1];
|
||||
object key = _binder.ChangeType(pkey, ktype, null);
|
||||
object value = vfunc(ptype);
|
||||
collection.Add(key, value);
|
||||
}
|
||||
}
|
||||
else {
|
||||
MemberInfo prop = null;
|
||||
bool flag = false;
|
||||
if (pkey is string) prop = FieldLikeHelper.GetMember(type, (string)pkey);
|
||||
if (prop == null) {
|
||||
prop = FieldLikeHelper.FindMemberWithAttribute<T>(type);
|
||||
flag = true;
|
||||
}
|
||||
if (prop == null) throw new MissingMemberException(string.Format("The property \"{0}\" is not found", pkey));
|
||||
Type ptype = FieldLikeHelper.GetMemberType(prop);
|
||||
if (flag) {
|
||||
var origCollection = FieldLikeHelper.GetValue(prop, result);
|
||||
if (origCollection == null) {
|
||||
FieldLikeHelper.SetValue(prop, result, origCollection = Activator.CreateInstance(ptype));
|
||||
}
|
||||
using (var collection = new PairCollection(origCollection)) {
|
||||
var ktype = ptype.GetGenericArguments()[0];
|
||||
var vtype = ptype.GetGenericArguments()[1];
|
||||
object key = _binder.ChangeType(pkey, ktype, null);
|
||||
object value = vfunc(vtype);
|
||||
collection.Add(key, value);
|
||||
}
|
||||
}
|
||||
else FieldLikeHelper.SetValue(prop, result, vfunc(ptype), _binder);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Interprets a key from the current position.
|
||||
/// </summary>
|
||||
@@ -324,13 +311,13 @@ namespace Cryville.Common.Pdt {
|
||||
int pos = interpreter.Position;
|
||||
if (pos >= src.Length) return "Failed to interpret the PDT: There are some missing or redundant tokens";
|
||||
int lineStartPos = src.LastIndexOf('\n', pos) + 1;
|
||||
int previewStartPos = src.LastIndexOf('\n', pos, 64);
|
||||
int previewStartPos = src.LastIndexOf('\n', pos, CMath.Min(64, pos));
|
||||
if (previewStartPos == -1) {
|
||||
previewStartPos = pos - 64;
|
||||
if (previewStartPos < 0) previewStartPos = 0;
|
||||
}
|
||||
else previewStartPos++;
|
||||
int previewEndPos = src.IndexOf('\n', pos, 64);
|
||||
int previewEndPos = src.IndexOf('\n', pos, CMath.Min(64, src.Length - pos));
|
||||
if (previewEndPos == -1) {
|
||||
previewEndPos = pos + 64;
|
||||
if (previewEndPos > src.Length) previewEndPos = src.Length;
|
||||
|
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
|
||||
namespace Cryville.Common.Pdt {
|
||||
/// <summary>
|
||||
@@ -91,7 +91,7 @@ namespace Cryville.Common.Pdt {
|
||||
/// <param name="name">The name of the operator.</param>
|
||||
/// <param name="paramCount">The parameter count.</param>
|
||||
public PdtOperatorSignature(string name, int paramCount)
|
||||
: this(IdentifierManager.SharedInstance.Request(name), paramCount) { }
|
||||
: this(IdentifierManager.Shared.Request(name), paramCount) { }
|
||||
/// <summary>
|
||||
/// Creates an operator signature.
|
||||
/// </summary>
|
||||
@@ -113,7 +113,7 @@ namespace Cryville.Common.Pdt {
|
||||
return _hash;
|
||||
}
|
||||
public override string ToString() {
|
||||
return string.Format("{0}({1})", IdentifierManager.SharedInstance.Retrieve(Name), ParamCount);
|
||||
return string.Format("{0}({1})", IdentifierManager.Shared.Retrieve(Name), ParamCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using UnsafeIL;
|
||||
|
||||
namespace Cryville.Common.Pdt {
|
||||
|
@@ -1,186 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Cryville.Common {
|
||||
/// <summary>
|
||||
/// Provides a set of <see langword="static" /> methods for refletion.
|
||||
/// </summary>
|
||||
public static class ReflectionHelper {
|
||||
static readonly Type[] emptyTypeArray = {};
|
||||
/// <summary>
|
||||
/// Gets the parameterless constructor of a type.
|
||||
/// </summary>
|
||||
/// <param name="type">The type.</param>
|
||||
/// <returns>The parameterless constructor of the type.</returns>
|
||||
public static ConstructorInfo GetEmptyConstructor(Type type) {
|
||||
return type.GetConstructor(emptyTypeArray);
|
||||
}
|
||||
static readonly object[] emptyObjectArray = {};
|
||||
/// <summary>
|
||||
/// Invokes the parameterless constructor of a type and returns the result.
|
||||
/// </summary>
|
||||
/// <param name="type">The type.</param>
|
||||
/// <returns>The created instance.</returns>
|
||||
public static object InvokeEmptyConstructor(Type type) {
|
||||
return GetEmptyConstructor(type).Invoke(emptyObjectArray);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to find a member with the specified attribute type in a type.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The attribute type.</typeparam>
|
||||
/// <param name="t">The type containing the member with the specified attribute type.</param>
|
||||
/// <param name="mi">The member.</param>
|
||||
/// <returns>Whether the member is found.</returns>
|
||||
public static bool TryFindMemberWithAttribute<T>(Type t, out MemberInfo mi) where T : Attribute {
|
||||
try {
|
||||
mi = FindMemberWithAttribute<T>(t);
|
||||
return true;
|
||||
}
|
||||
catch (MissingMemberException) {
|
||||
mi = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Finds a member with the specified attribute type in a type.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The attribute type.</typeparam>
|
||||
/// <param name="type">The type containing the member with the specified attribute type.</param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="MissingMemberException">The member is not found or multiple members are found.</exception>
|
||||
public static MemberInfo FindMemberWithAttribute<T>(Type type) where T : Attribute {
|
||||
var mil = type.FindMembers(
|
||||
MemberTypes.Field | MemberTypes.Property,
|
||||
BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static,
|
||||
(m, o) => m.GetCustomAttributes(typeof(T), true).Length != 0,
|
||||
null
|
||||
);
|
||||
if (mil.Length != 1)
|
||||
throw new MissingMemberException(type.Name, typeof(T).Name);
|
||||
return mil[0];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether a type is a <see cref="Dictionary{TKey, TValue}" />.
|
||||
/// </summary>
|
||||
/// <param name="type">The type.</param>
|
||||
/// <returns>Whether the type is a <see cref="Dictionary{TKey, TValue}" />.</returns>
|
||||
public static bool IsGenericDictionary(Type type) {
|
||||
return type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Dictionary<,>);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the member from a type with the specified name.
|
||||
/// </summary>
|
||||
/// <param name="type">The type.</param>
|
||||
/// <param name="name">The name of the member.</param>
|
||||
/// <returns>The member.</returns>
|
||||
/// <exception cref="MissingMemberException">The member is not found or multiple members are found.</exception>
|
||||
public static MemberInfo GetMember(Type type, string name) {
|
||||
var mil = type.GetMember(
|
||||
name,
|
||||
MemberTypes.Field | MemberTypes.Property,
|
||||
BindingFlags.Public | BindingFlags.Instance
|
||||
);
|
||||
if (mil.Length != 1)
|
||||
throw new MissingMemberException(type.Name, name);
|
||||
return mil[0];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type of a member.
|
||||
/// </summary>
|
||||
/// <param name="mi">The member.</param>
|
||||
/// <returns>The type of the member.</returns>
|
||||
/// <exception cref="ArgumentException"><paramref name="mi" /> is not a field or a property.</exception>
|
||||
public static Type GetMemberType(MemberInfo mi) {
|
||||
if (mi is FieldInfo)
|
||||
return ((FieldInfo)mi).FieldType;
|
||||
if (mi is PropertyInfo)
|
||||
return ((PropertyInfo)mi).PropertyType;
|
||||
else
|
||||
throw new ArgumentException("Member is not field or property.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of a member of an object.
|
||||
/// </summary>
|
||||
/// <param name="mi">The member.</param>
|
||||
/// <param name="obj">The object.</param>
|
||||
/// <returns>The value.</returns>
|
||||
/// <exception cref="ArgumentException"><paramref name="mi" /> is not a field or a property.</exception>
|
||||
public static object GetValue(MemberInfo mi, object obj) {
|
||||
if (mi is FieldInfo)
|
||||
return ((FieldInfo)mi).GetValue(obj);
|
||||
else if (mi is PropertyInfo)
|
||||
return ((PropertyInfo)mi).GetValue(obj, new object[]{});
|
||||
else
|
||||
throw new ArgumentException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the value of a member of an object.
|
||||
/// </summary>
|
||||
/// <param name="mi">The member.</param>
|
||||
/// <param name="obj">The object.</param>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <param name="binder">An optional binder to convert the value.</param>
|
||||
/// <exception cref="ArgumentException"><paramref name="mi" /> is not a field or a property.</exception>
|
||||
public static void SetValue(MemberInfo mi, object obj, object value, Binder binder = null) {
|
||||
if (mi is FieldInfo)
|
||||
((FieldInfo)mi).SetValue(obj, value, BindingFlags.Default, binder, null);
|
||||
else if (mi is PropertyInfo)
|
||||
((PropertyInfo)mi).SetValue(obj, value, BindingFlags.Default, binder, emptyObjectArray, null);
|
||||
else
|
||||
throw new ArgumentException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all the subclasses of a type in the current app domain.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type.</typeparam>
|
||||
/// <returns>An array containing all the subclasses of the type in the current app domain.</returns>
|
||||
public static Type[] GetSubclassesOf<T>() where T : class {
|
||||
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
|
||||
IEnumerable<Type> r = Enumerable.Empty<Type>();
|
||||
foreach (var a in assemblies)
|
||||
r = r.Concat(a.GetTypes().Where(
|
||||
t => t.IsClass
|
||||
&& !t.IsAbstract
|
||||
&& t.IsSubclassOf(typeof(T))
|
||||
));
|
||||
return r.ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a simple name of a type.
|
||||
/// </summary>
|
||||
/// <param name="type">The type.</param>
|
||||
/// <returns>A simple name of the class.</returns>
|
||||
public static string GetSimpleName(Type type) {
|
||||
string result = type.Name;
|
||||
var typeargs = type.GetGenericArguments();
|
||||
if (typeargs.Length > 0) {
|
||||
result = string.Format("{0}[{1}]", result, string.Join(",", from a in typeargs select GetSimpleName(a)));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the namespace qualified name of a type.
|
||||
/// </summary>
|
||||
/// <param name="type">The type.</param>
|
||||
/// <returns>The namespace qualified name of the class.</returns>
|
||||
public static string GetNamespaceQualifiedName(Type type) {
|
||||
string result = type.Namespace + "." + type.Name;
|
||||
var typeargs = type.GetGenericArguments();
|
||||
if (typeargs.Length > 0) {
|
||||
result = string.Format("{0}[{1}]", result, string.Join(",", from a in typeargs select GetNamespaceQualifiedName(a)));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,12 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 16857d076fc8d534788424e6c6d180e0
|
||||
timeCreated: 1608801352
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Cryville.Common.Unity {
|
||||
|
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
|
@@ -1,109 +0,0 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Cryville.Common.Unity.Input {
|
||||
public delegate void InputEventDelegate(InputIdentifier id, InputVector vec);
|
||||
public abstract class InputHandler : IDisposable {
|
||||
InputEventDelegate m_onInput;
|
||||
public event InputEventDelegate OnInput {
|
||||
add {
|
||||
if (m_onInput == null) Activate();
|
||||
m_onInput -= value;
|
||||
m_onInput += value;
|
||||
}
|
||||
remove {
|
||||
if (m_onInput == null) return;
|
||||
m_onInput -= value;
|
||||
if (m_onInput == null) Deactivate();
|
||||
}
|
||||
}
|
||||
|
||||
~InputHandler() {
|
||||
Dispose(false);
|
||||
}
|
||||
public void Dispose() {
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
protected abstract void Activate();
|
||||
protected abstract void Deactivate();
|
||||
public abstract void Dispose(bool disposing);
|
||||
public abstract bool IsNullable(int type);
|
||||
public abstract byte GetDimension(int type);
|
||||
public abstract string GetTypeName(int type);
|
||||
public abstract double GetCurrentTimestamp();
|
||||
protected void Feed(int type, int id, InputVector vec) {
|
||||
var del = m_onInput;
|
||||
if (del != null) del(new InputIdentifier { Source = new InputSource { Handler = this, Type = type }, Id = id }, vec);
|
||||
}
|
||||
}
|
||||
|
||||
public struct InputSource : IEquatable<InputSource> {
|
||||
public InputHandler Handler { get; set; }
|
||||
public int Type { get; set; }
|
||||
public override bool Equals(object obj) {
|
||||
if (obj == null || !(obj is InputSource)) return false;
|
||||
return Equals((InputSource)obj);
|
||||
}
|
||||
public bool Equals(InputSource other) {
|
||||
return Handler == other.Handler && Type == other.Type;
|
||||
}
|
||||
public override int GetHashCode() {
|
||||
return Handler.GetHashCode() ^ Type;
|
||||
}
|
||||
public override string ToString() {
|
||||
return string.Format("{0}:{1}", ReflectionHelper.GetSimpleName(Handler.GetType()), Handler.GetTypeName(Type));
|
||||
}
|
||||
public static bool operator ==(InputSource lhs, InputSource rhs) {
|
||||
return lhs.Equals(rhs);
|
||||
}
|
||||
public static bool operator !=(InputSource lhs, InputSource rhs) {
|
||||
return !lhs.Equals(rhs);
|
||||
}
|
||||
}
|
||||
|
||||
public struct InputIdentifier : IEquatable<InputIdentifier> {
|
||||
public InputSource Source { get; set; }
|
||||
public int Id { get; set; }
|
||||
public override bool Equals(object obj) {
|
||||
if (obj == null || !(obj is InputIdentifier)) return false;
|
||||
return Equals((InputIdentifier)obj);
|
||||
}
|
||||
public bool Equals(InputIdentifier other) {
|
||||
return Source == other.Source && Id == other.Id;
|
||||
}
|
||||
public override int GetHashCode() {
|
||||
return Source.GetHashCode() ^ ((Id << 16) | (Id >> 16));
|
||||
}
|
||||
public override string ToString() {
|
||||
return string.Format("{0},{1}", Source, Id);
|
||||
}
|
||||
public static bool operator ==(InputIdentifier lhs, InputIdentifier rhs) {
|
||||
return lhs.Equals(rhs);
|
||||
}
|
||||
public static bool operator !=(InputIdentifier lhs, InputIdentifier rhs) {
|
||||
return !lhs.Equals(rhs);
|
||||
}
|
||||
}
|
||||
|
||||
public struct InputVector {
|
||||
public double Time { get; set; }
|
||||
public bool IsNull { get; set; }
|
||||
public Vector3 Vector { get; set; }
|
||||
public InputVector(double time) {
|
||||
Time = time;
|
||||
IsNull = true;
|
||||
Vector = default(Vector3);
|
||||
}
|
||||
public InputVector(double time, Vector3 vector) {
|
||||
Time = time;
|
||||
IsNull = false;
|
||||
Vector = vector;
|
||||
}
|
||||
public override string ToString() {
|
||||
if (IsNull) return string.Format("null@{0}", Time);
|
||||
else return string.Format("{0}@{1}", Vector.ToString("G9"), Time);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 139cf0675329c9d46b902249fecdb500
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,46 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Cryville.Common.Unity.Input {
|
||||
public class InputManager {
|
||||
static readonly HashSet<Type> HandlerRegistries = new HashSet<Type> {
|
||||
typeof(WindowsPointerHandler),
|
||||
typeof(UnityKeyHandler<UnityKeyboardReceiver>),
|
||||
typeof(UnityKeyHandler<UnityMouseButtonReceiver>),
|
||||
typeof(UnityMouseHandler),
|
||||
typeof(UnityTouchHandler),
|
||||
};
|
||||
readonly HashSet<InputHandler> _handlers = new HashSet<InputHandler>();
|
||||
readonly Dictionary<Type, InputHandler> _typemap = new Dictionary<Type, InputHandler>();
|
||||
public InputManager() {
|
||||
foreach (var t in HandlerRegistries) {
|
||||
try {
|
||||
if (!typeof(InputHandler).IsAssignableFrom(t)) continue;
|
||||
var h = (InputHandler)ReflectionHelper.InvokeEmptyConstructor(t);
|
||||
_typemap.Add(t, h);
|
||||
_handlers.Add(h);
|
||||
Logger.Log("main", 1, "Input", "Initialized {0}", ReflectionHelper.GetSimpleName(t));
|
||||
}
|
||||
catch (TargetInvocationException ex) {
|
||||
Logger.Log("main", 1, "Input", "Cannot initialize {0}: {1}", ReflectionHelper.GetSimpleName(t), ex.InnerException.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
public InputHandler GetHandler(string name) {
|
||||
return _typemap[Type.GetType(name)];
|
||||
}
|
||||
public void EnumerateHandlers(Action<InputHandler> cb) {
|
||||
foreach (var h in _handlers) cb(h);
|
||||
}
|
||||
}
|
||||
|
||||
public struct InputEvent {
|
||||
public InputIdentifier Id { get; set; }
|
||||
public InputVector From { get; set; }
|
||||
public InputVector To { get; set; }
|
||||
public override string ToString() {
|
||||
return string.Format("[{0}] {1} -> {2}", Id, From, To);
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,12 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: aaf7daeaf7afb3146b3eea2a07f88055
|
||||
timeCreated: 1611035810
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,528 +0,0 @@
|
||||
namespace Cryville.Common.Unity.Input {
|
||||
public enum WindowMessages : uint {
|
||||
WM_NULL = 0x0000,
|
||||
WM_CREATE = 0x0001,
|
||||
WM_DESTROY = 0x0002,
|
||||
WM_MOVE = 0x0003,
|
||||
WM_SIZE = 0x0005,
|
||||
|
||||
WM_ACTIVATE = 0x0006,
|
||||
/*
|
||||
* WM_ACTIVATE state values
|
||||
*/
|
||||
WA_INACTIVE = 0,
|
||||
WA_ACTIVE = 1,
|
||||
WA_CLICKACTIVE = 2,
|
||||
|
||||
WM_SETFOCUS = 0x0007,
|
||||
WM_KILLFOCUS = 0x0008,
|
||||
WM_ENABLE = 0x000A,
|
||||
WM_SETREDRAW = 0x000B,
|
||||
WM_SETTEXT = 0x000C,
|
||||
WM_GETTEXT = 0x000D,
|
||||
WM_GETTEXTLENGTH = 0x000E,
|
||||
WM_PAINT = 0x000F,
|
||||
WM_CLOSE = 0x0010,
|
||||
//#ifndef _WIN32_WCE
|
||||
WM_QUERYENDSESSION = 0x0011,
|
||||
WM_QUERYOPEN = 0x0013,
|
||||
WM_ENDSESSION = 0x0016,
|
||||
//#endif
|
||||
WM_QUIT = 0x0012,
|
||||
WM_ERASEBKGND = 0x0014,
|
||||
WM_SYSCOLORCHANGE = 0x0015,
|
||||
WM_SHOWWINDOW = 0x0018,
|
||||
WM_WININICHANGE = 0x001A,
|
||||
//#if(WINVER >= 0x0400)
|
||||
WM_SETTINGCHANGE = WM_WININICHANGE,
|
||||
//#endif /* WINVER >= 0x0400 */
|
||||
|
||||
|
||||
WM_DEVMODECHANGE = 0x001B,
|
||||
WM_ACTIVATEAPP = 0x001C,
|
||||
WM_FONTCHANGE = 0x001D,
|
||||
WM_TIMECHANGE = 0x001E,
|
||||
WM_CANCELMODE = 0x001F,
|
||||
WM_SETCURSOR = 0x0020,
|
||||
WM_MOUSEACTIVATE = 0x0021,
|
||||
WM_CHILDACTIVATE = 0x0022,
|
||||
WM_QUEUESYNC = 0x0023,
|
||||
|
||||
WM_GETMINMAXINFO = 0x0024,
|
||||
WM_PAINTICON = 0x0026,
|
||||
WM_ICONERASEBKGND = 0x0027,
|
||||
WM_NEXTDLGCTL = 0x0028,
|
||||
WM_SPOOLERSTATUS = 0x002A,
|
||||
WM_DRAWITEM = 0x002B,
|
||||
WM_MEASUREITEM = 0x002C,
|
||||
WM_DELETEITEM = 0x002D,
|
||||
WM_VKEYTOITEM = 0x002E,
|
||||
WM_CHARTOITEM = 0x002F,
|
||||
WM_SETFONT = 0x0030,
|
||||
WM_GETFONT = 0x0031,
|
||||
WM_SETHOTKEY = 0x0032,
|
||||
WM_GETHOTKEY = 0x0033,
|
||||
WM_QUERYDRAGICON = 0x0037,
|
||||
WM_COMPAREITEM = 0x0039,
|
||||
//#if(WINVER >= 0x0500)
|
||||
//#ifndef _WIN32_WCE
|
||||
WM_GETOBJECT = 0x003D,
|
||||
//#endif
|
||||
//#endif /* WINVER >= 0x0500 */
|
||||
WM_COMPACTING = 0x0041,
|
||||
WM_COMMNOTIFY = 0x0044, /* no longer suported */
|
||||
WM_WINDOWPOSCHANGING = 0x0046,
|
||||
WM_WINDOWPOSCHANGED = 0x0047,
|
||||
|
||||
WM_POWER = 0x0048,
|
||||
/*
|
||||
* wParam for WM_POWER window message and DRV_POWER driver notification
|
||||
*/
|
||||
/*PWR_OK = 1,
|
||||
PWR_FAIL = (-1),
|
||||
PWR_SUSPENDREQUEST = 1,
|
||||
PWR_SUSPENDRESUME = 2,
|
||||
PWR_CRITICALRESUME = 3,*/
|
||||
|
||||
WM_COPYDATA = 0x004A,
|
||||
WM_CANCELJOURNAL = 0x004B,
|
||||
|
||||
|
||||
//#if(WINVER >= 0x0400)
|
||||
WM_NOTIFY = 0x004E,
|
||||
WM_INPUTLANGCHANGEREQUEST = 0x0050,
|
||||
WM_INPUTLANGCHANGE = 0x0051,
|
||||
WM_TCARD = 0x0052,
|
||||
WM_HELP = 0x0053,
|
||||
WM_USERCHANGED = 0x0054,
|
||||
WM_NOTIFYFORMAT = 0x0055,
|
||||
|
||||
NFR_ANSI = 1,
|
||||
NFR_UNICODE = 2,
|
||||
NF_QUERY = 3,
|
||||
NF_REQUERY = 4,
|
||||
|
||||
WM_CONTEXTMENU = 0x007B,
|
||||
WM_STYLECHANGING = 0x007C,
|
||||
WM_STYLECHANGED = 0x007D,
|
||||
WM_DISPLAYCHANGE = 0x007E,
|
||||
WM_GETICON = 0x007F,
|
||||
WM_SETICON = 0x0080,
|
||||
//#endif /* WINVER >= 0x0400 */
|
||||
|
||||
WM_NCCREATE = 0x0081,
|
||||
WM_NCDESTROY = 0x0082,
|
||||
WM_NCCALCSIZE = 0x0083,
|
||||
WM_NCHITTEST = 0x0084,
|
||||
WM_NCPAINT = 0x0085,
|
||||
WM_NCACTIVATE = 0x0086,
|
||||
WM_GETDLGCODE = 0x0087,
|
||||
//#ifndef _WIN32_WCE
|
||||
WM_SYNCPAINT = 0x0088,
|
||||
//#endif
|
||||
WM_NCMOUSEMOVE = 0x00A0,
|
||||
WM_NCLBUTTONDOWN = 0x00A1,
|
||||
WM_NCLBUTTONUP = 0x00A2,
|
||||
WM_NCLBUTTONDBLCLK = 0x00A3,
|
||||
WM_NCRBUTTONDOWN = 0x00A4,
|
||||
WM_NCRBUTTONUP = 0x00A5,
|
||||
WM_NCRBUTTONDBLCLK = 0x00A6,
|
||||
WM_NCMBUTTONDOWN = 0x00A7,
|
||||
WM_NCMBUTTONUP = 0x00A8,
|
||||
WM_NCMBUTTONDBLCLK = 0x00A9,
|
||||
|
||||
|
||||
|
||||
//#if(_WIN32_WINNT >= 0x0500)
|
||||
WM_NCXBUTTONDOWN = 0x00AB,
|
||||
WM_NCXBUTTONUP = 0x00AC,
|
||||
WM_NCXBUTTONDBLCLK = 0x00AD,
|
||||
//#endif /* _WIN32_WINNT >= 0x0500 */
|
||||
|
||||
|
||||
//#if(_WIN32_WINNT >= 0x0501)
|
||||
WM_INPUT_DEVICE_CHANGE = 0x00FE,
|
||||
//#endif /* _WIN32_WINNT >= 0x0501 */
|
||||
|
||||
//#if(_WIN32_WINNT >= 0x0501)
|
||||
WM_INPUT = 0x00FF,
|
||||
//#endif /* _WIN32_WINNT >= 0x0501 */
|
||||
|
||||
WM_KEYFIRST = 0x0100,
|
||||
WM_KEYDOWN = 0x0100,
|
||||
WM_KEYUP = 0x0101,
|
||||
WM_CHAR = 0x0102,
|
||||
WM_DEADCHAR = 0x0103,
|
||||
WM_SYSKEYDOWN = 0x0104,
|
||||
WM_SYSKEYUP = 0x0105,
|
||||
WM_SYSCHAR = 0x0106,
|
||||
WM_SYSDEADCHAR = 0x0107,
|
||||
//#if(_WIN32_WINNT >= 0x0501)
|
||||
WM_UNICHAR = 0x0109,
|
||||
WM_KEYLAST = 0x0109,
|
||||
UNICODE_NOCHAR = 0xFFFF,
|
||||
//#else
|
||||
WM_KEYLAST__WIN2000 = 0x0108,
|
||||
//#endif /* _WIN32_WINNT >= 0x0501 */
|
||||
|
||||
//#if(WINVER >= 0x0400)
|
||||
WM_IME_STARTCOMPOSITION = 0x010D,
|
||||
WM_IME_ENDCOMPOSITION = 0x010E,
|
||||
WM_IME_COMPOSITION = 0x010F,
|
||||
WM_IME_KEYLAST = 0x010F,
|
||||
//#endif /* WINVER >= 0x0400 */
|
||||
|
||||
WM_INITDIALOG = 0x0110,
|
||||
WM_COMMAND = 0x0111,
|
||||
WM_SYSCOMMAND = 0x0112,
|
||||
WM_TIMER = 0x0113,
|
||||
WM_HSCROLL = 0x0114,
|
||||
WM_VSCROLL = 0x0115,
|
||||
WM_INITMENU = 0x0116,
|
||||
WM_INITMENUPOPUP = 0x0117,
|
||||
//#if(WINVER >= 0x0601)
|
||||
WM_GESTURE = 0x0119,
|
||||
WM_GESTURENOTIFY = 0x011A,
|
||||
//#endif /* WINVER >= 0x0601 */
|
||||
WM_MENUSELECT = 0x011F,
|
||||
WM_MENUCHAR = 0x0120,
|
||||
WM_ENTERIDLE = 0x0121,
|
||||
//#if(WINVER >= 0x0500)
|
||||
//#ifndef _WIN32_WCE
|
||||
WM_MENURBUTTONUP = 0x0122,
|
||||
WM_MENUDRAG = 0x0123,
|
||||
WM_MENUGETOBJECT = 0x0124,
|
||||
WM_UNINITMENUPOPUP = 0x0125,
|
||||
WM_MENUCOMMAND = 0x0126,
|
||||
|
||||
//#ifndef _WIN32_WCE
|
||||
//#if(_WIN32_WINNT >= 0x0500)
|
||||
WM_CHANGEUISTATE = 0x0127,
|
||||
WM_UPDATEUISTATE = 0x0128,
|
||||
WM_QUERYUISTATE = 0x0129,
|
||||
|
||||
/*
|
||||
* LOWORD(wParam) values in WM_*UISTATE*
|
||||
*/
|
||||
UIS_SET = 1,
|
||||
UIS_CLEAR = 2,
|
||||
UIS_INITIALIZE = 3,
|
||||
|
||||
/*
|
||||
* HIWORD(wParam) values in WM_*UISTATE*
|
||||
*/
|
||||
UISF_HIDEFOCUS = 0x1,
|
||||
UISF_HIDEACCEL = 0x2,
|
||||
//#if(_WIN32_WINNT >= 0x0501)
|
||||
UISF_ACTIVE = 0x4,
|
||||
//#endif /* _WIN32_WINNT >= 0x0501 */
|
||||
//#endif /* _WIN32_WINNT >= 0x0500 */
|
||||
//#endif
|
||||
|
||||
//#endif
|
||||
//#endif /* WINVER >= 0x0500 */
|
||||
|
||||
WM_CTLCOLORMSGBOX = 0x0132,
|
||||
WM_CTLCOLOREDIT = 0x0133,
|
||||
WM_CTLCOLORLISTBOX = 0x0134,
|
||||
WM_CTLCOLORBTN = 0x0135,
|
||||
WM_CTLCOLORDLG = 0x0136,
|
||||
WM_CTLCOLORSCROLLBAR = 0x0137,
|
||||
WM_CTLCOLORSTATIC = 0x0138,
|
||||
MN_GETHMENU = 0x01E1,
|
||||
|
||||
WM_MOUSEFIRST = 0x0200,
|
||||
WM_MOUSEMOVE = 0x0200,
|
||||
WM_LBUTTONDOWN = 0x0201,
|
||||
WM_LBUTTONUP = 0x0202,
|
||||
WM_LBUTTONDBLCLK = 0x0203,
|
||||
WM_RBUTTONDOWN = 0x0204,
|
||||
WM_RBUTTONUP = 0x0205,
|
||||
WM_RBUTTONDBLCLK = 0x0206,
|
||||
WM_MBUTTONDOWN = 0x0207,
|
||||
WM_MBUTTONUP = 0x0208,
|
||||
WM_MBUTTONDBLCLK = 0x0209,
|
||||
//#if (_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)
|
||||
WM_MOUSEWHEEL = 0x020A,
|
||||
//#endif
|
||||
//#if (_WIN32_WINNT >= 0x0500)
|
||||
WM_XBUTTONDOWN = 0x020B,
|
||||
WM_XBUTTONUP = 0x020C,
|
||||
WM_XBUTTONDBLCLK = 0x020D,
|
||||
//#endif
|
||||
//#if (_WIN32_WINNT >= 0x0600)
|
||||
WM_MOUSEHWHEEL = 0x020E,
|
||||
//#endif
|
||||
|
||||
//#if (_WIN32_WINNT >= 0x0600)
|
||||
WM_MOUSELAST = 0x020E,
|
||||
//#elif (_WIN32_WINNT >= 0x0500)
|
||||
WM_MOUSELAST__WIN2000 = 0x020D,
|
||||
//#elif (_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)
|
||||
WM_MOUSELAST__WIN4 = 0x020A,
|
||||
//#else
|
||||
WM_MOUSELAST__WIN3 = 0x0209,
|
||||
//#endif /* (_WIN32_WINNT >= 0x0600) */
|
||||
|
||||
|
||||
//#if(_WIN32_WINNT >= 0x0400)
|
||||
/* Value for rolling one detent */
|
||||
WHEEL_DELTA = 120,
|
||||
//GET_WHEEL_DELTA_WPARAM(wParam) ((short)HIWORD(wParam))
|
||||
|
||||
/* Setting to scroll one page for SPI_GET/SETWHEELSCROLLLINES */
|
||||
WHEEL_PAGESCROLL = (uint.MaxValue),
|
||||
//#endif /* _WIN32_WINNT >= 0x0400 */
|
||||
|
||||
//#if(_WIN32_WINNT >= 0x0500)
|
||||
//GET_KEYSTATE_WPARAM(wParam) (LOWORD(wParam))
|
||||
//GET_NCHITTEST_WPARAM(wParam) ((short)LOWORD(wParam))
|
||||
//GET_XBUTTON_WPARAM(wParam) (HIWORD(wParam))
|
||||
|
||||
/* XButton values are WORD flags */
|
||||
XBUTTON1 = 0x0001,
|
||||
XBUTTON2 = 0x0002,
|
||||
/* Were there to be an XBUTTON3, its value would be 0x0004 */
|
||||
//#endif /* _WIN32_WINNT >= 0x0500 */
|
||||
|
||||
WM_PARENTNOTIFY = 0x0210,
|
||||
WM_ENTERMENULOOP = 0x0211,
|
||||
WM_EXITMENULOOP = 0x0212,
|
||||
|
||||
//#if(WINVER >= 0x0400)
|
||||
WM_NEXTMENU = 0x0213,
|
||||
WM_SIZING = 0x0214,
|
||||
WM_CAPTURECHANGED = 0x0215,
|
||||
WM_MOVING = 0x0216,
|
||||
WM_POWERBROADCAST = 0x0218,
|
||||
//#endif /* WINVER >= 0x0400 */
|
||||
//#if(WINVER >= 0x0400)
|
||||
WM_DEVICECHANGE = 0x0219,
|
||||
//#endif /* WINVER >= 0x0400 */
|
||||
|
||||
WM_MDICREATE = 0x0220,
|
||||
WM_MDIDESTROY = 0x0221,
|
||||
WM_MDIACTIVATE = 0x0222,
|
||||
WM_MDIRESTORE = 0x0223,
|
||||
WM_MDINEXT = 0x0224,
|
||||
WM_MDIMAXIMIZE = 0x0225,
|
||||
WM_MDITILE = 0x0226,
|
||||
WM_MDICASCADE = 0x0227,
|
||||
WM_MDIICONARRANGE = 0x0228,
|
||||
WM_MDIGETACTIVE = 0x0229,
|
||||
|
||||
|
||||
WM_MDISETMENU = 0x0230,
|
||||
WM_ENTERSIZEMOVE = 0x0231,
|
||||
WM_EXITSIZEMOVE = 0x0232,
|
||||
WM_DROPFILES = 0x0233,
|
||||
WM_MDIREFRESHMENU = 0x0234,
|
||||
|
||||
//#if(WINVER >= 0x0602)
|
||||
WM_POINTERDEVICECHANGE = 0x238,
|
||||
WM_POINTERDEVICEINRANGE = 0x239,
|
||||
WM_POINTERDEVICEOUTOFRANGE = 0x23A,
|
||||
//#endif /* WINVER >= 0x0602 */
|
||||
|
||||
|
||||
//#if(WINVER >= 0x0601)
|
||||
WM_TOUCH = 0x0240,
|
||||
//#endif /* WINVER >= 0x0601 */
|
||||
|
||||
//#if(WINVER >= 0x0602)
|
||||
WM_NCPOINTERUPDATE = 0x0241,
|
||||
WM_NCPOINTERDOWN = 0x0242,
|
||||
WM_NCPOINTERUP = 0x0243,
|
||||
WM_POINTERUPDATE = 0x0245,
|
||||
WM_POINTERDOWN = 0x0246,
|
||||
WM_POINTERUP = 0x0247,
|
||||
WM_POINTERENTER = 0x0249,
|
||||
WM_POINTERLEAVE = 0x024A,
|
||||
WM_POINTERACTIVATE = 0x024B,
|
||||
WM_POINTERCAPTURECHANGED = 0x024C,
|
||||
WM_TOUCHHITTESTING = 0x024D,
|
||||
WM_POINTERWHEEL = 0x024E,
|
||||
WM_POINTERHWHEEL = 0x024F,
|
||||
DM_POINTERHITTEST = 0x0250,
|
||||
WM_POINTERROUTEDTO = 0x0251,
|
||||
WM_POINTERROUTEDAWAY = 0x0252,
|
||||
WM_POINTERROUTEDRELEASED = 0x0253,
|
||||
//#endif /* WINVER >= 0x0602 */
|
||||
|
||||
|
||||
//#if(WINVER >= 0x0400)
|
||||
WM_IME_SETCONTEXT = 0x0281,
|
||||
WM_IME_NOTIFY = 0x0282,
|
||||
WM_IME_CONTROL = 0x0283,
|
||||
WM_IME_COMPOSITIONFULL = 0x0284,
|
||||
WM_IME_SELECT = 0x0285,
|
||||
WM_IME_CHAR = 0x0286,
|
||||
//#endif /* WINVER >= 0x0400 */
|
||||
//#if(WINVER >= 0x0500)
|
||||
WM_IME_REQUEST = 0x0288,
|
||||
//#endif /* WINVER >= 0x0500 */
|
||||
//#if(WINVER >= 0x0400)
|
||||
WM_IME_KEYDOWN = 0x0290,
|
||||
WM_IME_KEYUP = 0x0291,
|
||||
//#endif /* WINVER >= 0x0400 */
|
||||
|
||||
//#if((_WIN32_WINNT >= 0x0400) || (WINVER >= 0x0500))
|
||||
WM_MOUSEHOVER = 0x02A1,
|
||||
WM_MOUSELEAVE = 0x02A3,
|
||||
//#endif
|
||||
//#if(WINVER >= 0x0500)
|
||||
WM_NCMOUSEHOVER = 0x02A0,
|
||||
WM_NCMOUSELEAVE = 0x02A2,
|
||||
//#endif /* WINVER >= 0x0500 */
|
||||
|
||||
//#if(_WIN32_WINNT >= 0x0501)
|
||||
WM_WTSSESSION_CHANGE = 0x02B1,
|
||||
|
||||
WM_TABLET_FIRST = 0x02c0,
|
||||
WM_TABLET_LAST = 0x02df,
|
||||
//#endif /* _WIN32_WINNT >= 0x0501 */
|
||||
|
||||
//#if(WINVER >= 0x0601)
|
||||
WM_DPICHANGED = 0x02E0,
|
||||
//#endif /* WINVER >= 0x0601 */
|
||||
//#if(WINVER >= 0x0605)
|
||||
WM_DPICHANGED_BEFOREPARENT = 0x02E2,
|
||||
WM_DPICHANGED_AFTERPARENT = 0x02E3,
|
||||
WM_GETDPISCALEDSIZE = 0x02E4,
|
||||
//#endif /* WINVER >= 0x0605 */
|
||||
|
||||
|
||||
WM_CUT = 0x0300,
|
||||
WM_COPY = 0x0301,
|
||||
WM_PASTE = 0x0302,
|
||||
WM_CLEAR = 0x0303,
|
||||
WM_UNDO = 0x0304,
|
||||
WM_RENDERFORMAT = 0x0305,
|
||||
WM_RENDERALLFORMATS = 0x0306,
|
||||
WM_DESTROYCLIPBOARD = 0x0307,
|
||||
WM_DRAWCLIPBOARD = 0x0308,
|
||||
WM_PAINTCLIPBOARD = 0x0309,
|
||||
WM_VSCROLLCLIPBOARD = 0x030A,
|
||||
WM_SIZECLIPBOARD = 0x030B,
|
||||
WM_ASKCBFORMATNAME = 0x030C,
|
||||
WM_CHANGECBCHAIN = 0x030D,
|
||||
WM_HSCROLLCLIPBOARD = 0x030E,
|
||||
WM_QUERYNEWPALETTE = 0x030F,
|
||||
WM_PALETTEISCHANGING = 0x0310,
|
||||
WM_PALETTECHANGED = 0x0311,
|
||||
WM_HOTKEY = 0x0312,
|
||||
|
||||
//#if(WINVER >= 0x0400)
|
||||
WM_PRINT = 0x0317,
|
||||
WM_PRINTCLIENT = 0x0318,
|
||||
//#endif /* WINVER >= 0x0400 */
|
||||
|
||||
//#if(_WIN32_WINNT >= 0x0500)
|
||||
WM_APPCOMMAND = 0x0319,
|
||||
//#endif /* _WIN32_WINNT >= 0x0500 */
|
||||
|
||||
//#if(_WIN32_WINNT >= 0x0501)
|
||||
WM_THEMECHANGED = 0x031A,
|
||||
//#endif /* _WIN32_WINNT >= 0x0501 */
|
||||
|
||||
|
||||
//#if(_WIN32_WINNT >= 0x0501)
|
||||
WM_CLIPBOARDUPDATE = 0x031D,
|
||||
//#endif /* _WIN32_WINNT >= 0x0501 */
|
||||
|
||||
//#if(_WIN32_WINNT >= 0x0600)
|
||||
WM_DWMCOMPOSITIONCHANGED = 0x031E,
|
||||
WM_DWMNCRENDERINGCHANGED = 0x031F,
|
||||
WM_DWMCOLORIZATIONCOLORCHANGED= 0x0320,
|
||||
WM_DWMWINDOWMAXIMIZEDCHANGE = 0x0321,
|
||||
//#endif /* _WIN32_WINNT >= 0x0600 */
|
||||
|
||||
//#if(_WIN32_WINNT >= 0x0601)
|
||||
WM_DWMSENDICONICTHUMBNAIL = 0x0323,
|
||||
WM_DWMSENDICONICLIVEPREVIEWBITMAP = 0x0326,
|
||||
//#endif /* _WIN32_WINNT >= 0x0601 */
|
||||
|
||||
|
||||
//#if(WINVER >= 0x0600)
|
||||
WM_GETTITLEBARINFOEX = 0x033F,
|
||||
//#endif /* WINVER >= 0x0600 */
|
||||
|
||||
//#if(WINVER >= 0x0400)
|
||||
//#endif /* WINVER >= 0x0400 */
|
||||
|
||||
|
||||
//#if(WINVER >= 0x0400)
|
||||
WM_HANDHELDFIRST = 0x0358,
|
||||
WM_HANDHELDLAST = 0x035F,
|
||||
|
||||
WM_AFXFIRST = 0x0360,
|
||||
WM_AFXLAST = 0x037F,
|
||||
//#endif /* WINVER >= 0x0400 */
|
||||
|
||||
WM_PENWINFIRST = 0x0380,
|
||||
WM_PENWINLAST = 0x038F,
|
||||
|
||||
|
||||
//#if(WINVER >= 0x0400)
|
||||
WM_APP = 0x8000,
|
||||
//#endif /* WINVER >= 0x0400 */
|
||||
|
||||
|
||||
/*
|
||||
* NOTE: All Message Numbers below 0x0400 are RESERVED.
|
||||
*
|
||||
* Private Window Messages Start Here:
|
||||
*/
|
||||
WM_USER = 0x0400,
|
||||
|
||||
//#if(WINVER >= 0x0400)
|
||||
|
||||
/* wParam for WM_SIZING message */
|
||||
WMSZ_LEFT = 1,
|
||||
WMSZ_RIGHT = 2,
|
||||
WMSZ_TOP = 3,
|
||||
WMSZ_TOPLEFT = 4,
|
||||
WMSZ_TOPRIGHT = 5,
|
||||
WMSZ_BOTTOM = 6,
|
||||
WMSZ_BOTTOMLEFT = 7,
|
||||
WMSZ_BOTTOMRIGHT = 8,
|
||||
//#endif /* WINVER >= 0x0400 */
|
||||
|
||||
//#ifndef NONCMESSAGES
|
||||
|
||||
/*
|
||||
* WM_NCHITTEST and MOUSEHOOKSTRUCT Mouse Position Codes
|
||||
*/
|
||||
/*HTERROR = (-2),
|
||||
HTTRANSPARENT = (-1),
|
||||
HTNOWHERE = 0,
|
||||
HTCLIENT = 1,
|
||||
HTCAPTION = 2,
|
||||
HTSYSMENU = 3,
|
||||
HTGROWBOX = 4,
|
||||
HTSIZE = HTGROWBOX,
|
||||
HTMENU = 5,
|
||||
HTHSCROLL = 6,
|
||||
HTVSCROLL = 7,
|
||||
HTMINBUTTON = 8,
|
||||
HTMAXBUTTON = 9,
|
||||
HTLEFT = 10,
|
||||
HTRIGHT = 11,
|
||||
HTTOP = 12,
|
||||
HTTOPLEFT = 13,
|
||||
HTTOPRIGHT = 14,
|
||||
HTBOTTOM = 15,
|
||||
HTBOTTOMLEFT = 16,
|
||||
HTBOTTOMRIGHT = 17,
|
||||
HTBORDER = 18,
|
||||
HTREDUCE = HTMINBUTTON,
|
||||
HTZOOM = HTMAXBUTTON,
|
||||
HTSIZEFIRST = HTLEFT,
|
||||
HTSIZELAST = HTBOTTOMRIGHT,
|
||||
//#if(WINVER >= 0x0400)
|
||||
HTOBJECT = 19,
|
||||
HTCLOSE = 20,
|
||||
HTHELP = 21,
|
||||
//#endif /* WINVER >= 0x0400 */
|
||||
}
|
||||
}
|
@@ -1,12 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 466300df0840ba54d95240e3a800a642
|
||||
timeCreated: 1611373988
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,252 +0,0 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace Cryville.Common.Unity.Input {
|
||||
static class NativeMethods {
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct MONITORINFO {
|
||||
public int cbSize;
|
||||
public RECT rcMonitor;
|
||||
public RECT rcWork;
|
||||
public uint dwFlags;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct RECT {
|
||||
public int Left, Top, Right, Bottom;
|
||||
|
||||
public RECT(int left, int top, int right, int bottom) {
|
||||
Left = left;
|
||||
Top = top;
|
||||
Right = right;
|
||||
Bottom = bottom;
|
||||
}
|
||||
|
||||
public int X {
|
||||
get { return Left; }
|
||||
set {
|
||||
Right -= (Left - value);
|
||||
Left = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int Y {
|
||||
get { return Top; }
|
||||
set {
|
||||
Bottom -= (Top - value);
|
||||
Top = value;
|
||||
}
|
||||
}
|
||||
|
||||
public int Height {
|
||||
get { return Bottom - Top; }
|
||||
set { Bottom = value + Top; }
|
||||
}
|
||||
|
||||
public int Width {
|
||||
get { return Right - Left; }
|
||||
set { Right = value + Left; }
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool GetTouchInputInfo(IntPtr hTouchInput, int cInputs, [Out] TOUCHINPUT[] pInputs, int cbSize);
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct TOUCHINPUT {
|
||||
public int x;
|
||||
public int y;
|
||||
public IntPtr hSource;
|
||||
public int dwID;
|
||||
public TOUCHINPUT_Flags dwFlags;
|
||||
public TOUCHINPUT_Mask dwMask;
|
||||
public int dwTime;
|
||||
public IntPtr dwExtraInfo;
|
||||
public int cxContact;
|
||||
public int cyContact;
|
||||
}
|
||||
[Flags]
|
||||
public enum TOUCHINPUT_Flags : int {
|
||||
TOUCHEVENTF_MOVE = 0x0001,
|
||||
TOUCHEVENTF_DOWN = 0x0002,
|
||||
TOUCHEVENTF_UP = 0x0004,
|
||||
TOUCHEVENTF_INRANGE = 0x0008,
|
||||
TOUCHEVENTF_PRIMARY = 0x0010,
|
||||
TOUCHEVENTF_NOCOALESCE = 0x0020,
|
||||
TOUCHEVENTF_PEN = 0x0040,
|
||||
TOUCHEVENTF_PALM = 0x0080,
|
||||
}
|
||||
[Flags]
|
||||
public enum TOUCHINPUT_Mask : int {
|
||||
TOUCHINPUTMASKF_CONTACTAREA = 0x0004,
|
||||
TOUCHINPUTMASKF_EXTRAINFO = 0x0002,
|
||||
TOUCHINPUTMASKF_TIMEFROMSYSTEM = 0x0001,
|
||||
}
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool GetPointerInfo(int pointerID, ref POINTER_INFO pPointerInfo);
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct POINTER_INFO {
|
||||
public POINTER_INPUT_TYPE pointerType;
|
||||
public UInt32 pointerId;
|
||||
public UInt32 frameId;
|
||||
public POINTER_FLAGS pointerFlags;
|
||||
public IntPtr sourceDevice;
|
||||
public IntPtr hwndTarget;
|
||||
public POINT ptPixelLocation;
|
||||
public POINT ptHimetricLocation;
|
||||
public POINT ptPixelLocationRaw;
|
||||
public POINT ptHimetricLocationRaw;
|
||||
public UInt32 dwTime;
|
||||
public UInt32 historyCount;
|
||||
public Int32 inputData;
|
||||
public UInt32 dwKeyStates;
|
||||
public UInt64 PerformanceCount;
|
||||
public POINTER_BUTTON_CHANGE_TYPE ButtonChangeType;
|
||||
}
|
||||
public enum POINTER_INPUT_TYPE {
|
||||
PT_POINTER = 0x00000001,
|
||||
PT_TOUCH = 0x00000002,
|
||||
PT_PEN = 0x00000003,
|
||||
PT_MOUSE = 0x00000004,
|
||||
PT_TOUCHPAD = 0x00000005,
|
||||
}
|
||||
[Flags]
|
||||
public enum POINTER_FLAGS {
|
||||
POINTER_FLAG_NONE = 0x00000000,
|
||||
POINTER_FLAG_NEW = 0x00000001,
|
||||
POINTER_FLAG_INRANGE = 0x00000002,
|
||||
POINTER_FLAG_INCONTACT = 0x00000004,
|
||||
POINTER_FLAG_FIRSTBUTTON = 0x00000010,
|
||||
POINTER_FLAG_SECONDBUTTON = 0x00000020,
|
||||
POINTER_FLAG_THIRDBUTTON = 0x00000040,
|
||||
POINTER_FLAG_FOURTHBUTTON = 0x00000080,
|
||||
POINTER_FLAG_FIFTHBUTTON = 0x00000100,
|
||||
POINTER_FLAG_PRIMARY = 0x00002000,
|
||||
POINTER_FLAG_CONFIDENCE = 0x00004000,
|
||||
POINTER_FLAG_CANCELED = 0x00008000,
|
||||
POINTER_FLAG_DOWN = 0x00010000,
|
||||
POINTER_FLAG_UPDATE = 0x00020000,
|
||||
POINTER_FLAG_UP = 0x00040000,
|
||||
POINTER_FLAG_WHEEL = 0x00080000,
|
||||
POINTER_FLAG_HWHEEL = 0x00100000,
|
||||
POINTER_FLAG_CAPTURECHANGED = 0x00200000,
|
||||
POINTER_FLAG_HASTRANSFORM = 0x00400000,
|
||||
}
|
||||
public enum POINTER_BUTTON_CHANGE_TYPE {
|
||||
POINTER_CHANGE_NONE,
|
||||
POINTER_CHANGE_FIRSTBUTTON_DOWN,
|
||||
POINTER_CHANGE_FIRSTBUTTON_UP,
|
||||
POINTER_CHANGE_SECONDBUTTON_DOWN,
|
||||
POINTER_CHANGE_SECONDBUTTON_UP,
|
||||
POINTER_CHANGE_THIRDBUTTON_DOWN,
|
||||
POINTER_CHANGE_THIRDBUTTON_UP,
|
||||
POINTER_CHANGE_FOURTHBUTTON_DOWN,
|
||||
POINTER_CHANGE_FOURTHBUTTON_UP,
|
||||
POINTER_CHANGE_FIFTHBUTTON_DOWN,
|
||||
POINTER_CHANGE_FIFTHBUTTON_UP,
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct POINT {
|
||||
public int X;
|
||||
public int Y;
|
||||
}
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool GetPointerTouchInfo(int pointerId, ref POINTER_TOUCH_INFO touchInfo);
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct POINTER_TOUCH_INFO {
|
||||
public POINTER_INFO pointerInfo;
|
||||
public TOUCH_FLAGS touchFlags;
|
||||
public TOUCH_MASK touchMask;
|
||||
public RECT rcContact;
|
||||
public RECT rcContactRaw;
|
||||
public uint orientation;
|
||||
public uint pressure;
|
||||
}
|
||||
[Flags]
|
||||
public enum TOUCH_FLAGS {
|
||||
TOUCH_FLAG_NONE = 0x00000000,
|
||||
}
|
||||
[Flags]
|
||||
public enum TOUCH_MASK {
|
||||
TOUCH_MASK_NONE = 0x00000000,
|
||||
TOUCH_MASK_CONTACTAREA = 0x00000001,
|
||||
TOUCH_MASK_ORIENTATION = 0x00000002,
|
||||
TOUCH_MASK_PRESSURE = 0x00000004,
|
||||
}
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern IntPtr EnableMouseInPointer(bool value);
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
public static extern uint GetCurrentThreadId();
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
||||
public static extern int GetClassName(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
|
||||
public delegate bool EnumWindowsProc(IntPtr hWnd,IntPtr lParam);
|
||||
[DllImport("user32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool EnumThreadWindows(uint dwThreadId, EnumWindowsProc lpEnumFunc, IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern IntPtr MonitorFromWindow(IntPtr hwnd, uint dwFlags);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern bool GetMonitorInfo(IntPtr hMonitor, ref MONITORINFO lpmi);
|
||||
|
||||
[DllImport("user32.dll", EntryPoint = "SetWindowLong")]
|
||||
public static extern int SetWindowLong32(IntPtr hWnd, int nIndex, int dwNewLong);
|
||||
|
||||
[DllImport("user32.dll", EntryPoint = "SetWindowLongPtr")]
|
||||
public static extern IntPtr SetWindowLongPtr64(IntPtr hWnd, int nIndex, IntPtr dwNewLong);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern IntPtr CallWindowProc(IntPtr lpPrevWndFunc, IntPtr hWnd, uint msg, IntPtr wParam,
|
||||
IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool RegisterTouchWindow(IntPtr hWnd, TOUCH_WINDOW_FLAGS ulFlags);
|
||||
[Flags]
|
||||
public enum TOUCH_WINDOW_FLAGS {
|
||||
TWF_FINETOUCH = 1,
|
||||
TWF_WANTPALM = 2,
|
||||
}
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool UnregisterTouchWindow(IntPtr hWnd);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern void CloseTouchInputHandle(IntPtr lParam);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
public static extern bool ScreenToClient(IntPtr hWnd, ref POINT lpPoint);
|
||||
|
||||
[DllImport("Kernel32.dll", CharSet = CharSet.Unicode)]
|
||||
public static extern ushort GlobalAddAtom(string lpString);
|
||||
|
||||
[DllImport("Kernel32.dll")]
|
||||
public static extern ushort GlobalDeleteAtom(ushort nAtom);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
|
||||
public static extern int SetProp(IntPtr hWnd, string lpString, int hData);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
|
||||
public static extern int RemoveProp(IntPtr hWnd, string lpString);
|
||||
|
||||
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
||||
public static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
public static extern uint QueryPerformanceFrequency(out Int64 lpFrequency);
|
||||
|
||||
[DllImport("kernel32.dll")]
|
||||
public static extern uint QueryPerformanceCounter(out Int64 lpPerformanceCount);
|
||||
}
|
||||
}
|
@@ -1,12 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a6ff72ea2b7f71345aa19940faf026e8
|
||||
timeCreated: 1622589747
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,49 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Cryville.Common.Unity.Input {
|
||||
public class SimpleInputConsumer {
|
||||
readonly InputManager _manager;
|
||||
readonly object _lock = new object();
|
||||
readonly Dictionary<InputIdentifier, InputVector> _vectors = new Dictionary<InputIdentifier, InputVector>();
|
||||
readonly List<InputEvent> _events = new List<InputEvent>();
|
||||
public SimpleInputConsumer(InputManager manager) { _manager = manager; }
|
||||
public void Activate() {
|
||||
lock (_lock) {
|
||||
_events.Clear();
|
||||
}
|
||||
_manager.EnumerateHandlers(h => h.OnInput += OnInput);
|
||||
}
|
||||
public void Deactivate() {
|
||||
_manager.EnumerateHandlers(h => h.OnInput -= OnInput);
|
||||
}
|
||||
protected void OnInput(InputIdentifier id, InputVector vec) {
|
||||
lock (_lock) {
|
||||
InputVector vec0;
|
||||
if (_vectors.TryGetValue(id, out vec0)) {
|
||||
_events.Add(new InputEvent {
|
||||
Id = id,
|
||||
From = vec0,
|
||||
To = vec,
|
||||
});
|
||||
if (vec.IsNull) _vectors.Remove(id);
|
||||
else _vectors[id] = vec;
|
||||
}
|
||||
else {
|
||||
_events.Add(new InputEvent {
|
||||
Id = id,
|
||||
From = new InputVector(vec.Time),
|
||||
To = vec,
|
||||
});
|
||||
_vectors.Add(id, vec);
|
||||
}
|
||||
}
|
||||
}
|
||||
public void EnumerateEvents(Action<InputEvent> cb) {
|
||||
lock (_lock) {
|
||||
foreach (var ev in _events) cb(ev);
|
||||
_events.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8fd2d5f1c7ba0c74c9ce8775075750db
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,12 +0,0 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace Cryville.Common.Unity.Input {
|
||||
public static class UnityCameraUtils {
|
||||
public static Vector2 ScreenToWorldPoint(Vector2 pos) {
|
||||
Vector3 i = pos;
|
||||
i.z = -Camera.main.transform.localPosition.z;
|
||||
i = Camera.main.ScreenToWorldPoint(i);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 35a1c45601c39f94db20178505a68be2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -1,114 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Cryville.Common.Unity.Input {
|
||||
public class UnityKeyHandler<T> : InputHandler where T : UnityKeyReceiver<T> {
|
||||
GameObject receiver;
|
||||
T recvcomp;
|
||||
|
||||
public UnityKeyHandler() { }
|
||||
|
||||
protected override void Activate() {
|
||||
receiver = new GameObject("__keyrecv__");
|
||||
recvcomp = receiver.AddComponent<T>();
|
||||
recvcomp.SetCallback(Feed);
|
||||
}
|
||||
|
||||
protected override void Deactivate() {
|
||||
if (receiver) GameObject.Destroy(receiver);
|
||||
}
|
||||
|
||||
public override void Dispose(bool disposing) {
|
||||
if (disposing) {
|
||||
Deactivate();
|
||||
}
|
||||
}
|
||||
|
||||
public override bool IsNullable(int type) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public override byte GetDimension(int type) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override string GetTypeName(int type) {
|
||||
return recvcomp.GetKeyName(type);
|
||||
}
|
||||
|
||||
public override double GetCurrentTimestamp() {
|
||||
return Time.realtimeSinceStartupAsDouble;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class UnityKeyReceiver<T> : MonoBehaviour where T : UnityKeyReceiver<T> {
|
||||
protected Action<int, int, InputVector> Callback;
|
||||
protected readonly HashSet<int> Keys = new HashSet<int>();
|
||||
public void SetCallback(Action<int, int, InputVector> h) {
|
||||
Callback = h;
|
||||
}
|
||||
public abstract string GetKeyName(int type);
|
||||
void Awake() {
|
||||
useGUILayout = false;
|
||||
}
|
||||
void Update() {
|
||||
double time = Time.realtimeSinceStartupAsDouble;
|
||||
foreach (var k in Keys) {
|
||||
Callback(k, 0, new InputVector(time, Vector3.zero));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class UnityKeyboardReceiver : UnityKeyReceiver<UnityKeyboardReceiver> {
|
||||
public override string GetKeyName(int type) {
|
||||
return Enum.GetName(typeof(KeyCode), type);
|
||||
}
|
||||
void OnGUI() {
|
||||
var e = Event.current;
|
||||
if (e.keyCode == KeyCode.None) return;
|
||||
double time = Time.realtimeSinceStartupAsDouble;
|
||||
var key = (int)e.keyCode;
|
||||
switch (e.type) {
|
||||
case EventType.KeyDown:
|
||||
if (!Keys.Contains(key)) {
|
||||
Callback(key, 0, new InputVector(time, Vector3.zero));
|
||||
Keys.Add(key);
|
||||
}
|
||||
break;
|
||||
case EventType.KeyUp:
|
||||
Keys.Remove(key);
|
||||
Callback(key, 0, new InputVector(time));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class UnityMouseButtonReceiver : UnityKeyReceiver<UnityMouseButtonReceiver> {
|
||||
public override string GetKeyName(int type) {
|
||||
switch (type) {
|
||||
case 0: return "Mouse Left";
|
||||
case 1: return "Mouse Right";
|
||||
case 2: return "Mouse Middle";
|
||||
default: return string.Format("Mouse Button {0}", type);
|
||||
}
|
||||
}
|
||||
void OnGUI() {
|
||||
var e = Event.current;
|
||||
double time = Time.realtimeSinceStartupAsDouble;
|
||||
var key = e.button;
|
||||
switch (e.type) {
|
||||
case EventType.MouseDown:
|
||||
if (!Keys.Contains(key)) {
|
||||
Callback(key, 0, new InputVector(time, Vector3.zero));
|
||||
Keys.Add(key);
|
||||
}
|
||||
break;
|
||||
case EventType.MouseUp:
|
||||
Keys.Remove(key);
|
||||
Callback(key, 0, new InputVector(time));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user