Browse Source

更新到最新的CSharp.lua CoreSystem

tanghai 4 years ago
parent
commit
f4c06d4722
31 changed files with 3582 additions and 1103 deletions
  1. 14 1
      Unity/Assets/Bundles/Lua/CSharpLua/All.lua.txt
  2. 744 78
      Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/Array.lua.txt
  3. 64 47
      Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/Collections/Dictionary.lua.txt
  4. 2 4
      Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/Collections/EqualityComparer.lua.txt
  5. 7 7
      Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/Collections/HashSet.lua.txt
  6. 1 1
      Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/Collections/LinkedList.lua.txt
  7. 4 4
      Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/Collections/Linq.lua.txt
  8. 2 1
      Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/Collections/List.lua.txt
  9. 185 0
      Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/Collections/PriorityQueue.lua.txt
  10. 1 1
      Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/Collections/Queue.lua.txt
  11. 34 839
      Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/Collections/SortedDictionary.lua.txt
  12. 60 0
      Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/Collections/SortedList.lua.txt
  13. 34 3
      Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/Collections/SortedSet.lua.txt
  14. 1 1
      Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/Collections/Stack.lua.txt
  15. 222 14
      Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/Convert.lua.txt
  16. 87 45
      Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/Core.lua.txt
  17. 194 2
      Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/DateTime.lua.txt
  18. 3 3
      Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/Delegate.lua.txt
  19. 44 5
      Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/Exception.lua.txt
  20. 14 7
      Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/Math.lua.txt
  21. 2 2
      Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/Number.lua.txt
  22. 13 7
      Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/Reflection/Assembly.lua.txt
  23. 28 7
      Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/String.lua.txt
  24. 968 0
      Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/Threading/Task.lua
  25. 202 0
      Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/Threading/Thread.lua
  26. 199 0
      Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/Threading/Timer.lua
  27. 6 4
      Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/TimeSpan.lua.txt
  28. 19 18
      Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/Type.lua.txt
  29. 1 1
      Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/Utilities.lua.txt
  30. 426 0
      Unity/Assets/Bundles/Lua/CSharpLua/Sample/test.lua.txt
  31. 1 1
      Unity/Assets/Bundles/Lua/Main.lua.txt

+ 14 - 1
Unity/Assets/Bundles/Lua/CSharpLua/All.lua.txt

@@ -22,6 +22,7 @@ return function(dir, conf)
   load("Core")(conf)
   load("Interfaces")
   load("Exception")
+  load("Math")
   load("Number")
   load("Char")
   load("String")
@@ -39,10 +40,12 @@ return function(dir, conf)
   load("Collections.Stack")
   load("Collections.HashSet")
   load("Collections.LinkedList")
+  load("Collections.SortedSet")
+  load("Collections.SortedList")
   load("Collections.SortedDictionary")
+  load("Collections.PriorityQueue")
   load("Collections.Linq")
   load("Convert")
-  load("Math")
   load("Random")
   load("Text.StringBuilder")
   load("Console")
@@ -52,4 +55,14 @@ return function(dir, conf)
   load("Threading.Thread")
   load("Threading.Task")
   load("Utilities")
+  load("Globalization.Globalization")
+  load("Numerics.HashCodeHelper")
+  load("Numerics.Complex")
+  load("Numerics.Matrix3x2")
+  load("Numerics.Matrix4x4")
+  load("Numerics.Plane")
+  load("Numerics.Quaternion")
+  load("Numerics.Vector2")
+  load("Numerics.Vector3")
+  load("Numerics.Vector4")
 end

File diff suppressed because it is too large
+ 744 - 78
Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/Array.lua.txt


+ 64 - 47
Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/Collections/Dictionary.lua.txt

@@ -23,6 +23,8 @@ local each = System.each
 local lengthFn = System.lengthFn
 local versions = System.versions
 local Array = System.Array
+local toString = System.toString
+
 local checkIndexAndCount = System.checkIndexAndCount
 local throwFailedVersion = System.throwFailedVersion
 local ArgumentNullException = System.ArgumentNullException
@@ -78,29 +80,29 @@ local KeyValuePairFn
 local KeyValuePair = {
   __ctor__ = function (this, ...)
     if select("#", ...) == 0 then
-      this.Key, this.Value = this.__genericTKey__:default(), this.__genericTValue__:default()
+      this[1], this[2] = this.__genericTKey__:default(), this.__genericTValue__:default()
     else
-      this.Key, this.Value = ...
+      this[1], this[2] = ...
     end
   end,
   Create = function (key, value, TKey, TValue)
-    return setmetatable({ Key = key, Value = value }, KeyValuePairFn(TKey, TValue))
+    return setmetatable({ key, value }, KeyValuePairFn(TKey, TValue))
   end,
   Deconstruct = function (this)
-    return this.Key, this.Value
+    return this[1], this[2]
   end,
   ToString = function (this)
     local t = { "[" }
     local count = 2
-    local k, v = this.Key, this.Value
+    local k, v = this[1], this[2]
     if k ~= nil then
-      t[count] = k:ToString()
+      t[count] = toString(k)
       count = count + 1
     end
     t[count] = ", "
     count = count + 1
     if v ~= nil then
-      t[count] = v:ToString()
+      t[count] = toString(v)
       count = count + 1
     end
     t[count] = "]"
@@ -114,7 +116,7 @@ KeyValuePairFn = System.defStc("System.Collections.Generic.KeyValuePair", functi
     __genericTValue__ = TValue,
   }
   return cls
-end, KeyValuePair)
+end, KeyValuePair, 2)
 System.KeyValuePair = KeyValuePairFn
 
 local function isKeyValuePair(t)
@@ -133,9 +135,9 @@ local DictionaryEnumerator = define("System.Collections.Generic.DictionaryEnumer
     local k, v = next(t, this.index)
     if k ~= nil then
       if kind then
-        kind.Key = k
+        kind[1] = k
         if v == null then v = nil end
-        kind.Value = v
+        kind[2] = v
       elseif kind == false then
         if v == null then v = nil end
         this.current = v
@@ -146,7 +148,7 @@ local DictionaryEnumerator = define("System.Collections.Generic.DictionaryEnumer
       return true
     else
       if kind then
-        kind.Key, kind.Value = kind.__genericTKey__:default(), kind.__genericTValue__:default()
+        kind[1], kind[2] = kind.__genericTKey__:default(), kind.__genericTValue__:default()
       elseif kind == false then
         this.current = t.__genericTValue__:default()
       else
@@ -161,7 +163,7 @@ local function dictionaryEnumerator(t, kind)
   local current
   if not kind then
     local TKey, TValue = t.__genericTKey__, t.__genericTValue__
-    kind = setmetatable({ Key = TKey:default(), Value = TValue:default() }, t.__genericT__)
+    kind = setmetatable({ TKey:default(), TValue:default() }, t.__genericT__)
     current = kind
   elseif kind == 1 then
     local TKey = t.__genericTKey__
@@ -198,7 +200,7 @@ local DictionaryCollection = define("System.Collections.Generic.DictionaryCollec
   GetEnumerator = function (this)
     return dictionaryEnumerator(this.dict, this.kind)
   end
-})
+}, 1)
 
 local function add(this, key, value)
   if key == nil then throw(ArgumentNullException("key")) end
@@ -274,7 +276,7 @@ local Dictionary = {
     local k, v
     if select("#", ...) == 1 then
       local pair = ... 
-      k, v = pair.Key, pair.Value
+      k, v = pair[1], pair[2]
     else
       k, v = ...
     end
@@ -311,13 +313,13 @@ local Dictionary = {
     return false
   end,
   Contains = function (this, pair)
-    local key = pair.Key
+    local key = pair[1]
     if key == nil then throw(ArgumentNullException("key")) end
     local value = this[key]
     if value ~= nil then
       if value == null then value = nil end
       local comparer = EqualityComparer(this.__genericTValue__).getDefault()
-      if comparer:EqualsOf(value, pair.Value) then
+      if comparer:EqualsOf(value, pair[2]) then
         return true
       end
     end
@@ -331,7 +333,7 @@ local Dictionary = {
       index = index + 1
       for k, v in pairs(this) do
         if v == null then v = nil end
-        array[index] = setmetatable({ Key = k, Value = v }, KeyValuePair)
+        array[index] = setmetatable({ k, v }, KeyValuePair)
         index = index + 1
       end
     end
@@ -339,7 +341,7 @@ local Dictionary = {
   RemoveKey = remove,
   Remove = function (this, key)
     if isKeyValuePair(key) then
-      local k, v = key.Key, key.Value
+      local k, v = key[1], key[2]
       if k == nil then throw(ArgumentNullException("key")) end
       local value = this[k]
       if value ~= nil then
@@ -413,10 +415,10 @@ end, {
     local index = this.index
     local pair = t[index]
     if pair ~= nil then
-      if t.kind then
-        this.current = pair.Value
+      if this.kind then
+        this.current = pair[2]
       else
-        this.current = pair.Key
+        this.current = pair[1]
       end
       this.index = index + 1
       return true
@@ -424,7 +426,7 @@ end, {
     this.current = nil
     return false
   end
-})
+}, 1)
 
 local arrayDictionaryEnumerator = function (t, kind, T)
   return setmetatable({ list = t, kind = kind, index = 1, version = versions[t], currnet = T:default() }, ArrayDictionaryEnumerator(T))
@@ -441,12 +443,26 @@ local ArrayDictionaryCollection = define("System.Collections.Generic.ArrayDictio
     this.kind = kind
   end,
   getCount = function (this)
-    return getCount(this.dict)
+    return #this.dict
+  end,
+  get = function (this, index)
+    local p = this.dict[index + 1]
+    if p == nil then throw(System.ArgumentOutOfRangeException()) end
+    if this.kind then
+      return p[2]
+    end
+    return p[1]
+  end,
+  Contains = function (this, v)
+    if this.kind then
+      return this.dict:ContainsValue(v)
+    end 
+    return this.dict:ContainsKey(v)
   end,
   GetEnumerator = function (this)
     return arrayDictionaryEnumerator(this.dict, this.kind, this.__genericT__)
   end
-})
+}, 1)
 
 local ArrayDictionary = (function ()
   local function buildFromDictionary(this, dictionary)
@@ -454,11 +470,11 @@ local ArrayDictionary = (function ()
     local count = 1
     local KeyValuePair = this.__genericT__
     for _, pair in each(dictionary) do
-      local k, v = pair.Key, pair.Value
+      local k, v = pair[1], pair[2]
       if type(k) == "table" and k.class == 'S' then
         k = k:__clone__()
       end
-      this[count] = setmetatable({ Key = k, Value = v }, KeyValuePair)
+      this[count] = setmetatable({ k, v }, KeyValuePair)
       count = count + 1
     end
   end 
@@ -470,9 +486,9 @@ local ArrayDictionary = (function ()
       local comparer = this.comparer
       local equals = comparer.EqualsOf
       for i = 1, len do
-        if equals(comparer, this[i].Key, key) then
+        if equals(comparer, this[i][1], key) then
           if set then
-            this[i].Value = value
+            this[i][2] = value
             return
           else
             throw(ArgumentException("key already exists"))
@@ -480,7 +496,7 @@ local ArrayDictionary = (function ()
         end
       end
     end
-    this[len + 1] = setmetatable({ Key = key, Value = value }, this.__genericT__)
+    this[len + 1] = setmetatable({ key, value }, this.__genericT__)
     versions[this] = (versions[this] or 0) + 1
   end
   
@@ -491,7 +507,7 @@ local ArrayDictionary = (function ()
       local comparer = this.comparer
       local equals = comparer.EqualsOf
       for i = 1, len do
-        if equals(comparer, this[i].Key, key) then
+        if equals(comparer, this[i][1], key) then
           tremove(this, i)
           versions[this] = (versions[this] or 0) + 1
           return true
@@ -533,7 +549,7 @@ local ArrayDictionary = (function ()
       local k, v
       if select("#", ...) == 1 then
         local pair = ... 
-        k, v = pair.Key, pair.Value
+        k, v = pair[1], pair[2]
       else
         k, v = ...
       end
@@ -547,7 +563,7 @@ local ArrayDictionary = (function ()
         local comparer = this.comparer
         local equals = comparer.EqualsOf
         for i = 1, len do
-          if equals(comparer, this[i].Key, key) then
+          if equals(comparer, this[i][1], key) then
             return true
           end
         end
@@ -559,8 +575,8 @@ local ArrayDictionary = (function ()
       if len > 0 then
         local comparer = EqualityComparer(this.__genericTValue__).getDefault()
         local equals = comparer.EqualsOf
-        for i = 1, #this do
-          if equals(comparer, value, this[i].Value) then
+        for i = 1, len do
+          if equals(comparer, value, this[i][2]) then
             return true
           end
         end
@@ -568,7 +584,7 @@ local ArrayDictionary = (function ()
       return false
     end,
     Contains = function (this, pair)
-      local key = pair.Key
+      local key = pair[1]
       if key == nil then throw(ArgumentNullException("key")) end
       local len = #this
       if len > 0 then
@@ -576,9 +592,9 @@ local ArrayDictionary = (function ()
         local equals = comparer.EqualsOf
         for i = 1, len do
           local t = this[i]
-          if equals(comparer, t.Key, key) then
+          if equals(comparer, t[1], key) then
             local comparer = EqualityComparer(this.__genericTValue__).getDefault()
-            if comparer:EqualsOf(t.Value, pair.Value) then
+            if comparer:EqualsOf(t[2], pair[2]) then
               return true
             end 
           end
@@ -594,7 +610,7 @@ local ArrayDictionary = (function ()
         index = index + 1
         for i = 1, count do
           local t = this[i]
-          array[index] = setmetatable({ Key = t.Key:__clone__(), Value = t.Value }, KeyValuePair)
+          array[index] = setmetatable({ t[1]:__clone__(), t[2] }, KeyValuePair)
           index = index + 1
         end
       end
@@ -603,12 +619,12 @@ local ArrayDictionary = (function ()
     Remove = function (this, key)
       if isKeyValuePair(key) then
         local len = #this
-        local k, v = key.Key, key.Value
+        local k, v = key[1], key[2]
         for i = 1, #this do
           local pair = this[i]
-          if pair.Key:EqualsObj(k) then
+          if pair[1]:EqualsObj(k) then
             local comparer = EqualityComparer(this.__genericTValue__).getDefault()
-            if comparer:EqualsOf(pair.Value, v) then
+            if comparer:EqualsOf(pair[2], v) then
               tremove(this, i)
               return true
             end
@@ -625,8 +641,8 @@ local ArrayDictionary = (function ()
         local equals = comparer.EqualsOf
         for i = 1, len do
           local pair = this[i]
-          if equals(comparer, pair.Key, key) then
-            return true, pair.Value
+          if equals(comparer, pair[1], key) then
+            return true, pair[2]
           end
         end
       end
@@ -644,8 +660,8 @@ local ArrayDictionary = (function ()
         local equals = comparer.EqualsOf
         for i = 1, len do
           local pair = this[i]
-          if equals(comparer, pair.Key, key) then
-            return pair.Value
+          if equals(comparer, pair[1], key) then
+            return pair[2]
           end
         end
       end
@@ -671,7 +687,7 @@ ArrayDictionaryFn = define("System.Collections.Generic.ArrayDictionary", functio
     __genericTKey__ = TKey,
     __genericTValue__ = TValue,
   }
-end, ArrayDictionary)
+end, ArrayDictionary, 2)
 
 function System.dictionaryFromTable(t, TKey, TValue)
   return setmetatable(t, Dictionary(TKey, TValue))
@@ -695,9 +711,10 @@ local DictionaryFn = define("System.Collections.Generic.Dictionary", function(TK
     __genericTValue__ = TValue,
     __len = len
   }, array
-end, Dictionary)
+end, Dictionary, 2)
 
 System.Dictionary = DictionaryFn
+System.ArrayDictionary = ArrayDictionaryFn
 
 local Object = System.Object
 System.Hashtable = DictionaryFn(Object, Object)

+ 2 - 4
Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/Collections/EqualityComparer.lua.txt

@@ -73,7 +73,6 @@ EqualityComparer = define("System.EqualityComparer", function (T)
       if obj == nil then return 0 end
       if System.is(obj, T) then return getHashCode(obj) end
       throw(ArgumentException("Type of argument is not compatible with the generic comparer."))
-      return false
     end,
     EqualsObjOf = function (this, x, y)
       if x == y then return true end
@@ -81,10 +80,9 @@ EqualityComparer = define("System.EqualityComparer", function (T)
       local is = System.is
       if is(x, T) and is(y, T) then return equals(x, y) end
       throw(ArgumentException("Type of argument is not compatible with the generic comparer."))
-      return false
     end
   }
-end)
+end, nil, 1)
 
 local function compare(this, a, b)
   return compareObj(a, b)
@@ -116,7 +114,7 @@ ComparisonComparer = define("System.ComparisonComparer", function (T)
       return this.comparison(x, y)
     end
   }
-end)
+end, nil, 1)
 
 Comparer = define("System.Comparer_1", function (T)
   local Compare

+ 7 - 7
Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/Collections/HashSet.lua.txt

@@ -51,12 +51,12 @@ local function checkUniqueAndUnfoundElements(this, other, returnIfUnfound)
   local set, uniqueCount, unfoundCount = {}, 0, 0
   for _, item in each(other) do
     item = wrap(item)
-      if this[item] ~= nil then
-        if set[item] == nil then
-          set[item] = true
-          uniqueCount = uniqueCount + 1
-        end
-      else
+    if this[item] ~= nil then
+      if set[item] == nil then
+        set[item] = true
+        uniqueCount = uniqueCount + 1
+      end
+    else
       unfoundCount = unfoundCount + 1
       if returnIfUnfound then
         break
@@ -313,4 +313,4 @@ System.HashSet = System.define("System.Collections.Generic.HashSet", function(T)
     __genericTKey__ = T,
     __len = HashSet.getCount
   }
-end, HashSet)
+end, HashSet, 1)

+ 1 - 1
Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/Collections/LinkedList.lua.txt

@@ -343,4 +343,4 @@ System.LinkedList = define("System.Collections.Generic.LinkedList", function(T)
   __genericT__ = T,
   __len = LinkedList.getCount
   }
-end, LinkedList)
+end, LinkedList, 1)

+ 4 - 4
Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/Collections/Linq.lua.txt

@@ -53,7 +53,7 @@ local InternalEnumerable = define("System.Linq.InternalEnumerable", function(T)
   return {
     base = { IEnumerable_1(T) }
   }
-end)
+end, nil, 1)
 
 local function createEnumerable(T, GetEnumerator)
   assert(T)
@@ -64,7 +64,7 @@ local InternalEnumerator = define("System.Linq.InternalEnumerator", function(T)
   return {
     base = { IEnumerator_1(T) }
   }
-end)
+end, nil, 1)
 
 local function createEnumerator(T, source, tryGetNext, init)
   assert(T)
@@ -277,7 +277,7 @@ local Grouping = define("System.Linq.Grouping", function (TKey, TElement)
       return #this
     end
   }
-end)
+end, nil, 2)
 
 local function getGrouping(this, key)
   local hashCode = this.comparer:GetHashCodeOf(key)
@@ -313,7 +313,7 @@ local LookupFn = define("System.Linq.Lookup", function(TKey, TElement)
     __genericTElement__ = TElement,
   }
   return cls
-end, Lookup)
+end, Lookup, 2)
 
 local function addToLookup(this, key, value)
   local hashCode = this.comparer:GetHashCodeOf(key)

+ 2 - 1
Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/Collections/List.lua.txt

@@ -22,6 +22,7 @@ local Array = System.Array
 local List = {
   __ctor__ = Array.ctorList,
   getCapacity = lengthFn,
+  setCapacity = Array.setCapacity,
   getCount = lengthFn,
   getIsFixedSize = falseFn,
   getIsReadOnly = falseFn,
@@ -68,7 +69,7 @@ local ListFn = System.define("System.Collections.Generic.List", function(T)
     base = { System.IList_1(T), System.IReadOnlyList_1(T), System.IList }, 
     __genericT__ = T,
   }
-end, List)
+end, List, 1)
 
 System.List = ListFn
 System.ArrayList = ListFn(System.Object)

+ 185 - 0
Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/Collections/PriorityQueue.lua.txt

@@ -0,0 +1,185 @@
+--[[
+Copyright YANG Huan (sy.yanghuan@gmail.com).
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+--]]
+
+local System = System
+local throw = System.throw
+local each = System.each
+local er = System.er 
+local Array = System.Array
+local heapDown = Array.heapDown
+local heapUp = Array.heapUp
+local heapify = Array.heapify
+local heapAdd = Array.heapAdd
+local heapPop = Array.heapPop
+local Comparer_1 = System.Comparer_1
+
+local ArgumentNullException = System.ArgumentNullException
+local ArgumentOutOfRangeException = System.ArgumentOutOfRangeException
+local InvalidOperationException = System.InvalidOperationException
+
+local select = select
+local type = type
+
+local function __ctor__(t, ...)
+  local items, comparer
+  local n = select("#", ...)
+  if n == 0 then
+  else
+    items, comparer = ...
+    if items == nil then throw(ArgumentNullException("items")) end
+  end
+  if comparer == nil then comparer = Comparer_1(t.__genericTPriority__).getDefault() end
+  local compare = comparer.Compare
+  local c = function (a, b) return compare(comparer, a[2], b[2]) end
+  t.comparer, t.c = comparer, c
+  if type(items) == "table" then
+    local i = 1
+    for _, tuple in each(items) do
+      local element, priority = tuple[1], tuple[2]
+      t[i] = { element, priority }
+      i = i + 1
+    end
+    if i > 1 then
+      heapify(t, c)
+    end
+  end
+end
+
+local function dequeue(t, n)
+  local v = heapPop(t, t.c)
+  if v == nil then throw(InvalidOperationException(er.InvalidOperation_EmptyQueue())) end
+  return v[1]
+end
+
+local function enqueue(t, element, priority) 
+  heapAdd(t, { element, priority }, t.c)
+end
+
+local function enqueueDequeue(t, element, priority)
+  local n = #t
+  if n ~= 0 then
+    local c = t.c
+    local v = { element, priority }
+    local root = t[1]
+    if c(v, root) > 0 then
+      t[1] = v
+      heapDown(t, 1, n, c)
+      return root[1]
+    end
+  end
+  return element
+end
+
+local function enqueueRange(t, ...)
+  local len = select("#", ...)
+  local n = #t
+  if n == 0 then
+    local i = 1
+    if len == 1 then
+      local items = ...
+      for _, tuple in each(items) do
+        local element, priority = tuple[1], tuple[2]
+        t[i] = { element, priority }
+        i = i + 1
+      end
+    else
+      local elements, priority = ...
+      for _, element in each(elements) do
+        t[i] = { element, priority }
+        i = i + 1
+      end
+    end
+    if i > 1 then
+      heapify(t, t.c)
+    end
+  else
+    local c = t.c
+    if len == 1 then
+      local items = ...
+      for _, tuple in each(items) do
+        local element, priority = tuple[1], tuple[2]
+        n = n + 1
+        t[n] = { element, priority }
+        heapUp(t, n, n, c)
+      end
+    else
+      local elements, priority = ...
+      for _, element in each(elements) do
+        n = n + 1
+        t[n] = { element, priority }
+        heapUp(t, n, n, c)
+      end
+    end
+  end
+end
+
+local function ensureCapacity(t, capacity)
+  if capacity < 0 then
+    throw(ArgumentOutOfRangeException("capacity", er.ArgumentOutOfRange_NeedNonNegNum()))
+  end
+  local n = #t
+  local newcapacity = 2 * n
+  newcapacity = math.max(newcapacity, n + 4)
+  if newcapacity < 4 then newcapacity = 4 end
+  return newcapacity
+end
+
+local function peek(t)
+  local v = t[1]
+  if v == nil then throw(InvalidOperationException(er.InvalidOperation_EmptyQueue())) end
+  return v[1]
+end
+
+local function tryDequeue(t)
+  local v = heapPop(t, t.c)
+  if v then
+    return true, v[1], v[2]
+  end
+  return false, t.__genericTElement__:default(), t.__genericTPriority__:default()
+end
+
+local function tryPeek(t)
+  local v = t[1] 
+  if v then
+    return true, v[1], v[2]
+  end
+  return false, t.__genericTElement__:default(), t.__genericTPriority__:default()
+end
+
+local PriorityQueue = {
+  __ctor__ = __ctor__,
+  getCount = System.lengthFn,
+  getComparer = Array.getOrderComparer,
+  Clear = Array.clear,
+  Dequeue = dequeue,
+  Enqueue = enqueue,
+  EnqueueDequeue = enqueueDequeue,
+  EnqueueRange = enqueueRange,
+  EnsureCapacity = ensureCapacity,
+  Peek = peek,
+  TrimExcess = System.emptyFn,
+  TryDequeue = tryDequeue,
+  TryPeek = tryPeek,
+}
+
+local PriorityQueueFn = System.define("System.Collections.Generic.PriorityQueue", function (TElement, TPriority)
+  return { 
+    __genericTElement__ = TElement,
+    __genericTPriority__ = TPriority,
+  }
+end, PriorityQueue, 2)
+
+System.PriorityQueue = PriorityQueueFn

+ 1 - 1
Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/Collections/Queue.lua.txt

@@ -48,7 +48,7 @@ local QueueFn = System.define("System.Collections.Generic.Queue", function(T)
     base = { System.IEnumerable_1(T), System.ICollection },
     __genericT__ = T,
   }
-end, Queue)
+end, Queue, 1)
 
 System.Queue = QueueFn
 System.queue = QueueFn(System.Object)

+ 34 - 839
Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/Collections/SortedDictionary.lua.txt

@@ -1,5 +1,5 @@
 --[[
-Copyright 2017 YANG Huan (sy.yanghuan@gmail.com).
+Copyright YANG Huan (sy.yanghuan@gmail.com).
 
 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
@@ -15,848 +15,43 @@ limitations under the License.
 --]]
 
 local System = System
-local define = System.define
-local throw = System.throw
-local null = System.null
-local falseFn = System.falseFn
-local each = System.each
-local lengthFn = System.lengthFn
-local versions = System.versions
 local Array = System.Array
-local checkIndexAndCount = System.checkIndexAndCount
-local throwFailedVersion = System.throwFailedVersion
-local ArgumentNullException = System.ArgumentNullException
-local ArgumentException = System.ArgumentException
-local KeyNotFoundException = System.KeyNotFoundException
-local EqualityComparer = System.EqualityComparer
-local Comparer = System.Comparer_1
-local NotSupportedException = System.NotSupportedException
-
-local assert = assert
-local pairs = pairs
-local next = next
-local select = select
-local getmetatable = getmetatable
-local setmetatable = setmetatable
-local tconcat = table.concat
-local tremove = table.remove
-local type = type
-
-local counts = setmetatable({}, { __mode = "k" })
-System.counts = counts
-
-local function getCount(this)
-    local t = counts[this]
-    if t then
-        return t[1]
-    end
-    return 0
-end
-
-local function pairsFn(t, i)
-    local count = counts[t]
-    if count then
-        if count[2] ~= count[3] then
-            throwFailedVersion()
-        end
-    end
-    local k, v = next(t, i)
-    if v == null then
-        return k
-    end
-    return k, v
-end
-
-function System.pairs(t)
-    local count = counts[t]
-    if count then
-        count[3] = count[2]
-    end
-    return pairsFn, t
-end
-
-local KeyValuePairFn =System.KeyValuePair
-local KeyValuePair = {
-    __ctor__ = function(this, ...)
-        if select("#", ...) == 0 then
-            this.Key, this.Value = this.__genericTKey__:default(), this.__genericTValue__:default()
-        else
-            this.Key, this.Value = ...
-        end
-    end,
-    Create = function(key, value, TKey, TValue)
-        return setmetatable({ Key = key, Value = value }, KeyValuePairFn(TKey, TValue))
-    end,
-    Deconstruct = function(this)
-        return this.Key, this.Value
-    end,
-    ToString = function(this)
-        local t = { "[" }
-        local count = 2
-        local k, v = this.Key, this.Value
-        if k ~= nil then
-            t[count] = k:ToString()
-            count = count + 1
-        end
-        t[count] = ", "
-        count = count + 1
-        if v ~= nil then
-            t[count] = v:ToString()
-            count = count + 1
-        end
-        t[count] = "]"
-        return tconcat(t)
-    end
-}
-
-local function isKeyValuePair(t)
-    return getmetatable(getmetatable(t)) == KeyValuePair
-end
-
-local DictionaryEnumerator = define("System.Collections.Generic.SortedDictionaryEnumerator", {
-    getCurrent = System.getCurrent,
-    Dispose = System.emptyFn,
-    MoveNext = function(this)
-        local t, kind = this.dict, this.kind
-        local count = counts[t]
-        if this.version ~= (count and count[2] or 0) then
-            throwFailedVersion()
-        end
-        if this.currNode then
-            local k, v = this.currNode.k,this.currNode.v
-            if kind then
-                kind.Key = k
-                if v == null then
-                    v = nil
-                end
-                kind.Value = v
-            elseif kind == false then
-                if v == null then
-                    v = nil
-                end
-                this.current = v
-            else
-                this.current = k
-            end
-            this.currNode = this.currNode.next
-            return true
-        else
-            if kind then
-                kind.Key, kind.Value = kind.__genericTKey__:default(), kind.__genericTValue__:default()
-            elseif kind == false then
-                this.current = t.__genericTValue__:default()
-            else
-                this.current = t.__genericTKey__:default()
-            end
-            return false
-        end
-    end
-})
-
-local function dictionaryEnumerator(t, kind)
-    local current
-    if not kind then
-        local TKey, TValue = t.__genericTKey__, t.__genericTValue__
-        kind = setmetatable({ Key = TKey:default(), Value = TValue:default() }, t.__genericT__)
-        current = kind
-    elseif kind == 1 then
-        local TKey = t.__genericTKey__
-        current = TKey:default()
-        kind = nil
-    else
-        local TValue = t.__genericTValue__
-        current = TValue:default()
-        kind = false
-    end
-    local count = counts[t]
-    local en = {
-        dict = t,
-        version = count and count[2] or 0,
-        kind = kind,
-        current = current
-    }
-    local enumerator= setmetatable(en, DictionaryEnumerator)
-    enumerator.currNode = t.first
-    return enumerator
-end
-
-local DictionaryCollection = define("System.Collections.Generic.SortedDictionaryCollection", function(T)
-    return {
-        base = { System.ICollection_1(T), System.IReadOnlyCollection_1(T), System.ICollection },
-        __genericT__ = T
-    }
-end, {
-    __ctor__ = function(this, dict, kind)
-        this.dict = dict
-        this.kind = kind
-    end,
-    getCount = function(this)
-        return getCount(this.dict)
-    end,
-    GetEnumerator = function(this)
-        return dictionaryEnumerator(this.dict, this.kind)
-    end
-}, 1)
-
-local KVNode = define("System.Collections.Generic.SortedDictionaryCollection.KVNode",{
-    __ctor__ = function(this, k, v, ...)
-        this.k = k
-        this.v = v
-        local pre, next = ...
-        this.pre = pre
-        this.next = next
-    end
-})
-
-local function addNodeEmpty(this, key, value)
-    local node = KVNode()(key, value)
-    this.first = node
-end
-local function addNode(this, key, value)
-    local node = KVNode()(key, value)
-    local curr = this.first;
-    if not curr then
-        throw(ArgumentNullException("first"))
-    end
-    while (1) do
-        local k = curr.k
-        local comparer = Comparer(this.__genericTKey__).getDefault()
-        if (comparer:Compare(k,key) > 0) then
-            curr.pre = node
-            node.next = curr
-            break
-        end
-        local nextNode = curr.next;
-        if not nextNode then
-            curr.next = node
-            node.pre = curr
-            break ;
-        end
-        curr = nextNode
-    end
-end
-local function removeNode(this, key)
-    local curr = this.first;
-    if not curr then
-        throw(ArgumentNullException("first"))
-    end
-    while (1) do
-        local k = curr.k
-        local comparer = Comparer(this.__genericTKey__).getDefault()
-        if (comparer:Compare(k,key) == 0) then
-            if curr.pre then
-                curr.pre.next = curr.next;
-            end
-            if curr.next then
-                curr.next.pre = curr.pre;
-            end
-            if curr == this.first and not curr.next then
-                this.first=nil
-            end
-            break
-        end
-        local nextNode = curr.next;
-        if not nextNode then
-            break ;
-        end
-        curr = nextNode
-    end
-
-end
-
-local function clearNodes(this)
-    local curr = this.first;
-    if not curr then
-        return
-    end
-    while (1) do
-        local nextNode = curr.next;
-        if not nextNode then
-            break
-        end
-        curr = nextNode
-    end
-    this.first = nil
-end
-local function add(this, key, value)
-    if key == nil then
-        throw(ArgumentNullException("key"))
-    end
-    if this[key] ~= nil then
-        throw(ArgumentException("key already exists"))
-    end
-    local t = counts[this]
-    if t then
-        t[1] = t[1] + 1
-        t[2] = t[2] + 1
-    else
-       t = { 1, 1 }
-       counts[this] = t
-    end
-    if this.first == nil then
-        addNodeEmpty(this, key, value)
-    else
-        addNode(this, key, value)
-    end
-    this[key] = value == nil and null or value
-end
-
-local function remove(this, key)
-    if key == nil then
-        throw(ArgumentNullException("key"))
-    end
-    if this[key] ~= nil then
-        this[key] = nil
-        removeNode(this, key)
-        local t = counts[this]
-        t[1] = t[1] - 1
-        t[2] = t[2] + 1
-        return true
-    end
-    return false
-end
-local function replace(this, key,value)
-    local node=KVNode()(key,value)
-    local curr = this.first;
-    if not curr then
-        throw(ArgumentNullException("first"))
-    end
-    while (1) do
-        local k = curr.k
-        local comparer = Comparer(this.__genericTKey__).getDefault()
-        if (comparer:Compare(k,key) == 0) then
-            curr.pre.next = node;
-            curr.nect.pre = node;
-            node.pre=curr.pre
-            node.next=curr.next
-            curr = nil;
-            break
-        end
-        local nextNode = curr.next;
-        if not nextNode then
-            break ;
-        end
-        curr = nextNode
-    end
-end
-
-local function buildFromDictionary(this, dictionary)
-    if dictionary == nil then
-        throw(ArgumentNullException("dictionary"))
-    end
-    local count = 0
-    for k, v in pairs(dictionary) do
-
-        if count == 0 then
-            addNodeEmpty(this, k, v)
-        else
-            addNode(this, k, v)
-        end
-
-        this[k] = v
-        count = count + 1
-    end
-    counts[this] = { count, 0 }
-end
-
-local ArrayDictionaryFn
-local function buildHasComparer(this, ...)
-    local Dictionary = ArrayDictionaryFn(this.__genericTKey__, this.__genericTValue__)
-    Dictionary.__ctor__(this, ...)
-    return setmetatable(this, Dictionary)
-end
-
-local Dictionary = {
-    getIsFixedSize = falseFn,
-    getIsReadOnly = falseFn,
-    __ctor__ = function(this, ...)
-        local n = select("#", ...)
-        if n == 0 then
-        elseif n == 1 then
-            local comparer = ...
-            if comparer == nil or type(comparer) == "number" then
-            else
-                local equals = comparer.EqualsOf
-                if equals == nil then
-                    buildFromDictionary(this, comparer)
-                else
-                    buildHasComparer(this, ...)
-                end
-            end
-        else
-            local dictionary, comparer = ...
-            if comparer ~= nil then
-                buildHasComparer(this, ...)
-            end
-            if type(dictionary) ~= "number" then
-                buildFromDictionary(this, dictionary)
-            end
-        end
-    end,
-    AddKeyValue = add,
-    Add = function(this, ...)
-        local k, v
-        if select("#", ...) == 1 then
-            local pair = ...
-            k, v = pair.Key, pair.Value
-        else
-            k, v = ...
-        end
-        add(this, k, v)
-    end,
-    Clear = function(this)
-        for k, v in pairs(this) do
-            clearNodes(this)
-            this[k] = nil
-        end
-        counts[this] = nil
-    end,
-    ContainsKey = function(this, key)
-        if key == nil then
-            throw(ArgumentNullException("key"))
-        end
-        return this[key] ~= nil
-    end,
-    ContainsValue = function(this, value)
-        if value == nil then
-            for _, v in pairs(this) do
-                if v == null then
-                    return true
-                end
-            end
-        else
-            local comparer = EqualityComparer(this.__genericTValue__).getDefault()
-            local equals = comparer.EqualsOf
-            for _, v in pairs(this) do
-                if v ~= null then
-                    if equals(comparer, value, v) then
-                        return true
-                    end
-                end
-            end
-        end
-        return false
-    end,
-    Contains = function(this, pair)
-        local key = pair.Key
-        if key == nil then
-            throw(ArgumentNullException("key"))
-        end
-        local value = this[key]
-        if value ~= nil then
-            if value == null then
-                value = nil
-            end
-            local comparer = EqualityComparer(this.__genericTValue__).getDefault()
-            if comparer:EqualsOf(value, pair.Value) then
-                return true
-            end
-        end
-        return false
-    end,
-    CopyTo = function(this, array, index)
-        local count = getCount(this)
-        checkIndexAndCount(array, index, count)
-        if count > 0 then
-            local KeyValuePair = this.__genericT__
-            index = index + 1
-            for k, v in pairs(this) do
-                if v == null then
-                    v = nil
-                end
-                array[index] = setmetatable({ Key = k, Value = v }, KeyValuePair)
-                index = index + 1
-            end
-        end
-    end,
-    RemoveKey = remove,
-    Remove = function(this, key)
-        if isKeyValuePair(key) then
-            local k, v = key.Key, key.Value
-            if k == nil then
-                throw(ArgumentNullException("key"))
-            end
-            local value = this[k]
-            if value ~= nil then
-                if value == null then
-                    value = nil
-                end
-                local comparer = EqualityComparer(this.__genericTValue__).getDefault()
-                if comparer:EqualsOf(value, v) then
-                    remove(this, k)
-                    return true
-                end
-            end
-            return false
-        end
-        return remove(this, key)
-    end,
-    TryGetValue = function(this, key)
-        if key == nil then
-            throw(ArgumentNullException("key"))
-        end
-        local value = this[key]
-        if value == nil then
-            return false, this.__genericTValue__:default()
-        end
-        if value == null then
-            return true
-        end
-        return true, value
-    end,
-    getComparer = function(this)
-        return EqualityComparer(this.__genericTKey__).getDefault()
-    end,
-    getCount = getCount,
-    get = function(this, key)
-        if key == nil then
-            throw(ArgumentNullException("key"))
-        end
-        local value = this[key]
-        if value == nil then
-            throw(KeyNotFoundException())
-        end
-        if value ~= null then
-            return value
-        end
-        return nil
-    end,
-    set = function(this, key, value)
-        if key == nil then
-            throw(ArgumentNullException("key"))
-        end
-        local t = counts[this]
-        if t then
-            if this[key] == nil then
-                t[1] = t[1] + 1
-            end
-            t[2] = t[2] + 1
-        else
-            counts[this] = { 1, 1 }
-        end
-        this[key] = value == nil and null or value
-        replace(this,key,value)
-    end,
-    GetEnumerator = dictionaryEnumerator,
-    getKeys = function(this)
-        return DictionaryCollection(this.__genericTKey__)(this, 1)
-    end,
-    getValues = function(this)
-        return DictionaryCollection(this.__genericTValue__)(this, 2)
-    end
+local ArrayDictionary = System.ArrayDictionary
+
+local SortedDictionary = {
+  __ctor__ = Array.ctorOrderDict,
+  getComparer = Array.getOrderComparer,
+  getCount = System.lengthFn,
+  AddKeyValue = Array.addOrderDict,
+  AddKeyValueObj = Array.addOrderDictObj,
+  Add = Array.addPairOrderDict,
+  Clear = Array.clear,
+  ContainsKey = Array.containsOrderDict,
+  ContainsValue = ArrayDictionary.ContainsValue,
+  ContainsKeyObj = Array.containsOrderDictObj,
+  CopyTo = Array.CopyTo,
+  GetEnumerator = Array.GetEnumerator,
+  RemoveKey = Array.removeOrderDict,
+  Remove =  Array.removePairOrderDict,
+  TryGetValue = Array.tryGetValueOrderDict,
+  getKeys = ArrayDictionary.getKeys,
+  getValues = ArrayDictionary.getValues,
+  get = Array.getOrderDict,
+  getObj = Array.getOrderDictObj,
+  set = Array.setOrderDict,
+  setObj = Array.setOrderDictObj,
 }
 
-local ArrayDictionaryEnumerator = define("System.Collections.Generic.ArraySortedDictionaryEnumerator", function(T)
-    return {
-        base = { System.IEnumerator_1(T) }
-    }
-end, {
-    getCurrent = System.getCurrent,
-    Dispose = System.emptyFn,
-    MoveNext = function(this)
-        local t = this.list
-        if this.version ~= versions[t] then
-            throwFailedVersion()
-        end
-        local index = this.index
-        local pair = t[index]
-        if pair ~= nil then
-            if t.kind then
-                this.current = pair.Value
-            else
-                this.current = pair.Key
-            end
-            this.index = index + 1
-            return true
-        end
-        this.current = nil
-        return false
-    end
-}, 1)
-
-local arrayDictionaryEnumerator = function(t, kind, T)
-    return setmetatable({ list = t, kind = kind, index = 1, version = versions[t], currnet = T:default() }, ArrayDictionaryEnumerator(T))
-end
-
-local ArrayDictionaryCollection = define("System.Collections.Generic.ArraySortedDictionaryCollection", function(T)
-    return {
-        base = { System.ICollection_1(T), System.IReadOnlyCollection_1(T), System.ICollection },
-        __genericT__ = T
-    }
-end, {
-    __ctor__ = function(this, dict, kind)
-        this.dict = dict
-        this.kind = kind
-    end,
-    getCount = function(this)
-        return getCount(this.dict)
-    end,
-    GetEnumerator = function(this)
-        return arrayDictionaryEnumerator(this.dict, this.kind, this.__genericT__)
-    end
-}, 1)
-
-local ArrayDictionary = (function()
-    local function buildFromDictionary(this, dictionary)
-        if dictionary == nil then
-            throw(ArgumentNullException("dictionary"))
-        end
-        local count = 1
-        local KeyValuePair = this.__genericT__
-        for _, pair in each(dictionary) do
-            local k, v = pair.Key, pair.Value
-            if type(k) == "table" and k.class == 'S' then
-                k = k:__clone__()
-            end
-            this[count] = setmetatable({ Key = k, Value = v }, KeyValuePair)
-            count = count + 1
-        end
-    end
-
-    local function add(this, key, value, set)
-        if key == nil then
-            throw(ArgumentNullException("key"))
-        end
-        local len = #this
-        if len > 0 then
-            local comparer = this.comparer
-            local equals = comparer.EqualsOf
-            for i = 1, len do
-                if equals(comparer, this[i].Key, key) then
-                    if set then
-                        this[i].Value = value
-                        return
-                    else
-                        throw(ArgumentException("key already exists"))
-                    end
-                end
-            end
-        end
-        this[len + 1] = setmetatable({ Key = key, Value = value }, this.__genericT__)
-        versions[this] = (versions[this] or 0) + 1
-    end
-
-    local function remove(this, key)
-        if key == nil then
-            throw(ArgumentNullException("key"))
-        end
-        local len = #this
-        if len > 0 then
-            local comparer = this.comparer
-            local equals = comparer.EqualsOf
-            for i = 1, len do
-                if equals(comparer, this[i].Key, key) then
-                    tremove(this, i)
-                    versions[this] = (versions[this] or 0) + 1
-                    return true
-                end
-            end
-        end
-        return false
-    end
-
-    return {
-        getIsFixedSize = falseFn,
-        getIsReadOnly = falseFn,
-        __ctor__ = function(this, ...)
-            local Comparer
-            local n = select("#", ...)
-            if n == 0 then
-            elseif n == 1 then
-                local comparer = ...
-                if comparer == nil or type(comparer) == "number" then
-                else
-                    local equals = comparer.EqualsOf
-                    if equals == nil then
-                        buildFromDictionary(this, comparer)
-                    else
-                        Comparer = comparer
-                    end
-                end
-            else
-                local dictionary, comparer = ...
-                if type(dictionary) ~= "number" then
-                    buildFromDictionary(this, dictionary)
-                end
-                Comparer = comparer
-            end
-            this.comparer = Comparer or EqualityComparer(this.__genericTKey__).getDefault()
-        end,
-        AddKeyValue = add,
-        Add = function(this, ...)
-            local k, v
-            if select("#", ...) == 1 then
-                local pair = ...
-                k, v = pair.Key, pair.Value
-            else
-                k, v = ...
-            end
-            add(this, k, v)
-        end,
-        Clear = Array.clear,
-        ContainsKey = function(this, key)
-            if key == nil then
-                throw(ArgumentNullException("key"))
-            end
-            local len = #this
-            if len > 0 then
-                local comparer = this.comparer
-                local equals = comparer.EqualsOf
-                for i = 1, len do
-                    if equals(comparer, this[i].Key, key) then
-                        return true
-                    end
-                end
-            end
-            return false
-        end,
-        ContainsValue = function(this, value)
-            local len = #this
-            if len > 0 then
-                local comparer = EqualityComparer(this.__genericTValue__).getDefault()
-                local equals = comparer.EqualsOf
-                for i = 1, #this do
-                    if equals(comparer, value, this[i].Value) then
-                        return true
-                    end
-                end
-            end
-            return false
-        end,
-        Contains = function(this, pair)
-            local key = pair.Key
-            if key == nil then
-                throw(ArgumentNullException("key"))
-            end
-            local len = #this
-            if len > 0 then
-                local comparer = this.comparer
-                local equals = comparer.EqualsOf
-                for i = 1, len do
-                    local t = this[i]
-                    if equals(comparer, t.Key, key) then
-                        local comparer = EqualityComparer(this.__genericTValue__).getDefault()
-                        if comparer:EqualsOf(t.Value, pair.Value) then
-                            return true
-                        end
-                    end
-                end
-            end
-            return false
-        end,
-        CopyTo = function(this, array, index)
-            local count = #this
-            checkIndexAndCount(array, index, count)
-            if count > 0 then
-                local KeyValuePair = this.__genericT__
-                index = index + 1
-                for i = 1, count do
-                    local t = this[i]
-                    array[index] = setmetatable({ Key = t.Key:__clone__(), Value = t.Value }, KeyValuePair)
-                    index = index + 1
-                end
-            end
-        end,
-        RemoveKey = remove,
-        Remove = function(this, key)
-            if isKeyValuePair(key) then
-                local len = #this
-                local k, v = key.Key, key.Value
-                for i = 1, #this do
-                    local pair = this[i]
-                    if pair.Key:EqualsObj(k) then
-                        local comparer = EqualityComparer(this.__genericTValue__).getDefault()
-                        if comparer:EqualsOf(pair.Value, v) then
-                            tremove(this, i)
-                            return true
-                        end
-                    end
-                end
-            end
-            return false
-        end,
-        TryGetValue = function(this, key)
-            if key == nil then
-                throw(ArgumentNullException("key"))
-            end
-            local len = #this
-            if len > 0 then
-                local comparer = this.comparer
-                local equals = comparer.EqualsOf
-                for i = 1, len do
-                    local pair = this[i]
-                    if equals(comparer, pair.Key, key) then
-                        return true, pair.Value
-                    end
-                end
-            end
-            return false, this.__genericTValue__:default()
-        end,
-        getComparer = function(this)
-            return this.comparer
-        end,
-        getCount = lengthFn,
-        get = function(this, key)
-            if key == nil then
-                throw(ArgumentNullException("key"))
-            end
-            local len = #this
-            if len > 0 then
-                local comparer = this.comparer
-                local equals = comparer.EqualsOf
-                for i = 1, len do
-                    local pair = this[i]
-                    if equals(comparer, pair.Key, key) then
-                        return pair.Value
-                    end
-                end
-            end
-            throw(KeyNotFoundException())
-        end,
-        set = function(this, key, value)
-            add(this, key, value, true)
-        end,
-        GetEnumerator = Array.GetEnumerator,
-        getKeys = function(this)
-            return ArrayDictionaryCollection(this.__genericTKey__)(this)
-        end,
-        getValues = function(this)
-            return ArrayDictionaryCollection(this.__genericTValue__)(this, true)
-        end
-    }
-end)()
-
-ArrayDictionaryFn = define("System.Collections.Generic.ArraySortedDictionary", function(TKey, TValue)
-    return {
-        base = { System.IDictionary_2(TKey, TValue), System.IDictionary, System.IReadOnlyDictionary_2(TKey, TValue) },
-        __genericT__ = KeyValuePairFn(TKey, TValue),
-        __genericTKey__ = TKey,
-        __genericTValue__ = TValue,
-    }
-end, ArrayDictionary, 2)
+local SortedDictionaryFn = System.define("System.Collections.Generic.SortedDictionary", function(TKey, TValue) 
+  return { 
+    base = { System.IDictionary_2(TKey, TValue), System.IDictionary, System.IReadOnlyDictionary_2(TKey, TValue) },
+    __genericT__ = System.KeyValuePair(TKey, TValue),
+    __genericTKey__ = TKey,
+    __genericTValue__ = TValue,
+  }
+end, SortedDictionary, 2)
 
-function System.dictionaryFromTable(t, TKey, TValue)
-    return setmetatable(t, Dictionary(TKey, TValue))
-end
+System.SortedDictionary = SortedDictionaryFn
 
-function System.isDictLike(t)
-    return type(t) == "table" and t.GetEnumerator == dictionaryEnumerator
-end
 
-local DictionaryFn = define("System.Collections.Generic.SortedDictionary", function(TKey, TValue)
-    local array, len
-    if TKey.class == 'S' and type(TKey:default()) == "table" then
-        array = ArrayDictionary
-    else
-        len = getCount
-    end
-    return {
-        base = { System.IDictionary_2(TKey, TValue), System.IDictionary, System.IReadOnlyDictionary_2(TKey, TValue) },
-        __genericT__ = KeyValuePairFn(TKey, TValue),
-        __genericTKey__ = TKey,
-        __genericTValue__ = TValue,
-        __len = len
-    }, array
-end, Dictionary, 2)
 
-System.SortedDictionary_2 = DictionaryFn

+ 60 - 0
Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/Collections/SortedList.lua.txt

@@ -0,0 +1,60 @@
+--[[
+  Copyright 2017 YANG Huan (sy.yanghuan@gmail.com).
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+limitations under the License.
+--]]
+
+local System = System
+local lengthFn = System.lengthFn
+local Array = System.Array
+local ArrayDictionary = System.ArrayDictionary
+
+local SortedList = {
+  __ctor__ = Array.ctorOrderDict,
+  getComparer = Array.getOrderComparer,
+  getCount = lengthFn,
+  getCapacity = lengthFn,
+  setCapacity = Array.setCapacity,
+  AddKeyValue = Array.addOrderDict,
+  AddKeyValueObj = Array.addOrderDictObj,
+  Add = Array.addPairOrderDict,
+  Clear = Array.clear,
+  ContainsKey = Array.containsOrderDict,
+  ContainsValue = ArrayDictionary.ContainsValue,
+  ContainsKeyObj = Array.containsOrderDictObj,
+  GetEnumerator = Array.GetEnumerator,
+  IndexOfKey = Array.indexKeyOrderDict,
+  IndexOfValue =  Array.indexOfValue,
+  RemoveKey = Array.removeOrderDict,
+  Remove =  Array.removePairOrderDict,
+  RemoveAt = Array.removeAt,
+  TrimExcess = System.emptyFn,
+  getKeys = ArrayDictionary.getKeys,
+  getValues = ArrayDictionary.getValues,
+  get = Array.getOrderDict,
+  getObj = Array.getOrderDictObj,
+  set = Array.setOrderDict,
+  setObj = Array.setOrderDictObj,
+}
+
+local SortedListFn = System.define("System.Collections.Generic.SortedList", function(TKey, TValue) 
+return { 
+  base = { System.IDictionary_2(TKey, TValue), System.IDictionary, System.IReadOnlyDictionary_2(TKey, TValue) },
+  __genericT__ = System.KeyValuePair(TKey, TValue),
+  __genericTKey__ = TKey,
+  __genericTValue__ = TValue,
+}
+end, SortedList, 2)
+
+System.SortedList = SortedListFn
+

+ 34 - 3
Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/Collections/SortedSet.lua.txt

@@ -15,11 +15,42 @@ limitations under the License.
 --]]
 
 local System = System
-local define = System.define
+local Array = System.Array
 
 local SortedSet = {
-  
+  __ctor__ = Array.ctorOrderSet,
+  getMin = Array.firstOrDefault,
+  getMax = Array.lastOrDefault,
+  getCount = System.lengthFn,
+  getComparer = Array.getOrderComparer,
+  CreateSetComparer = Array.createSetComparer,
+  Add = Array.addOrder,
+  Clear = Array.clear,
+  Contains = Array.containsOrder,
+  CopyTo = Array.CopyTo,
+  ExceptWith = Array.exceptWithOrder,
+  GetEnumerator = Array.GetEnumerator,
+  GetViewBetween = Array.getViewBetweenOrder,
+  IntersectWith = Array.intersectWithOrder,
+  IsProperSubsetOf = Array.isProperSubsetOfOrder,
+  IsProperSupersetOf = Array.isProperSupersetOfOrder,
+  IsSubsetOf = Array.isSubsetOfOrder,
+  IsSupersetOf = Array.isSupersetOfOrder,
+  Overlaps = Array.isOverlapsOrder,
+  Remove = Array.removeOrder,
+  RemoveWhere = Array.removeAll,
+  Reverse = Array.reverseEnumerable,
+  SetEquals = Array.equalsOrder,
+  SymmetricExceptWith = Array.symmetricExceptWithOrder,
+  TryGetValue = Array.tryGetValueOrder,
+  UnionWith = Array.addOrderRange,
 }
 
+local SortedSetFn = System.define("System.Collections.Generic.SortedSet", function(T) 
+  return { 
+    base = { System.ICollection_1(T), System.IReadOnlyCollection_1(T), System.ISet_1(T) }, 
+    __genericT__ = T,
+  }
+end, SortedSet, 1)
 
-
+System.SortedSet = SortedSetFn

+ 1 - 1
Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/Collections/Stack.lua.txt

@@ -39,7 +39,7 @@ local StackFn = System.define("System.Collections.Generic.Stack", function(T)
     base = { System.IEnumerable_1(T), System.ICollection },
     __genericT__ = T,
   }
-end, Stack)
+end, Stack, 1)
 
 System.Stack = StackFn
 System.stack = StackFn(System.Object)

+ 222 - 14
Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/Convert.lua.txt

@@ -20,9 +20,15 @@ local cast = System.cast
 local as = System.as
 local trunc = System.trunc
 local define = System.define
+local band = System.band
+local bor = System.bor
+local sl = System.sl
+local sr = System.sr
+local div = System.div
 local identityFn = System.identityFn
 local IConvertible = System.IConvertible
 local systemToString = System.toString
+local checkIndex = System.checkIndexAndCount
 
 local OverflowException = System.OverflowException
 local FormatException = System.FormatException
@@ -66,8 +72,10 @@ local sbyte = string.byte
 local math = math
 local floor = math.floor
 local tconcat = table.concat
+local setmetatable = setmetatable
 local getmetatable = getmetatable
 local tonumber = tonumber
+local select = select
 
 local function toBoolean(value)
   if value == nil then return false end
@@ -87,7 +95,7 @@ local function toChar(value)
   if value == nil then return 0 end
   local typename = type(value)
   if typename == "number" then
-    if value ~= floor(value) or value > 9223372036854775807 or value < -9223372036854775808 then
+    if value ~= floor(value) or value > 9223372036854775807 or value < (-9223372036854775807 - 1) then
       throw(InvalidCastException("InvalidCast_FromTo_Char"))
     end
     if value < 0 or value > 65535 then 
@@ -254,7 +262,7 @@ local function objectToInt64(value)
 end
 
 local function toInt64(value, fromBase)
-  return toNumber(value, -9223372036854775808, 9223372036854775807, ParseInt64, objectToInt64, fromBase) 
+  return toNumber(value, (-9223372036854775807 - 1), 9223372036854775807, ParseInt64, objectToInt64, fromBase) 
 end
 
 local function objectToUInt64(value)
@@ -341,14 +349,28 @@ local function changeType(value, conversionType)
   return ic.ToType(conversionType)
 end
 
+local rexp
+if math.frexp then
+  rexp = function (x)
+    local _, v = math.frexp(x)
+    return v
+  end
+else
+  local abs, log = math.abs, math.log
+  local log2 = log(2)
+  rexp = function (x)
+    return floor(log(abs(x)) / log2) + 1
+  end
+end
+
 local function toBits(num, bits)
   -- returns a table of bits, most significant first.
-  bits = bits or math.max(1, select(2, math.frexp(num)))
+  bits = bits or math.max(1, rexp(num))
   local t = {} -- will contain the bits        
   for b = bits, 1, -1 do
     local i =  num % 2
     t[b] = i
-    num = System.div(num - i, 2)
+    num = div(num - i, 2)
   end
   if bits == 64 and t[1] == 0 then
     return tconcat(t, nil, 2, bits)
@@ -383,6 +405,198 @@ local function toString(value, toBaseOrProvider, cast)
   return systemToString(value)
 end
 
+local base64Table = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O',
+                      'P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d',
+                      'e','f','g','h','i','j','k','l','m','n','o','p','q','r','s',
+                      't','u','v','w','x','y','z','0','1','2','3','4','5','6','7',
+                      '8','9','+','/','=' };
+
+local function toBase64String(t, ...)
+  if t == nil then throw(ArgumentNullException("inArray")) end
+  local n = select("#", ...)
+  local offset, length, options
+  if n == 0 then
+    offset, length, options = 0, #t, 0
+  elseif n == 1 then
+    offset, length, options = 0, #t, ...
+  elseif n == 2 then
+    options, offset, length = 0, ...
+    checkIndex(t, offset, length)
+  else
+    offset, length, options = ...
+    checkIndex(t, offset, length)
+  end
+  local insertLineBreaks, lengthmod3, outChars  = options == 1, length % 3, {}
+  local calcLength, j, charcount = offset + (length - lengthmod3), 1, 0
+  local i = offset
+  while i < calcLength do
+    if insertLineBreaks then
+      if charcount == 76 then
+        outChars[j] = "\r\n"
+        j = j + 1
+        charcount = 0
+      end
+      charcount = charcount + 4
+    end
+    local a, b, c = t:get(i), t:get(i + 1), t:get(i + 2)
+    outChars[j] =  base64Table[sr(band(a, 0xfc), 2) + 1]
+    outChars[j + 1] = base64Table[bor(sl(band(a, 0x03), 4), sr(band(b, 0xf0), 4)) + 1]
+    outChars[j + 2] = base64Table[bor(sl(band(b, 0x0f), 2), sr(band(c, 0xc0), 6)) + 1]
+    outChars[j + 3] = base64Table[band(c, 0x3f) + 1]
+    j = j + 4
+    i = i + 3
+  end
+
+  i = calcLength
+  if insertLineBreaks and lengthmod3 ~= 0 and charcount == 76 then
+    outChars[j] = "\r\n"
+    j = j + 1
+  end
+  
+  if lengthmod3 == 2 then
+    local a, b = t:get(i), t:get(i + 1)
+    outChars[j] =  base64Table[sr(band(a, 0xfc), 2) + 1]
+    outChars[j + 1] = base64Table[bor(sl(band(a, 0x03), 4), sr(band(b, 0xf0), 4)) + 1]
+    outChars[j + 2] = base64Table[sl(band(b, 0x0f), 2) + 1]
+    outChars[j + 3] = '='
+  elseif lengthmod3 == 1 then
+    local a = t:get(i)
+    outChars[j] =  base64Table[sr(band(a, 0xfc), 2) + 1]
+    outChars[j + 1] = base64Table[sl(band(a, 0x03), 4) + 1]
+    outChars[j + 2] = '='
+    outChars[j + 3] = '='
+  end
+  return tconcat(outChars)
+end
+
+local function fromBase64ComputeResultLength(s, len)
+  local usefulInputLength, padding = len, 0
+  for i = 1, len do
+    local c = sbyte(s, i)
+    if c <= 32 then
+      usefulInputLength = usefulInputLength - 1
+    elseif c == 61 then
+      usefulInputLength = usefulInputLength - 1
+      padding = padding + 1
+    end
+  end
+  if padding ~= 0 then
+    if padding == 1 then
+      padding = 2
+    elseif padding == 2 then
+      padding = 1
+    else
+      throw(FormatException("Format_BadBase64Char"))
+    end
+  end
+  return div(usefulInputLength, 4) * 3 + padding
+end
+
+local function FromBase64Decode(s, len, t, resultLength)
+  local i, j, codes, c, gotoEqualityCharEncountered = 1, 0, 0x000000ff
+  while true do
+    if i > len then
+      break
+    end
+    c = sbyte(s, i)
+    i = i + 1
+    if c >= 65 then
+      if c <= 90 then
+        c = c - 65
+      elseif c <= 122 then
+        c = c - 71 
+      end
+    else
+      if c == 43 then
+        c = 62
+      elseif c == 47 then
+        c = 63
+      elseif c == 13 or c == 10 or c == 32 or c == 9 then
+      elseif c == 61 then
+        gotoEqualityCharEncountered = true
+        break
+      else
+        throw(FormatException("Format_BadBase64Char"))
+      end
+    end
+    codes = bor(sl(codes, 6), c)
+    if (band(codes, 0x80000000)) ~= 0 then
+      if resultLength - j < 3 then
+        return - 1
+      end
+      t[j + 1] = band(sr(codes, 16), 0xff)
+      t[j + 2] = band(sr(codes, 8), 0xff)
+      t[j + 3] = band(codes, 0xff)
+      j = j + 3
+      codes = 0x000000ff
+    end
+  end
+
+  if gotoEqualityCharEncountered then
+    if i > len then
+      codes = sl(codes, 6)
+      if (band(codes, 0x80000000)) == 0 then
+        throw(FormatException("Format_BadBase64CharArrayLength"))
+      end
+
+      if j < 2 then
+        return - 1
+      end
+
+      t[j + 1] = band(sr(codes, 16), 0xff)
+      t[j + 2] = band(sr(codes, 8), 0xff)
+      j = j + 2
+      codes = 0x000000ff
+    else
+      while i < len do
+        c = sbyte(s, i)
+        if c ~= 32 and c ~= 10 and c ~= 13 and c ~= 9 then
+          break
+        end
+        i = i + 1
+      end
+
+      if i == len and sbyte(s, i) == 61 then
+        codes = sl(codes, 12)
+        if (band(codes, 0x80000000)) == 0 then
+          throw(FormatException(("Format_BadBase64CharArrayLength")))
+        end
+
+        if resultLength - j < 1 then
+          return - 1
+        end
+
+        t[j + 1] = band(sr(codes, 16), 0xff)
+        j = j + 1
+        codes = 0x000000ff
+      else
+        System.throw(System.FormatException(("Format_BadBase64Char")))
+      end
+    end
+  end
+
+  if codes ~= 0x000000ff then
+    throw(FormatException(("Format_BadBase64CharArrayLength")))
+  end
+  return j
+end
+
+local function fromBase64String(s)
+  if s == nil then throw(ArgumentNullException("s")) end
+  local len = #s
+  while len > 0 do
+    local lastChar = sbyte(s, len)
+    if lastChar ~= 32 and lastChar ~= 10 and lastChar ~= 13 and lastChar ~= 9 then
+      break
+    end
+    len = len - 1
+  end
+  local resultLength = fromBase64ComputeResultLength(s, len)
+  local t = {}
+  FromBase64Decode(s, len, t, resultLength)
+  return System.arrayFromTable(t, Byte)
+end
+
 define("System.Convert", {
   ToBoolean = toBoolean,
   ToChar = toChar,
@@ -397,6 +611,8 @@ define("System.Convert", {
   ToSingle = toSingle,
   ToDouble = toDouble,
   ToDateTime = toDateTime,
+  ToBase64String = toBase64String,
+  FromBase64String = fromBase64String,
   ChangeType = changeType,
   ToString = toString,
   ToStringFromChar = string.char
@@ -467,13 +683,7 @@ DateTime.ToDouble = throwInvalidCastException
 DateTime.ToDateTime = identityFn
 DateTime.ToType = defaultToType
 
-
 -- BitConverter
-local band = System.band
-local bor = System.bor
-local sl = System.sl
-local sr = System.sr
-local div = System.div
 local global = System.global
 local systemToInt16 = System.toInt16
 local systemToInt32 = System.toInt32
@@ -494,7 +704,7 @@ if rawget(global, "jit") then
   end
 else 
   local dump = string.dump
-  if dump and sbyte(dump(System.emptyFn, 7)) == 0x00 then
+  if dump and sbyte(dump(System.emptyFn), 7) == 0x00 then
     isLittleEndian = false
   end
 end
@@ -518,7 +728,7 @@ local spack, sunpack, getBytesFromInt64, toInt64
 if System.luaVersion < 5.3 then
   local struct = rawget(global, "struct")
   if struct then
-    spack, sunpack = struct.pack, struct.upack
+    spack, sunpack = struct.pack, struct.unpack
   end
   if not spack then
     spack = function ()
@@ -755,13 +965,11 @@ local function toString(value, startIndex, length)
 end
 
 local function doubleToInt64Bits(value)
-  assert(isLittleEndian, "This method is implemented assuming little endian with an ambiguous spec.")
   local s = spack("d", value)
   return (sunpack("i8", s))
 end
 
 local function int64BitsToDouble(value)
-  assert(isLittleEndian, "This method is implemented assuming little endian with an ambiguous spec.")
   local s = spack("i8", value)
   return (sunpack("d", s))
 end

+ 87 - 45
Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/Core.lua.txt

@@ -136,10 +136,15 @@ local function set(className, cls)
   end
 end
 
-local function multiKey(t, ...)
+local function multiKey(t, f, ...)
   local n, i, k = select("#", ...), 1
   while true do
-    k = assert(select(i, ...))
+    local arg = assert(select(i, ...))
+    if f then
+      k = f(arg)
+    else
+      k = arg
+    end
     if i == n then
       break
     end
@@ -155,9 +160,6 @@ local function multiKey(t, ...)
 end
 
 local function genericName(name, ...)
-  if name:byte(-2) == 95 then
-    name = ssub(name, 1, -3)
-  end
   local n = select("#", ...)
   local t = { name, "`", n, "[" }
   local count = 5
@@ -319,45 +321,78 @@ local function defCore(name, kind, cls, generic)
   return cls
 end
 
-local function def(name, kind, cls, generic)
-  if type(cls) == "function" then
-    local mt = {}
-    local fn = function(_, ...)
-      local gt, gk = multiKey(mt, ...)
-      local t = gt[gk]
-      if t == nil then
-        local class, super  = cls(...)
-        t = defCore(genericName(name, ...), kind, class or {}, true)
-        if generic then
-          setmetatable(t, super or generic)
-        end
-        gt[gk] = t
+local genericClassKey = {}
+local function getGenericClass(cls)
+  return cls[genericClassKey]
+end
+
+local function getDefGenericClass(name, kind, generic, genericArgumentCount)
+  local genericClass, genericBaseName
+  if generic then
+    generic.__index = generic
+    generic.__call = new
+    genericClass = generic
+  else
+    genericClass = {}
+  end
+  genericClass[genericClassKey] = genericClass
+  if kind == 'I' then
+    genericClass.class = 'I'
+  end
+  local _, i = name:find('.*_')
+  if i then
+    genericBaseName = name:sub(1, i - 1)
+    genericArgumentCount = name:sub(i + 1, i + 1)
+  else
+    genericBaseName = name
+    if not genericArgumentCount then error(name .. ' has not pass genericArgumentCount') end
+  end
+  genericClass.__name__ = genericBaseName .. '`' .. genericArgumentCount
+  return genericClass, genericBaseName
+end
+
+local function defGeneric(name, kind, cls, generic, ...)
+  local genericClass, genericBaseName = getDefGenericClass(name, kind, generic, ...)
+  local mt = {}
+  local fn = function(_, ...)
+    local gt, gk = multiKey(mt, nil, ...)
+    local t = gt[gk]
+    if t == nil then
+      local class, super  = cls(...)
+      t = class or {}
+      t[genericClassKey] = genericClass
+      defCore(genericName(genericBaseName, ...), kind, t, true)
+      if generic then
+        setmetatable(t, super or generic)
       end
-      return t
+      gt[gk] = t
     end
+    return t
+  end
 
-    local base = kind ~= "S" and Object or ValueType
-    local caller = setmetatable({ __call = fn, __index = base }, base)
-    if generic then
-      generic.__index = generic
-      generic.__call = new
-    end
-    return set(name, setmetatable(generic or {}, caller))
+  local base = kind ~= "S" and Object or ValueType
+  local caller = setmetatable({ __call = fn, __index = base }, base)
+  return set(name, setmetatable(genericClass, caller))
+end
+
+local function def(name, kind, cls, ...)
+  if type(cls) == "function" then
+    return defGeneric(name, kind, cls, ...)
   else
-    return defCore(name, kind, cls, generic)
+    return defCore(name, kind, cls, ...)
   end
 end
 
-local function defCls(name, cls, generic)
-  return def(name, "C", cls, generic)
+local function defCls(name, cls, ...)
+  return def(name, "C", cls, ...)
 end
 
-local function defInf(name, cls)
-  return def(name, "I", cls)
+local function defInf(name, cls, ...)
+  return def(name, "I", cls, ...)
 end
 
-local function defStc(name, cls, generic)
-  return def(name, "S", cls, generic)
+local function defStc(name, cls, ...)
+  return def(name, "S", cls, ...)
 end
 
 local function defEnum(name, cls)
@@ -382,7 +417,7 @@ local function defArray(name, cls, Array, MultiArray)
 
   local mtMulti = {}
   local function createMulti(MultiArray, T, dimension)
-    local gt, gk = multiKey(mtMulti, T, dimension)
+    local gt, gk = multiKey(mtMulti, nil, T, dimension)
     local ArrayT = gt[gk]
     if ArrayT == nil then
       local name = T.__name__ .. "[" .. (","):rep(dimension - 1) .. "]"
@@ -429,6 +464,7 @@ System = {
   throw = throw,
   getClass = set,
   multiKey = multiKey,
+  getGenericClass = getGenericClass,
   define = defCls,
   defInf = defInf,
   defStc = defStc,
@@ -604,7 +640,7 @@ if version < 5.3 then
   end
 
   function System.toInt64(v, checked) 
-    if v >= -9223372036854775808 and v <= 9223372036854775807 then
+    if v >= (-9223372036854775807 - 1) and v <= 9223372036854775807 then
       return v
     end
     if checked then
@@ -778,7 +814,7 @@ else
   end
 
   function System.toInt64(v, checked)
-    return toInt(v, -9223372036854775808, 9223372036854775807, 0xffffffffffffffff, 0x7fffffffffffffff, checked)
+    return toInt(v, (-9223372036854775807 - 1), 9223372036854775807, 0xffffffffffffffff, 0x7fffffffffffffff, checked)
   end
 
   function System.toUInt64(v, checked)
@@ -860,13 +896,13 @@ end
 
 function System.ToInt64(v, checked)
   v = trunc(v)
-  if v >= -9223372036854775808 and v <= 9223372036854775807 then
+  if v >= (-9223372036854775807 - 1) and v <= 9223372036854775807 then
     return v
   end
   if checked then
     throw(System.OverflowException(), 1) 
   end
-  return -9223372036854775808
+  return (-9223372036854775807 - 1)
 end
 
 function System.ToSingle(v, checked)
@@ -923,10 +959,13 @@ function System.default(T)
   return T:default()
 end
 
-function System.property(name)
+function System.property(name, onlyget)
   local function g(this)
     return this[name]
   end
+  if onlyget then
+    return g
+  end
   local function s(this, v)
     this[name] = v
   end
@@ -977,8 +1016,8 @@ if debugsetmetatable then
     throw(System.ArgumentException("Argument_ImplementIComparable"))
   end
 
-  toString = function (t)
-    return t ~= nil and t:ToString() or ""
+  toString = function (t, format)
+    return t ~= nil and t:ToString(format) or ""
   end
 
   debugsetmetatable(nil, {
@@ -1075,15 +1114,17 @@ else
     throw(System.ArgumentException("Argument_ImplementIComparable"))
   end
 
-  toString = function (obj)
+  toString = function (obj, format)
     if obj == nil then return "" end
     local t = type(obj) 
     if t == "table" then
-      return obj:ToString()
+      return obj:ToString(format)
     elseif t == "boolean" then
       return obj and "True" or "False"
     elseif t == "function" then
       return "System.Delegate"
+    elseif t == "Number" and format then
+      return System.Number.ToString(obj, format)
     end
     return tostring(obj)
   end
@@ -1278,6 +1319,7 @@ local ValueTuple = defStc("System.ValueTuple", {
     throw(System.NotSupportedException("not support default(T) when T is ValueTuple"))
   end
 })
+
 local valueTupleMetaTable = setmetatable({ __index  = ValueType, __call = tupleCreate }, ValueType)
 setmetatable(ValueTuple, valueTupleMetaTable)
 
@@ -1385,7 +1427,7 @@ defStc("System.Nullable", function (T)
   return { 
     __genericT__ = T 
   }
-end, Nullable)
+end, Nullable, 1)
 
 function System.isNullable(T)
   return getmetatable(T) == Nullable
@@ -1478,7 +1520,7 @@ local function defIn(kind, name, f)
   end
   assert(modules[name] == nil, name)
   namespace[1], namespace[2] = name, kind == "C" or kind == "S"
-  local t = f(assembly)
+  local t = f(assembly, global)
   namespace[1], namespace[2] = namespaceName, isClass
   modules[isClass and name:gsub("+", ".") or name] = function()
     return def(name, kind, t)

+ 194 - 2
Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/DateTime.lua.txt

@@ -190,6 +190,7 @@ local function getTimeZone()
 end
 
 local timeZoneTicks, dstTicks = getTimeZone()
+local baseUtcOffset = TimeSpan(timeZoneTicks)
 
 local time = System.config.time or ostime
 System.time = time
@@ -262,6 +263,194 @@ local function parse(s)
   return DateTime(year, month, day, hour, minute, second, milliseconds)
 end
 
+local abbreviatedDayNames = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }
+local dayNames = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"	 }
+local abbreviatedMonthNames = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }
+local monthNames = { "January",	"February",	"March", "April",	"May", "June", "July", "August", "September", "October", "November", "December" }
+
+local realFormats = {
+  ["d"] = "MM/dd/yyyy",
+  ["D"] = "dddd, dd MMMM yyyy",
+  ["f"] = "dddd, dd MMMM yyyy HH:mm",
+  ["F"] = "dddd, dd MMMM yyyy HH:mm:ss",
+  ["g"] = "MM/dd/yyyy HH:mm",
+  ["G"] = "MM/dd/yyyy HH:mm:ss",
+  ["m"] = "MMMM dd",
+  ["M"] = "MMMM dd",
+  ["o"] = "yyyy-MM-ddTHH:mm:ss.fffffffK",
+  ["O"] = "yyyy-MM-ddTHH:mm:ss.fffffffK",
+  ["r"] = "ddd, dd MMM yyyy HH:mm:ss GMT",
+  ["R"] = "ddd, dd MMM yyyy HH:mm:ss GMT",
+  ["s"] = "yyyy-MM-ddTHH:mm:ss",
+  ["t"] = "HH:mm",
+  ["T"] = "HH:mm:ss",
+  ["u"] = "yyyy-MM-dd HH:mm:ssZ",
+  ["U"] = "dddd, dd MMMM yyyy HH:mm:ss",
+  ["y"] = "yyyy MMMM",
+  ["Y"] = "yyyy MMMM"
+}
+
+local function parseRepeatPattern(format, n, pos, ch)
+  local index = pos + 1
+  while index <= n and format:byte(index) == ch do
+    index = index + 1
+  end
+  return index - pos
+end
+
+local function throwFormatInvalidException()
+  throw(FormatException("Input string was not in a correct format."))
+end
+
+local function formatCustomized(this, format, n)
+  local t, i, tokenLen, hour12 = {}, 1
+  while i <= n do
+    local ch = format:byte(i)
+    if ch == 104 then
+      tokenLen = parseRepeatPattern(format, n, i, ch)
+      hour12 = this:getHour() % 12
+      if hour12 == 0 then hour12 = 12 end
+      t[#t + 1] = sformat("%02d", hour12)
+    elseif ch == 72 then
+      tokenLen = parseRepeatPattern(format, n, i, ch)
+      t[#t + 1] = sformat("%02d", this:getHour())
+    elseif ch == 109 then
+      tokenLen = parseRepeatPattern(format, n, i, ch)
+      t[#t + 1] = sformat("%02d", this:getMinute())
+    elseif ch == 115 then
+      tokenLen = parseRepeatPattern(format, n, i, ch)
+      t[#t + 1] = sformat("%02d", this:getSecond())
+    elseif ch == 102 or ch == 70 then
+      tokenLen = parseRepeatPattern(format, n, i, ch)
+      if tokenLen <= 7 then
+        local fraction = this.ticks % 10000000
+        fraction = div(fraction, 10 ^ (7 - tokenLen))
+        if ch == 102 then
+          t[#t + 1] = sformat("%0" .. tokenLen .. 'd', fraction)
+        else
+          local effectiveDigits = tokenLen
+          while effectiveDigits > 0 do
+            if fraction % 10 == 0 then
+              fraction = div(fraction, 10)
+              effectiveDigits = effectiveDigits - 1
+            else 
+              break
+            end
+          end
+          if effectiveDigits > 0 then
+            t[#t + 1] = sformat("%0" .. effectiveDigits .. 'd', fraction)
+          end
+        end
+      else
+        throwFormatInvalidException()
+      end
+    elseif ch == 116 then
+      tokenLen = parseRepeatPattern(format, n, i, ch)
+      local hour = this:getHour()
+      if tokenLen == 1 then
+        t[#t + 1] = hour < 12 and "A" or "P"
+      else
+        t[#t + 1] = hour < 12 and "AM" or "PM"
+      end
+    elseif ch == 100 then
+      tokenLen = parseRepeatPattern(format, n, i, ch)
+      if tokenLen <= 2 then
+        local day = this:getDay()
+        t[#t + 1] = sformat("%0" .. tokenLen .. 'd', day)
+      else
+        local i = this:getDayOfWeek() + 1
+        t[#t + 1] = (tokenLen == 3 and abbreviatedDayNames or dayNames)[i]
+      end
+    elseif ch == 77 then
+      tokenLen = parseRepeatPattern(format, n, i, ch)
+      local month = this:getMonth()
+      if tokenLen <= 2 then
+        t[#t + 1] = sformat("%0" .. tokenLen .. 'd', month)
+      else
+        t[#t + 1] = (tokenLen == 3 and abbreviatedMonthNames or monthNames)[month]
+      end
+    elseif ch == 121 then
+      tokenLen = parseRepeatPattern(format, n, i, ch)
+      local year = this:getYear()
+      if tokenLen <= 2 then
+        year = year % 100
+        t[#t + 1] = tokenLen == 1 and year or sformat("%02d", year)
+      else
+        t[#t + 1] = sformat("%0" .. tokenLen .. 'd', year)
+      end
+    elseif ch == 122 then
+      tokenLen = parseRepeatPattern(format, n, i, ch)
+      local offset = this.kind == 1 and TimeSpan.Zero or baseUtcOffset
+      local sign
+      if offset.ticks >= 0 then
+        sign = "+"
+      else
+        sign = "-"
+        offset = offset:Negate()
+      end
+      local hour = offset:getHours()
+      if tokenLen <= 1 then
+        t[#t + 1] = sformat("%s%d", sign, hour)
+      elseif tokenLen < 3 then
+        t[#t + 1] = sformat("%s%02d", sign, hour)
+      else
+        t[#t + 1] = sformat("%s%02d:%02d", sign, hour, offset:getMinutes())
+      end
+    elseif ch == 75 then
+      tokenLen = 1
+      if this.kind == 2 then
+        local offset = baseUtcOffset
+        local sign
+        if offset.ticks >= 0 then
+          sign = "+"
+        else
+          sign = "-"
+          offset = offset:Negate()
+        end
+        t[#t + 1] = sformat("%s%02d:%02d", sign, offset:getHours(), offset:getMinutes())
+      elseif this.kind == 1 then
+        t[#t + 1] = "Z"
+      end
+    elseif ch == 39 or ch == 34 then
+      local a, b, c = sfind(format, "^(.*)" .. string.char(ch), i + 1)
+      if not a then throwFormatInvalidException() end
+      t[#t + 1] = c
+      tokenLen = b - a + 2
+    elseif ch == 37 then
+      local nextChar = format:byte(i + 1)
+      if nextChar and nextChar ~= 37 then
+        t[#t + 1] = formatCustomized(this, string.char(nextChar), 1)
+        tokenLen = 2
+      else
+        throwFormatInvalidException()
+      end
+    elseif ch == 92 then
+      local nextChar = format:byte(i + 1)
+      if nextChar then
+        t[#t + 1] = string.char(nextChar)
+        tokenLen = 2
+      else
+        throwFormatInvalidException()
+      end
+    else
+      t[#t + 1] = string.char(ch)
+      tokenLen = 1
+    end
+    i = i + tokenLen
+  end
+  return table.concat(t)
+end
+
+local function toStringWithFormat(this, format)
+  local n = #format
+  if n == 1 then
+    format = realFormats[format]
+    if not format then throwFormatInvalidException() end
+    return formatCustomized(this, format, #format)
+  end
+  return formatCustomized(this, format, n)
+end
+
 DateTime = System.defStc("System.DateTime", {
   ticks = 0,
   kind = 0,
@@ -378,7 +567,7 @@ DateTime = System.defStc("System.DateTime", {
   getTicks = function (this)
     return this.ticks
   end,
-  BaseUtcOffset = TimeSpan(timeZoneTicks),
+  BaseUtcOffset = baseUtcOffset,
   getUtcNow = function ()
     local seconds = time()
     local ticks = seconds * 10000000 + 621355968000000000
@@ -405,7 +594,10 @@ DateTime = System.defStc("System.DateTime", {
   IsDaylightSavingTime = function(this)
     return this.kind == 2 and dstTicks > 0
   end,
-  ToString = function (this)
+  ToString = function (this, format)
+    if format then 
+      return toStringWithFormat(this, format) 
+    end
     local year, month, day = getDatePart(this.ticks)
     return sformat("%d/%d/%d %02d:%02d:%02d", year, month, day, this:getHour(), this:getMinute(), this:getSecond())
   end,

+ 3 - 3
Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/Delegate.lua.txt

@@ -135,7 +135,7 @@ local multiKey = System.multiKey
 
 local mt = {}
 local function makeGenericTypes(...)
-  local gt, gk = multiKey(mt, ...)
+  local gt, gk = multiKey(mt, nil, ...)
   local t = gt[gk]
   if t == nil then
     t = setmetatable({ ... }, Delegate)
@@ -247,7 +247,7 @@ local binds = setmetatable({}, { __mode = "k" })
 
 function System.bind(f, n, ...)
   assert(f)
-  local gt, gk = multiKey(binds, f, ...)
+  local gt, gk = multiKey(binds, nil, f, ...)
   local fn = gt[gk]
   if fn == nil then
     local args = { ... }
@@ -276,7 +276,7 @@ end
 
 local function bind(f, create, ...)
   assert(f)
-  local gt, gk = multiKey(binds, f, create)
+  local gt, gk = multiKey(binds, nil, f, create)
   local fn = gt[gk]
   if fn == nil then
     fn = create(f, ...)

+ 44 - 5
Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/Exception.lua.txt

@@ -17,18 +17,56 @@ limitations under the License.
 local System = System
 local define = System.define
 local Object = System.Object
+local toString = System.toString
 
 local tconcat = table.concat
 local type = type
 local debug = debug
+local assert = assert
+local select = select
+
+local traceback = (debug and debug.traceback) or System.config.traceback or function () return "" end
+System.traceback = traceback
+
+local resource = {
+  Arg_KeyNotFound = "The given key was not present in the dictionary.",
+  Arg_KeyNotFoundWithKey = "The given key '%s' was not present in the dictionary.",
+  Arg_WrongType = "The value '%s' is not of type '%s' and cannot be used in this generic collection.",
+  Arg_ParamName_Name = "(Parameter '%s')",
+  Argument_AddingDuplicate = "An item with the same key has already been added. Key: %s",
+  ArgumentOutOfRange_SmallCapacity = "capacity was less than the current size.",
+  InvalidOperation_EmptyQueue = "Queue empty.",
+  ArgumentOutOfRange_NeedNonNegNum = "Non-negative number required.",
+}
+
+local function getResource(t, k)
+  local s = resource[k]
+  assert(s, k)
+  return function (...)
+	local n = select("#", ...)
+    local f
+    if n == 0 then
+      f = function () return s end
+    elseif n == 1 then
+      f = function (x1) return s:format(toString(x1)) end
+    elseif n == 2 then
+      f = function (x1, x2) return s:format(toString(x1), toString(x2)) end
+    elseif n == 3 then
+      f = function (x1, x2, x3) return s:format(toString(x1), toString(x2), toString(x3)) end
+    else
+      assert(false)
+    end
+    t[k] = f
+    return f(...)
+  end
+end
+
+System.er = setmetatable({}, { __index = getResource })
 
 local function getMessage(this)
   return this.message or ("Exception of type '%s' was thrown."):format(this.__name__)
 end
 
-local traceback = (debug and debug.traceback) or System.config.traceback or function () return "" end
-System.traceback = traceback
-
 local function toString(this)
   local t = { this.__name__ }
   local count = 2
@@ -94,7 +132,7 @@ local ArgumentException = define("System.ArgumentException", {
     ctorOfException(this, message or "Value does not fall within the expected range.", innerException)
     this.paramName = paramName
     if paramName and #paramName > 0 then
-      this.message = this.message .. "\nParameter name: " .. paramName
+      this.message = this.message .. " " .. resource.Arg_ParamName_Name:format(paramName)
     end
   end,
   getParamName = function(this) 
@@ -159,7 +197,7 @@ local KeyNotFoundException = define("System.Collections.Generic.KeyNotFoundExcep
   __tostring = toString,
   base = { SystemException },
   __ctor__ = function(this, message, innerException) 
-    ctorOfException(this, message or "The given key was not present in the dictionary.", innerException)
+    ctorOfException(this, message or resource.Arg_KeyNotFound, innerException)
   end
 })
 System.KeyNotFoundException = KeyNotFoundException
@@ -315,3 +353,4 @@ System.SwitchExpressionException = define("System.Runtime.CompilerServices", {
     ctorOfException(this, message or "Non-exhaustive switch expression failed to match its input.", innerException)
   end
 })
+

+ 14 - 7
Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/Math.lua.txt

@@ -22,6 +22,7 @@ local floor = math.floor
 local min = math.min
 local max = math.max
 local abs = math.abs
+local log = math.log
 
 local function bigMul(a, b)
   return a * b
@@ -99,11 +100,17 @@ local function truncate(d)
   return trunc(d) * 1.0
 end
 
+local log10 = math.log10
+if not log10 then
+  log10 = function (x) return log(x, 10) end
+  math.log10 = log10
+end
+
 local exp = math.exp
-local cosh = math.cosh or function(x) return (exp(x) + exp(-x)) / 2.0 end
-local pow = math.pow or function(x, y) return x ^ y end
-local sinh = math.sinh or function(x) return (exp(x) - exp(-x)) / 2.0 end
-local tanh = math.tanh or function(x) return sinh(x) / cosh(x) end
+local cosh = math.cosh or function (x) return (exp(x) + exp(-x)) / 2.0 end
+local pow = math.pow or function (x, y) return x ^ y end
+local sinh = math.sinh or function (x) return (exp(x) - exp(-x)) / 2.0 end
+local tanh = math.tanh or function (x) return sinh(x) / cosh(x) end
 
 local Math = math
 Math.Abs = abs
@@ -120,8 +127,8 @@ Math.DivRem = divRem
 Math.Exp = exp
 Math.Floor = math.floor
 Math.IEEERemainder = IEEERemainder
-Math.Log = math.log
-Math.Log10 = math.log10
+Math.Log = log
+Math.Log10 = log10
 Math.Max = math.max
 Math.Min = math.min
 Math.Pow = pow
@@ -134,4 +141,4 @@ Math.Tan = math.tan
 Math.Tanh = tanh
 Math.Truncate = truncate
 
-System.define("System.Math", Math)
+System.define("System.Math", Math)

+ 2 - 2
Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/Number.lua.txt

@@ -218,10 +218,10 @@ setmetatable(UInt32, Int)
 
 local Int64 = define("System.Int64", {
   Parse = function (s)
-    return parseIntWithException(s, -9223372036854775808, 9223372036854775807)
+    return parseIntWithException(s, (-9223372036854775807 - 1), 9223372036854775807)
   end,
   TryParse = function (s)
-    return tryParseInt(s, -9223372036854775808, 9223372036854775807)
+    return tryParseInt(s, (-9223372036854775807 - 1), 9223372036854775807)
   end
 })
 setmetatable(Int64, Int)

+ 13 - 7
Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/Reflection/Assembly.lua.txt

@@ -39,6 +39,7 @@ local rawget = rawget
 local type = type
 local unpack = table.unpack
 local select = select
+local floor = math.floor
 
 local TargetException = define("System.Reflection.TargetException", {
   __tostring = Exception.ToString,
@@ -402,7 +403,7 @@ local function getMethodParameterCount(flags)
   if count ~= 0 then
     count = count / 256
   end
-  return count
+  return floor(count)
 end
 
 local function getMethodAttributesIndex(metadata)
@@ -438,7 +439,7 @@ local MethodInfo = define("System.Reflection.MethodInfo", {
     if band(flags, 0xC00) > 0 then
       assert(false, "not implement for generic method")
     end
-    local parameterCount = band(flags, 0x300)
+    local parameterCount = getMethodParameterCount(flags)
     return typeof(metadata[4 + parameterCount])
   end,
   Invoke = function (this, obj, parameters)
@@ -448,8 +449,8 @@ local MethodInfo = define("System.Reflection.MethodInfo", {
       if checkTarget(cls, obj, metadata) then
         isStatic = true
       end
-      local t
-      local parameterCount = band(metadata[2], 0x300)
+      local t = {}
+      local parameterCount = getMethodParameterCount(metadata[2])
       if parameterCount == 0 then
         if parameters ~= nil and #parameters > 0 then
           throw(TargetParameterCountException())
@@ -460,7 +461,11 @@ local MethodInfo = define("System.Reflection.MethodInfo", {
         end
         for i = 4, 3 + parameterCount do
           local j = #t
-          t[j + 1] = checkValue(parameters:get(j), metadata[i])
+          local paramValue, mtData = parameters:get(j), metadata[i]
+          if mtData ~= nil then
+            paramValue = checkValue(paramValue, mtData)
+          end
+          t[j + 1] = paramValue
         end
       end
       local f = metadata[3]
@@ -888,15 +893,16 @@ function Type.GetGenericArguments(this)
   local name = cls.__name__ 
   local i = name:find("%[")
   if i then
+    i = i + 1
     while true do
-      i = i + 1
       local j = name:find(",", i) or -1
       local clsName = name:sub(i, j - 1)
       t[count] = typeof(System.getClass(clsName))
-      count = count + 1
       if j == -1 then
         break
       end
+      count = count + 1
+      i = j + 1
     end
   end
   return arrayFromTable(t, Type)

+ 28 - 7
Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/String.lua.txt

@@ -44,11 +44,12 @@ local getmetatable = getmetatable
 local setmetatable = setmetatable
 local select = select
 local type = type
+local tonumber = tonumber
 local String
 
-local function toString(t, isch)
+local function toString(t, isch, format)
   if isch then return char(t) end
-  return systemToString(t)
+  return systemToString(t, format)
 end
 
 local function checkIndex(value, startIndex, count)
@@ -218,14 +219,34 @@ local function formatBuild(format, len, select, ...)
       count = count + 1
       startPos = i
     end
-    i, j, s = find(format, "^(%d+)}", i)
+    local r, alignment, formatString
+    i, j, s, r = find(format, "^(%d+)(.-)}", i)
     if not i then throwFormatError() end
-    s = s + 1
+    s = tonumber(s) + 1
     if s > len then throwFormatError() end
+    if r ~= "" then
+      local i, j, c, d = find(r, "^,([-]?)(%d+)")
+      if i then
+        alignment = tonumber(d)
+        if c == '-' then alignment = -alignment end
+        i = j + 1
+      end
+      i, j, c = find(r, "^:(.*)$", i)
+      if i then
+        formatString = c
+      elseif not alignment then
+        throwFormatError()
+      end
+    end
     s = select(s, ...)
-    s = (s ~= nil and s ~= System.null) and toString(s)
-    t[count] = s
-    count = count + 1
+    if s ~= nil and s ~= System.null then
+      s = toString(s, false, formatString)
+      if alignment then
+        s = ("%" .. alignment .. "s"):format(s)
+      end
+      t[count] = s
+      count = count + 1
+    end
     i = j + 1
   end
 end

+ 968 - 0
Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/Threading/Task.lua

@@ -0,0 +1,968 @@
+--[[
+Copyright 2017 YANG Huan (sy.yanghuan@gmail.com).
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+--]]
+
+local System = System
+local define = System.define
+local defStc = System.defStc
+local throw = System.throw
+local try = System.try
+local trunc = System.trunc
+local Void = System.Void
+local post = System.post
+local addTimer = System.addTimer
+local removeTimer = System.removeTimer
+local waitTask = System.Thread.waitTask
+local arrayFromTable = System.arrayFromTable
+local Exception = System.Exception
+local NullReferenceException = System.NullReferenceException
+local NotImplementedException = System.NotImplementedException
+local ArgumentException = System.ArgumentException
+local ArgumentNullException = System.ArgumentNullException
+local ArgumentOutOfRangeException = System.ArgumentOutOfRangeException
+local InvalidOperationException = System.InvalidOperationException
+local AggregateException = System.AggregateException
+local ObjectDisposedException = System.ObjectDisposedException
+
+local ccreate = System.ccreate
+local cpool = System.cpool
+local cresume = System.cresume
+local cyield = System.yield
+
+local type = type
+local table = table
+local select = select
+local assert = assert
+local getmetatable = getmetatable
+local setmetatable = setmetatable
+local tremove = table.remove
+local pack = table.pack
+local unpack = table.unpack
+local error = error
+
+local TaskCanceledException = define("System.Threading.Tasks.TaskCanceledException", {
+  __tostring = Exception.ToString,
+  base = { Exception },
+  __ctor__ = function (this, task)
+    this.task = task  
+    Exception.__ctor__(this, "A task was canceled.")
+  end,
+  getTask = function(this) 
+    return this.task
+  end
+})
+System.TaskCanceledException = TaskCanceledException
+
+local TaskStatusCreated = 0
+local TaskStatusWaitingForActivation = 1
+local TaskStatusWaitingToRun = 2
+local TaskStatusRunning = 3
+local TaskStatusWaitingForChildrenToComplete = 4
+local TaskStatusRanToCompletion = 5
+local TaskStatusCanceled = 6
+local TaskStatusFaulted = 7
+
+System.TaskStatus = System.defEnum("System.Threading.Tasks.TaskStatus", {
+  Created = TaskStatusCreated,
+  WaitingForActivation = TaskStatusWaitingForActivation,
+  WaitingToRun = TaskStatusWaitingToRun,
+  Running = TaskStatusRunning,
+  WaitingForChildrenToComplete = TaskStatusWaitingForChildrenToComplete,
+  RanToCompletion = TaskStatusRanToCompletion,
+  Canceled = TaskStatusCanceled,
+  Faulted = TaskStatusFaulted,
+})
+
+local UnobservedTaskExceptionEventArgs = define("System.Threading.Tasks.UnobservedTaskExceptionEventArgs", {
+  __ctor__ = function (this, exception)
+    this.exception = exception
+  end,
+  SetObserved = function (this)
+    this.observed = true
+  end,
+  getObserved = function (this)
+    if this.observed then
+      return true
+    end
+    return false
+  end,
+  getException = function (this)
+    return this.exception
+  end
+})
+System.UnobservedTaskExceptionEventArgs = UnobservedTaskExceptionEventArgs
+
+local unobservedTaskException
+local function publishUnobservedTaskException(sender, ueea)
+  local handler = unobservedTaskException
+  if handler then
+    handler(sender, ueea)
+  end
+end
+
+local TaskScheduler = define("System.Threading.Tasks.TaskScheduler", {
+  addUnobservedTaskException = function (value)
+    unobservedTaskException = unobservedTaskException + value
+  end,
+  removeUnobservedTaskException = function (value)
+    unobservedTaskException = unobservedTaskException - value
+  end
+})
+System.TaskScheduler = TaskScheduler
+
+local TaskExceptionHolder = {
+  __index = false,
+  __gc = function (this)
+    if not this.isHandled then
+      local e = this.exception
+      if e then
+        local ueea = UnobservedTaskExceptionEventArgs(e)
+        publishUnobservedTaskException(this.task, ueea)
+        if not ueea.observed then
+          print("Warning: TaskExceptionHolder" , e)
+        end
+      end
+    end
+  end
+}
+TaskExceptionHolder.__index = TaskExceptionHolder
+
+local function newTaskExceptionHolder(task, exception) 
+  return setmetatable({ task = task, exception = exception }, TaskExceptionHolder)
+end
+
+local function getException(task, await)
+  local holder = task.data
+  if not holder.isHandled then
+    holder.isHandled = true
+  end
+  local e = holder.exception
+  if await then
+    return e
+  end
+  return AggregateException(e)
+end
+
+local Task
+local nextTaskId = 1
+local currentTask
+local completedTask
+
+local function getNewId()
+  local id = nextTaskId
+  nextTaskId = nextTaskId + 1
+  return id
+end
+
+local function getId(this)
+  local id = this.id
+  if id == nil then
+    id = getNewId()
+    this.id = id
+  end
+  return id 
+end
+
+local function isCompleted(this)
+  local status = this.status
+  return status == TaskStatusRanToCompletion or status == TaskStatusFaulted or status == TaskStatusCanceled
+end
+
+local function newTask(status, data)
+  return setmetatable({ status = status, data = data }, Task)
+end
+
+local function fromResult(result)
+  return newTask(TaskStatusRanToCompletion, result)
+end
+
+local function fromCanceled(cancellationToken)
+  if cancellationToken and cancellationToken:getIsCancellationRequested() then 
+    throw(ArgumentOutOfRangeException("cancellationToken"))
+  end
+  return newTask(TaskStatusCanceled, cancellationToken)
+end
+
+local function fromException(exception)
+  local data = newTaskExceptionHolder(false, exception)
+  local t = newTask(TaskStatusFaulted, data) 
+  data.task = t
+  return t
+end
+
+local function getCompletedTask()
+  local t = completedTask
+  if t == nil then
+    t = fromResult()
+    completedTask = t
+  end
+  return t
+end
+
+local function trySetComplete(this, status, data)
+  if isCompleted(this) then
+    return false
+  end
+
+  this.status = status
+  this.data = data
+
+  local continueActions = this.continueActions
+  if continueActions then
+    for i = 1, #continueActions do
+      continueActions[i](this)
+    end
+    this.continueActions = nil
+  end
+  return true
+end
+
+local function trySetResult(this, result)
+  return trySetComplete(this, TaskStatusRanToCompletion, result)
+end
+
+local function trySetException(this, exception)
+  if this.data == Void then
+    throw(exception)
+  end
+  return trySetComplete(this, TaskStatusFaulted, newTaskExceptionHolder(this, exception))
+end
+
+local function trySetCanceled(this, cancellationToken)
+  return trySetComplete(this, TaskStatusCanceled, cancellationToken)
+end
+
+local function newWaitingTask(isVoid)
+  return newTask(TaskStatusWaitingForActivation, isVoid and Void)
+end
+
+local function getContinueActions(task) 
+  local continueActions = task.continueActions
+  if continueActions == nil then
+    continueActions = {}
+    task.continueActions = continueActions
+  end
+  return continueActions
+end
+
+local function addContinueAction(task, f)
+  local continueActions = getContinueActions(task)
+  continueActions[#continueActions + 1] = assert(f)
+end
+
+local function checkTasks(...)
+  local tasks
+  local n = select("#", ...)
+  if n == 1 then
+    local args = ...
+    if args == nil then throw(ArgumentNullException("tasks")) end
+    if System.isArrayLike(args) then
+      tasks = args
+    elseif System.isEnumerableLike(args) then
+      tasks = System.Array.toArray(args)
+    end
+    if tasks ~= nil then
+      for i = 1, #tasks do
+        if tasks[i] == System.null then
+          throw(ArgumentNullException())
+        end
+      end
+    end
+  end
+  if tasks == nil then
+    tasks = { ... }
+    for i = 1, n do
+      if tasks[i] == nil then
+        throw(ArgumentNullException())
+      end
+    end
+  end
+  return tasks
+end
+
+local function getDelay(delay)
+  if type(delay) == "table" then
+    delay = trunc(delay:getTotalMilliseconds())
+    if delay < -1 or delay > 2147483647 then
+      throw(ArgumentOutOfRangeException("delay"))
+    end
+  elseif delay < -1 then
+    throw(ArgumentOutOfRangeException("millisecondsDelay"))  
+  end
+  return delay
+end
+
+local waitToken = {}
+local function getResult(this, await)
+  local status = this.status
+  if status == TaskStatusRanToCompletion then
+    return this.data
+  elseif status == TaskStatusFaulted then
+    throw(getException(this, await))
+  elseif status == TaskStatusCanceled then
+    local e = TaskCanceledException(this)
+    if not await then e = AggregateException(e) end
+    throw(e)
+  end
+  return waitToken
+end
+
+local function getAwaitResult(task)
+  local status = task.status
+  local ok, v
+  if status == TaskStatusRanToCompletion then
+    ok, v = true, task.data
+  elseif status == TaskStatusFaulted then
+    ok, v = false, getException(task, true)
+  elseif status == TaskStatusCanceled then
+    ok, v = false, TaskCanceledException(task)
+  else
+    assert(false)
+  end
+  return ok, v
+end
+
+local factory = {
+  StartNew = function (_, f, state)
+    local t = newWaitingTask()
+    post(function ()
+      try(function ()
+        assert(trySetResult(t, f(state)))
+      end, function (e)
+        assert(trySetException(t, e))
+      end)
+    end)
+    return t
+  end
+}
+
+Task = define("System.Threading.Tasks.Task", {
+  Dispose = System.emptyFn,
+  __ctor__ = function (this, action, state)
+    if action == nil then throw(ArgumentNullException("action")) end
+    this.status = TaskStatusCreated
+    this.data = function ()
+      return action(state)
+    end
+  end,
+  getId = getId,
+  getCurrentId = function ()
+    local t = currentTask
+    if t then
+      return getId(t)
+    end
+  end,
+  getFactory = function ()
+    return factory
+  end,
+  getStatus = function (this)
+    return this.status
+  end,
+  getException = function (this)
+    if this.status == TaskStatusFaulted then
+      return getException(this)
+    end
+    return nil
+  end,
+  getResult = function (this)
+    local result = getResult(this)
+    if result == waitToken then
+      waitTask(getContinueActions(this))
+      result = getResult(this)
+      assert(result ~= waitToken)
+    end
+    return result
+  end,
+  getIsCompleted = isCompleted,
+  getIsCanceled = function (this)
+    return this.status == TaskStatusCanceled
+  end,
+  getIsFaulted = function (this)
+    return this.status == TaskStatusFaulted
+  end,
+  FromResult = fromResult,
+  FromCanceled = fromCanceled,
+  FromException = fromException,
+  getCompletedTask = getCompletedTask,
+  Delay = function (delay, cancellationToken)
+    delay = getDelay(delay)
+
+    if cancellationToken and cancellationToken:getIsCancellationRequested() then
+      return fromCanceled(cancellationToken)
+    elseif delay == 0 then
+      return getCompletedTask()
+    end
+
+    local t = newWaitingTask()
+    local timerId, registration  
+
+    if cancellationToken and cancellationToken:getCanBeCanceled() then
+      registration = cancellationToken:Register(function ()
+        local success = trySetCanceled(t, cancellationToken)
+        if success and timerId then
+          removeTimer(timerId)
+        end
+      end)
+    end
+
+    if delay ~= -1 then
+      timerId = addTimer(function ()
+        local success = trySetResult(t)
+        if success and registration then
+          registration:Dispose()
+        end
+      end, delay)
+    end
+
+    return t
+  end,
+  Run = function (f, cancellationToken)
+    local t = Task(f) 
+    t:Start()
+    return t
+  end,
+  WhenAll = function (T, ...)
+    local tasks = checkTasks(...)
+    local count = #tasks
+    if count == 0 then
+      return getCompletedTask()
+    end
+    local result, exceptions, cancelled = {}, {}
+    local t = newWaitingTask()
+    local function f(task)
+      local status = task.status
+      if status == TaskStatusRanToCompletion then
+        result[#result + 1] = task.data
+      elseif status == TaskStatusFaulted then
+        local exception = getException(task, true)
+        exceptions[#exceptions + 1] = exception
+      elseif status == TaskStatusCanceled then
+        cancelled = true
+      end
+      count = count - 1
+      if count == 0 then
+        if #exceptions > 0 then
+          trySetException(t, arrayFromTable(exceptions, Exception))
+        elseif cancelled then
+          trySetCanceled(t)
+        else
+          if T then
+            trySetResult(t, arrayFromTable(result, T))
+          end
+            trySetResult(t)
+        end
+      end
+    end
+    for i = 1, count do
+      local task = tasks[i]
+      if isCompleted(task) then
+        post(function ()
+          f(task)
+        end)
+      else
+        addContinueAction(task, f)
+      end
+    end
+    return t
+  end,
+  WhenAny = function (...)
+    local tasks = checkTasks(...)
+    local count = #tasks
+    if count == 0 then
+      throw(ArgumentException())
+    end
+    local t = newWaitingTask()
+    local function f(task)
+      local status = task.status
+      if status == TaskStatusRanToCompletion then
+        trySetResult(t, task)
+      elseif status == TaskStatusFaulted then
+        trySetException(t, getException(task))
+      elseif status == TaskStatusCanceled then
+        trySetCanceled(t)
+      end
+    end
+    for i = 1, count do
+      local task = tasks[i]
+      if isCompleted(task) then
+        post(function ()
+          f(task)
+        end)
+      else
+        addContinueAction(task, f)
+      end
+    end
+    return t
+  end,
+  ContinueWith = function (this, continuationAction)
+    if continuationAction == nil then throw(ArgumentNullException("continuationAction")) end
+    local t = newWaitingTask()
+    local function f(task)
+      try(function ()
+        t.status = TaskStatusRunning
+        assert(trySetResult(t, continuationAction(task)))
+      end, function (e)
+        assert(trySetException(t, e))
+      end)
+    end
+    if isCompleted(this) then
+      post(function ()
+        f(this)
+      end)
+    else
+      addContinueAction(this, f)
+    end
+    return t
+  end,
+  Start = function (this)
+    if this.status ~= TaskStatusCreated then throw(InvalidOperationException("Task was already started.")) end
+    this.status = TaskStatusWaitingToRun
+    post(function ()
+      try(function ()
+        this.status = TaskStatusRunning
+        assert(trySetResult(this, this.data()))
+      end, function (e)
+        assert(trySetException(this, e))
+      end)
+    end)
+  end,
+  Wait = function (this)
+    waitTask(getContinueActions(this))
+  end,
+  Await = function (this, t)
+    local a = t:GetAwaiter()
+    if a:getIsCompleted() then
+      return a:GetResult()
+    end
+    a:OnCompleted(function ()
+      local ok, v
+      try(function ()
+        ok, v = true, a:GetResult()
+      end, function (e)
+        ok, v = false, e
+      end)
+      ok, v = cresume(this.c, ok, v)
+      if not ok then
+        assert(trySetException(this, v))
+      end
+    end)
+    local ok, v = cyield()
+    if ok then
+      return v
+    else
+      error(v)
+    end
+  end,
+  await = function (this, task)
+    if getmetatable(task) ~= Task then
+      return this:Await(task)
+    end
+
+    local result = getResult(task, true)
+    if result ~= waitToken then
+      return result
+    end
+    addContinueAction(task, function (task)
+      local ok, v = getAwaitResult(task)
+      ok, v = cresume(this.c, ok, v)
+      if not ok then
+        assert(trySetException(this, v))
+      end
+    end)
+    local ok, v = cyield()
+    if ok then
+      return v
+    else
+      error(v)
+    end
+  end
+})
+System.Task = Task
+
+local TaskT_TransitionToFinal_AlreadyCompleted = "An attempt was made to transition a task to a final state when it had already completed."
+local TaskCompletionSource = define("System.Threading.Tasks.TaskCompletionSource", {
+  __ctor__ = function (this)
+    this.task = newWaitingTask()
+  end,
+  getTask = function (this)
+    return this.task
+  end,
+  SetCanceled = function (this)
+    if not trySetCanceled(this.task) then
+      throw(InvalidOperationException(TaskT_TransitionToFinal_AlreadyCompleted))
+    end
+  end,
+  SetException = function (this, exception)
+    if exception == nil then throw(ArgumentNullException("exception")) end
+    if not trySetException(this.task, exception) then
+      throw(InvalidOperationException(TaskT_TransitionToFinal_AlreadyCompleted))
+    end
+  end,
+  SetResult = function (this, result)
+    if not trySetResult(this.task, result) then
+      throw(InvalidOperationException(TaskT_TransitionToFinal_AlreadyCompleted))
+    end
+  end,
+  TrySetCanceled = trySetCanceled,
+  TrySetException = trySetException,
+  TrySetResult = trySetResult
+})
+System.TaskCompletionSource = TaskCompletionSource
+
+local CancellationTokenRegistration = defStc("System.Threading.CancellationTokenRegistration", (function ()
+  local function unregister(this)
+    local token = this.token
+    if token then
+      local f = this.f
+      if f then
+        this.f = nil
+        return token.source:unRegister(f)
+      end
+    end
+    return false
+  end
+  return {
+    base =  function(_, T)
+      return { System.IDisposable, System.IEquatable_1(T) }
+    end,
+    __ctor__ = function (this, token, f)
+      if not token then
+        return
+      end
+      this.token = token
+      this.f = f
+    end,
+    getToken = function (this)
+      return this.token
+    end,
+    Equals = System.equals,
+    Unregister = unregister,
+    Dispose = unregister
+  }
+end)())
+System.CancellationTokenRegistration = CancellationTokenRegistration
+
+local OperationCanceledException = define("System.OperationCanceledException", {
+  __tostring = Exception.ToString,
+  base = { System.SystemException },
+  __ctor__ = function (this, message, innerException, token)
+    Exception.__ctor__(this, message or "The operation was canceled.", innerException)
+    this.tokne = token
+  end,
+  getCancellationToken = function (this)
+    return this.token
+  end
+})
+
+local canceledSource
+local CancellationToken 
+CancellationToken = defStc("System.Threading.CancellationToken", {
+  __ctor__ = function (this, canceled)
+    if canceled == nil then
+      return
+    end
+    if canceled == true then
+      this.source = canceledSource
+    elseif canceled then
+      this.source = canceled
+    end
+  end,
+  getCanBeCanceled = function (this)
+    return this.source ~= nil
+  end,
+  getIsCancellationRequested = function (this)
+    local source = this.source
+    if source then
+      return source:getIsCancellationRequested()
+    end
+    return false
+  end,
+  getNone = function ()
+    return CancellationToken()
+  end,
+  Equals = System.equals,
+  Register = function (this, callback, state)
+    local source = this.source
+    if source then
+      if not source:getIsCancellationRequested() then
+        local function f()
+          callback(state)
+        end
+        this.source:register(f)
+        return CancellationTokenRegistration(this, f)
+      end
+      callback(state)
+    end
+    return CancellationTokenRegistration()
+  end,
+  ThrowIfCancellationRequested = function (this)
+    if this:getIsCancellationRequested() then
+      throw(OperationCanceledException())
+    end
+  end
+})
+System.CancellationToken = CancellationToken
+
+local CancellationTokenSource 
+CancellationTokenSource = define("System.Threading.CancellationTokenSource", (function ()
+  local function clean(this)
+    local timerId = this.timerId
+    if timerId then
+      removeTimer(timerId)
+    end
+    local links = this.links
+    if links then
+      for i = 1, #links do
+        links[i]:Dispose()
+      end
+    end
+  end
+  return  {
+    state = 0,
+    base = { System.IDisposable },
+    __ctor__  = function (this, delay)
+      if delay then
+        delay = getDelay(delay)
+        if delay == 0 then
+          this.state = 1
+        else
+          this.timerId = addTimer(function ()
+            this.Cancel()
+          end, delay)
+        end
+      end
+    end,
+    Cancel = function (this, throwOnFirstException)
+      if this.disposed then throw(ObjectDisposedException()) end
+      if this.state == 1  then
+        return
+      end
+      clean(this)
+      this.state = 1
+      local actions = this.continueActions
+      if actions then
+        local t = {}
+        for i = 1, #actions do
+          try(function ()
+            actions[i]()          
+          end, function (e)
+            if throwOnFirstException then
+              throw(e)
+            end
+            t[#t + 1] = e
+          end)
+        end
+        if #t > 0 then
+          throw(AggregateException(arrayFromTable(t, Exception)))
+        end
+      end
+    end,
+    CancelAfter = function (this, delay)
+      if this.disposed then throw(ObjectDisposedException()) end
+      delay = getDelay(delay)
+      if this.state == 1  then
+        return
+      end
+      local timerId = this.timerId
+      if timerId then
+        removeTimer(timerId)
+      end
+      this.timerId = addTimer(function ()
+        this:Cancel()
+      end, delay)
+    end,
+    Dispose = function (this)
+      if this.disposed then
+        return
+      end
+      clean(this)
+      this.disposed = true
+    end,
+    getIsCancellationRequested = function (this)
+      return this.state == 1
+    end,
+    getToken = function (this)
+      local t = this.token
+      if not t then
+        t = CancellationToken(this)
+        this.token = t
+      end
+      return t
+    end,
+    register = addContinueAction,
+    unRegister = function (this, f)
+      local actions = this.continueActions
+      if actions then
+        for i = 1, #actions do
+          if actions[i] == f then
+            tremove(actions, i)
+            return true
+          end
+        end
+      end
+      return false
+    end,
+    CreateLinkedTokenSource = function (...)
+      local cts, links, count = CancellationTokenSource(), {}, 1
+      cts.links = links
+      local n = select("#", ...)
+      if n == 1 then
+        local args = ...
+        if System.isArrayLike(args) then
+          for i = 1, #args do
+            links[count] = args[i]:Register(cts.Cancel, cts)
+            count = count + 1 
+          end
+          return cts
+        end
+      end
+      for i = 1, n do
+        local token = select(i, ...)
+        links[count] = token:Register(cts.Cancel, cts)
+        count = count + 1 
+      end
+      return cts
+    end
+  }
+end)())
+System.CancellationTokenSource = CancellationTokenSource
+canceledSource = setmetatable({ state = 1 }, CancellationTokenSource)
+
+local function taskCoroutineCreate(t, f)
+  local c = ccreate(function (...)
+    local r = f(t, ...)
+    assert(trySetResult(t, r))
+  end)
+  t.c = c
+  return c
+end
+
+function System.async(f, void, ...)
+  local t = newWaitingTask(void)
+  local c = taskCoroutineCreate(t, f)
+  local ok, v = cresume(c, ...)
+  if not ok then
+    assert(trySetException(t, v))
+  end
+  return t
+end
+
+local IAsyncDisposable = System.defInf("System.IAsyncDisposable")
+local IAsyncEnumerable = System.defInf("System.Collections.Generic.IAsyncEnumerable", System.emptyFn, nil, 1)
+local IAsyncEnumerator = System.defInf("System.Collections.Generic.IAsyncEnumerator", System.emptyFn, nil, 1)
+
+System.IAsyncEnumerable_1 =  IAsyncEnumerable
+System.IAsyncEnumerator_1 = IAsyncEnumerator
+
+local yieldAsync 
+local function checkYieldAsync(this, ok, v, current)
+  if ok then
+    if v == yieldAsync then
+      this.e.current = current
+      assert(trySetResult(this.t, true))
+    elseif v == cpool then
+      this.c = nil
+      this.e.current = nil
+      assert(trySetResult(this.t, false))
+    end
+  else
+    assert(trySetException(this.t, v))
+  end
+end
+yieldAsync = {
+  __index = false,
+  await = function (this, task)
+    local result = getResult(task, true)
+    if result ~= waitToken then
+      return result
+    end
+    addContinueAction(task, function (task)
+      local current
+      local ok, v = getAwaitResult(task)
+      ok, v, current = cresume(this.c, ok, v)
+      checkYieldAsync(this, ok, v, current)
+    end)
+    local ok, v = cyield()
+    if ok then
+      return v
+    else
+      error(v)
+    end
+  end,
+  yield = function (this, v)
+    cyield(yieldAsync, v)
+  end
+}
+yieldAsync.__index = yieldAsync
+
+local YieldAsyncEnumerable
+YieldAsyncEnumerable = define("System.YieldAsyncEnumerable", function (T)
+   return {
+    base = { IAsyncEnumerable(T), IAsyncEnumerator(T), IAsyncDisposable },
+    __genericT__ = T
+  }
+end, {
+  getCurrent = System.getCurrent, 
+  GetAsyncEnumerator = function (this)
+    return setmetatable({ f = this.f, args = this.args }, YieldAsyncEnumerable(this.__genericT__))
+  end,
+  DisposeAsync = function (this)
+    return getCompletedTask()
+  end,
+  MoveNextAsync = function (this)
+    local a = this.a
+    if a and a.c == nil then
+      return fromResult(false)
+    end
+
+    local t = newWaitingTask()
+    local ok, v, current
+    if a == nil then
+      local c = ccreate(this.f)
+      a = setmetatable({ t = t, c = c, e = this }, yieldAsync)
+      this.a = a
+      local args = this.args
+      ok, v, current = cresume(c, a, unpack(args, 1, args.n))
+      this.args = nil
+    else
+      a.t = t
+      ok, v, current = cresume(a.c)
+    end
+    checkYieldAsync(a, ok, v, current)
+    return t
+  end
+}, 1)
+
+local function yieldIAsyncEnumerable(f, T, ...)
+  return setmetatable({ f = f, args = pack(...) }, YieldAsyncEnumerable(T))
+end
+
+System.yieldIAsyncEnumerable = yieldIAsyncEnumerable
+System.yieldIAsyncEnumerator = yieldIAsyncEnumerable
+
+local function eachFn(en, async)
+  if async:await(en:MoveNextAsync()) then
+    return async, en:getCurrent()
+  end
+  return nil
+end
+
+local function each(async, t)
+  if t == nil then throw(NullReferenceException(), 1) end
+  local en = t:GetAsyncEnumerator()
+  return eachFn, en, async
+end
+
+System.asynceach = each

+ 202 - 0
Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/Threading/Thread.lua

@@ -0,0 +1,202 @@
+--[[
+Copyright 2017 YANG Huan (sy.yanghuan@gmail.com).
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+--]]
+
+local System = System
+local define = System.define
+local throw = System.throw
+local trunc = System.trunc
+local post = System.post
+local addTimer = System.addTimer
+local Exception = System.Exception
+local ArgumentNullException = System.ArgumentNullException
+local ArgumentOutOfRangeException = System.ArgumentOutOfRangeException
+local NotSupportedException = System.NotSupportedException
+
+local assert = assert
+local type = type
+local setmetatable = setmetatable
+local coroutine = coroutine
+local ccreate = coroutine.create
+local cresume = coroutine.resume
+local cstatus = coroutine.status
+local cyield = coroutine.yield
+
+local mainThread
+
+local ThreadStateException = define("System.Threading.ThreadStateException", {
+  __tostring = Exception.ToString,
+  base = { Exception },
+
+  __ctor__ = function(this, message, innerException)
+     Exception.__ctor__(this, message or "Thread is running or terminated; it cannot restart.", innerException)
+  end
+})
+
+local ThreadAbortException = define("System.Threading.ThreadAbortException", {
+  __tostring = Exception.ToString,
+  base = { Exception },
+  __ctor__ = function(this, message, innerException)
+    Exception.__ctor__(this, message or "Thread aborted.", innerException)
+end
+})
+
+local nextThreadId = 1
+local currentThread
+
+local function getThreadId()
+  local id = nextThreadId
+  nextThreadId = nextThreadId + 1
+  return id
+end
+
+local function checkTimeout(timeout)
+  if type(timeout) == "table" then
+    timeout = trunc(timeout:getTotalMilliseconds())
+  end
+  if timeout < -1 or timeout > 2147483647 then
+    throw(ArgumentOutOfRangeException("timeout"))
+  end
+  return timeout
+end
+
+local function resume(t, obj)
+  local prevThread = currentThread
+  currentThread = t
+  local co = assert(t.co)
+  local ok, v = cresume(co, obj)
+  currentThread = prevThread
+  if ok then
+    if type(v) == "function" then
+      v()
+    elseif cstatus(co) == "dead" then
+      local joinThread = t.joinThread
+      if joinThread then
+        resume(joinThread, true)
+      end
+      t.co = false
+    end
+  else
+    t.co = false
+    print("Warning: Thread.run" , v)
+  end
+end
+
+local function run(t, obj)
+  post(function ()
+    resume(t, obj)
+  end)
+end
+
+local Thread =  define("System.Threading.Thread", {
+  IsBackground = false,
+  IsThreadPoolThread = false,
+  Priority = 2,
+  ApartmentState = 2,
+  Abort = function ()
+    throw(ThreadAbortException())
+  end,
+  getCurrentThread = function ()
+    return currentThread
+  end,
+  __ctor__ = function (this, start)
+	  if start == nil then throw(ArgumentNullException("start")) end
+    this.start = start
+  end,
+  getIsAlive = function (this)
+    local co = this.co
+    return co and cstatus(co) ~= "dead"
+  end,
+  ManagedThreadId = function (this)
+	  local id = this.id
+    if not id then
+      id = getThreadId()
+      this.id = id
+    end
+    return id
+  end,
+  Sleep = function (timeout)
+    local current = currentThread
+    if current == mainThread then
+      throw(NotSupportedException("mainThread not support"))
+    end
+    timeout = checkTimeout(timeout)
+    local f
+    if timeout ~= -1 then
+      f = function ()
+        addTimer(function () 
+          resume(current) 
+        end, timeout)
+      end
+    end
+    cyield(f)
+  end,
+  Yield = function ()
+    local current = currentThread
+    if current == mainThread then
+      return false
+    end
+    cyield(function ()
+      run(current)
+    end)
+    return true
+  end,
+  Join = function (this, timeout)
+    if currentThread == mainThread then
+      throw(NotSupportedException("mainThread not support"))
+    end
+    if this.joinThread then
+      throw(ThreadStateException())
+    end
+    this.joinThread = currentThread  
+    if timeout == nil then
+      cyield()
+    else
+      timeout = checkTimeout(timeout)
+      local f
+      if timeout ~= -1 then
+        f = function ()
+          addTimer(function ()
+            resume(currentThread, false)
+          end, timeout)
+        end
+      end
+      return cyield(f)
+    end
+  end,
+  Start = function (this, parameter)
+    if this.co ~= nil then throw(ThreadStateException()) end
+    local co = ccreate(this.start)
+    this.co = co
+    this.start = nil
+    run(this, parameter)
+  end,
+  waitTask = function (taskContinueActions)
+    if currentThread == mainThread then
+      throw(NotSupportedException("mainThread not support"))
+    end
+    taskContinueActions[#taskContinueActions + 1] = function ()
+      resume(currentThread)
+    end
+    cyield()
+  end,
+})
+
+mainThread = setmetatable({ id = getThreadId() }, Thread)
+currentThread = mainThread
+
+System.ThreadStateException = ThreadStateException
+System.ThreadAbortException = ThreadAbortException
+System.Thread = Thread

+ 199 - 0
Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/Threading/Timer.lua

@@ -0,0 +1,199 @@
+--[[
+Copyright 2017 YANG Huan (sy.yanghuan@gmail.com).
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+--]]
+
+local System = System
+local define = System.define
+local throw = System.throw
+local Array = System.Array
+local heapAdd = Array.heapAdd
+local heapPop = Array.heapPop
+local heapDown = Array.heapDown
+local currentTimeMillis = System.currentTimeMillis
+local ArgumentNullException = System.ArgumentNullException
+local ArgumentOutOfRangeException  = System.ArgumentOutOfRangeException
+local NotImplementedException = System.NotImplementedException
+local ObjectDisposedException = System.ObjectDisposedException
+
+local type = type
+
+local config = System.config
+local setTimeout = config.setTimeout
+local clearTimeout = config.clearTimeout
+
+if setTimeout and clearTimeout then
+  System.post = function (fn) 
+    setTimeout(fn, 0) 
+  end
+else
+  System.post = function (fn)
+    fn()
+  end
+  local function notset()
+    throw(NotImplementedException("System.config.setTimeout or clearTimeout is not registered."))
+  end
+  setTimeout = notset
+  clearTimeout = notset
+end
+
+local TimeoutQueue = define("System.TimeoutQueue", (function ()
+  local Add, AddRepeating, AddRepeating1, getNextExpiration, Erase, RunLoop, Contains, __ctor__
+  __ctor__ = function (this)
+	this.c = function (a, b) return a.Expiration - b.Expiration end
+  end
+  Add = function (this, now, delay, callback)
+    return AddRepeating1(this, now, delay, 0, callback)
+  end
+  AddRepeating = function (this, now, interval, callback)
+    return AddRepeating1(this, now, interval, interval, callback)
+  end
+  AddRepeating1 = function (this, now, delay, interval, callback)
+    local id = {
+      Expiration = now + delay,
+      RepeatInterval = interval,
+      Callback = callback
+    }
+    heapAdd(this, id, this.c)
+    return id
+  end
+  getNextExpiration = function (this)
+    if #this > 0 then return this[1].Expiration end
+  end
+  Erase = function (this, id)
+    if not id.cancel then
+      id.cancel = true
+      return true
+    end
+    return false
+  end
+  RunLoop = function (this, now)
+    while true do
+      local e = this[1]
+      if e == nil then break end
+      if e.cancel then
+        heapPop(this, this.c)
+      else
+        if e.Expiration <= now then
+          if e.RepeatInterval <= 0 then
+            heapPop(this, this.c)
+            e.cancel = true
+          else
+            e.Expiration = now + e.RepeatInterval
+            heapDown(this, 1, #this, this.c)
+          end
+          e.Callback(e, now)
+        else
+          return e.Expiration
+        end
+      end
+    end
+  end
+  Contains = function (this, id)
+    return not id.cancel
+  end
+  return {
+    nextId_ = 1,
+    Add = Add,
+    AddRepeating = AddRepeating,
+    AddRepeating1 = AddRepeating1,
+    getNextExpiration = getNextExpiration,
+    Erase = Erase,
+    RunLoop = RunLoop,
+    Contains = Contains,
+    __ctor__ = __ctor__
+  }
+end)())
+
+local timerQueue = TimeoutQueue()
+local driverTimer
+
+local function runTimerQueue()
+  local now = currentTimeMillis()
+  local nextExpiration = timerQueue:RunLoop(now)
+  if nextExpiration then
+    driverTimer = setTimeout(runTimerQueue, nextExpiration - now)
+  else
+    driverTimer = nil
+  end
+end
+
+local function addTimer(fn, dueTime, period)
+  local now = currentTimeMillis()
+  local id = timerQueue:AddRepeating1(now, dueTime, period or 0, fn)
+  if timerQueue[1] == id then
+    if driverTimer then
+      clearTimeout(driverTimer)
+    end
+    driverTimer = setTimeout(runTimerQueue, dueTime)
+  end
+  return id
+end
+
+local function removeTimer(id)
+  return timerQueue:Erase(id)
+end
+
+System.addTimer = addTimer
+System.removeTimer = removeTimer
+
+local function close(this)
+  local id = this.id
+  if id then
+    removeTimer(id)
+  end
+end
+
+local function change(this, dueTime, period)
+  if type(dueTime) == "table" then
+    dueTime = dueTime:getTotalMilliseconds()
+    period = period:getTotalMilliseconds()
+  end
+  if dueTime < -1 or dueTime > 0xfffffffe then
+    throw(ArgumentOutOfRangeException("dueTime"))
+  end
+  if period < -1 or period > 0xfffffffe then
+    throw(ArgumentOutOfRangeException("period"))
+  end
+  if this.id == false then throw(ObjectDisposedException()) end
+  close(this)
+  if dueTime ~= -1 then
+    this.id = addTimer(this.callback, dueTime, period)
+  end
+  return true
+end
+
+System.Timer = define("System.Threading.Timer", {
+  __ctor__ =  function (this, callback, state,  dueTime, period)
+    if callback == nil then throw(ArgumentNullException("callback")) end
+    this.callback = function () callback(state) end
+    change(this, dueTime, period)
+  end,
+  Change = change,
+  Dispose = function (this)
+    close(this)
+    this.id = false
+  end,
+  getActiveCount = function ()
+    local count = 0
+    for i = 1, #timerQueue do
+      if not timerQueue[i].cancel then
+        count = count + 1
+      end
+    end
+    return count
+  end,
+  __gc = close
+})
+

+ 6 - 4
Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/TimeSpan.lua.txt

@@ -52,7 +52,7 @@ end
 
 local function negate(this) 
   local ticks = this.ticks
-  if ticks == -9223372036854775808 then
+  if ticks == (-9223372036854775807 - 1) then
     throw(OverflowException("Overflow_NegateTwosCompNum"))
   end
   return TimeSpan(-ticks)
@@ -138,7 +138,9 @@ local function parse(s)
     end
   end
   if sign == '-' then
-    day, hour, minute, second, milliseconds = -day, -hour, -minute, -second, -milliseconds
+    day, hour, minute, second, milliseconds = -tonumber(day), -tonumber(hour), -tonumber(minute), -tonumber(second), -tonumber(milliseconds)
+  else
+    day, hour, minute, second, milliseconds = tonumber(day), tonumber(hour), tonumber(minute), tonumber(second), tonumber(milliseconds)
   end
   return TimeSpan(day, hour, minute, second, milliseconds)
 end
@@ -223,7 +225,7 @@ TimeSpan = System.defStc("System.TimeSpan", {
   Subtract = subtract,
   Duration = function (this) 
     local ticks = this.ticks
-    if ticks == -9223372036854775808 then
+    if ticks == (-9223372036854775807 - 1) then
       throw(OverflowException("Overflow_Duration"))
     end
     return TimeSpan(ticks >= 0 and ticks or - ticks)
@@ -297,4 +299,4 @@ TimeSpan = System.defStc("System.TimeSpan", {
 zero = TimeSpan(0)
 TimeSpan.Zero = zero
 TimeSpan.MaxValue = TimeSpan(9223372036854775807)
-TimeSpan.MinValue = TimeSpan(-9223372036854775808)
+TimeSpan.MinValue = TimeSpan((-9223372036854775807 - 1))

+ 19 - 18
Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/Type.lua.txt

@@ -20,6 +20,7 @@ local Object = System.Object
 local Boolean = System.Boolean
 local Delegate = System.Delegate
 local getClass = System.getClass
+local getGenericClass = System.getGenericClass
 local arrayFromTable = System.arrayFromTable
 
 local InvalidCastException = System.InvalidCastException
@@ -54,7 +55,7 @@ local floor = math.floor
 local Type, typeof
 
 local function isGenericName(name)
-  return name:byte(#name) == 93
+  return name:find('`') ~= nil
 end
 
 local function getBaseType(this)
@@ -118,13 +119,6 @@ end
 local function implementInterface(this, ifaceType)
   local t = this
   while t ~= nil do
-    --修改
-    meta=getmetatable(t)
-    if meta then
-      if(meta.__name == "System.RuntimeType")then
-        return false
-      end
-    end
     local interfaces = getInterfaces(this)
     if interfaces ~= nil then
       for i = 1, #interfaces do
@@ -163,7 +157,12 @@ local function isAssignableFrom(this, c)
 end
 
 local function isGenericTypeDefinition(this)
-  return not rawget(this[1], "__name__")
+  local cls = this[1]
+  return getGenericClass(cls) == cls
+end
+
+local function getIsArray(this)
+  return this[1].__name__:byte(-2) == 91
 end
 
 Type = System.define("System.Type", {
@@ -176,14 +175,9 @@ Type = System.define("System.Type", {
   end,
   getIsGenericTypeDefinition = isGenericTypeDefinition,
   GetGenericTypeDefinition = function (this)
-    if isGenericTypeDefinition(this) then
-      return this
-    end
-    local name = this[1].__name__
-    local i = name:find('`')
-    if i then
-      local genericTypeName = name:sub(1, i - 1)
-      return typeof(System.getClass(genericTypeName))
+    local genericClass = getGenericClass(this[1])
+    if genericClass then
+      return typeof(genericClass)
     end
     throw(System.InvalidOperationException())
   end,
@@ -254,6 +248,13 @@ Type = System.define("System.Type", {
     end
     return isAssignableFrom(this, obj:GetType())
   end,
+  getIsArray = getIsArray,
+  GetElementType = function (this)
+    if getIsArray(this) then
+      return typeof(this[1].__genericT__)
+    end
+    return nil
+  end,
   ToString = function (this)
     return this[1].__name__
   end,
@@ -394,7 +395,7 @@ checks[Number] = function (obj, T)
     [UInt16] = function (obj) return type(obj) == "number" and obj >= 0 and obj <= 32767 and floor(obj) == obj end,
     [Int32] = function (obj) return type(obj) == "number" and obj >= -2147483648 and obj <= 2147483647 and floor(obj) == obj end,
     [UInt32] = function (obj) return type(obj) == "number" and obj >= 0 and obj <= 4294967295 and floor(obj) == obj end,
-    [Int64] = function (obj) return type(obj) == "number" and obj >= -9223372036854775808 and obj <= 9223372036854775807 and floor(obj) == obj end,
+    [Int64] = function (obj) return type(obj) == "number" and obj >= (-9223372036854775807 - 1) and obj <= 9223372036854775807 and floor(obj) == obj end,
     [UInt64] = function (obj) return type(obj) == "number" and obj >= 0 and obj <= 18446744073709551615 and floor(obj) == obj end,
     [Single] = function (obj) return type(obj) == "number" and obj >= -3.40282347E+38 and obj <= 3.40282347E+38 end,
     [Double] = function (obj) return type(obj) == "number" end

+ 1 - 1
Unity/Assets/Bundles/Lua/CSharpLua/CoreSystem/Utilities.lua.txt

@@ -98,7 +98,7 @@ define("System.Lazy", function (T)
   return { 
     __genericT__ = T 
   }
-end, Lazy)
+end, Lazy, 1)
 
 local ticker, frequency
 local time = System.config.time

+ 426 - 0
Unity/Assets/Bundles/Lua/CSharpLua/Sample/test.lua.txt

@@ -0,0 +1,426 @@
+require("strict")
+local _, socket = pcall(require, "socket")
+
+local now = 0
+local timeoutQueue
+
+local conf = {
+  time = socket and socket.gettime or os.time,
+  setTimeout = function (f, delay)
+    if not timeoutQueue then
+      timeoutQueue = System.TimeoutQueue()
+    end
+    return timeoutQueue:Add(now, delay, f)
+  end,
+  clearTimeout = function (t)
+    timeoutQueue:Erase(t)
+  end
+}
+
+local function runTimeout()
+  if timeoutQueue then
+    while true do
+      local nextExpiration = timeoutQueue:getNextExpiration()
+      if nextExpiration then
+        now = nextExpiration
+        timeoutQueue:RunLoop(now)
+      else
+        break
+      end
+    end
+  end
+end
+
+package.path = package.path .. ";CSharp.lua/Coresystem.lua/?.lua"
+require("All")("", conf)
+collectgarbage("collect")
+print(collectgarbage("count"))
+
+local function test(f, name) 
+  print("-----------------------------", name)
+  f()
+  print("\n")
+end
+
+local function printList(list)
+  assert(list)
+  local t = {}
+  for _, i in System.each(list) do
+    table.insert(t, i:ToString())
+  end
+  print(table.concat(t, " "))
+end
+
+local function testDateTimeAndTimeSpan() 
+  local date = System.DateTime.getNow()
+  print(date:getTicks())
+  print(date:ToString(), date:getYear(), date:getMonth(), date:getDay(), date:getHour(), date:getMinute(), date:getSecond())
+    
+  local ts = System.TimeSpan.FromSeconds(20)
+  print(ts:ToString())
+    
+  date = date + System.TimeSpan.FromDays(2)
+  print(date:ToString())
+  
+  date = date:AddMonths(2);
+  print(date:ToString())
+    
+  local baseTime = System.DateTime(1970, 1, 1) 
+  print(baseTime:ToString())
+  print(baseTime:AddMilliseconds(1458032204643):ToString())
+end
+
+local function testArray() 
+  local arr = System.Array(System.Int32):new(10)
+  print(arr:ToString(), #arr)
+  printList(arr)
+  arr:set(0, 2)
+  arr:set(6, 4)
+  printList(arr)
+  print(arr:get(0), arr:get(6), arr:get(9))
+end
+
+local function testList()
+  local list = System.List(System.Int)()
+  list:Add(20)
+  list:Add(15)
+  list:Add(6)
+  print(list:ToString(), #list)
+  printList(list)
+  local subList = list:GetRange(1, 2)
+  printList(subList)
+  list:set(1, 8)
+  list:Sort()
+  printList(list)
+  print(list:Contains(10), list:Contains(15), list:IndexOf(20))
+  list:RemoveAll(function(i) return i >= 10 end)
+  print(#list, list:get(1))
+  printList(list)
+end
+
+local function testDictionary()
+  local dict = System.Dictionary(System.String, System.Int)()
+  dict:Add("a", 1)
+  dict:Add("b", 12)
+  dict:Add("c", 25)
+  dict:Add("d", 30)
+  for _,  pair in System.each(dict) do
+    print(pair.Key, pair.Value)
+  end
+  print("-------------")
+  for k, v in System.pairs(dict) do
+     print(k, v)
+  end
+end
+
+local function testYeild()
+  local enumerable = function (begin, _end) 
+    return System.yieldIEnumerable(function (begin, _end)
+      while begin < _end do
+        System.yield(begin)
+        begin = begin + 1
+      end
+    end, System.Int, begin, _end)
+  end
+  local e = enumerable(1, 10)
+  printList(e)
+  printList(e)
+end
+
+local function testDelegate()
+  local prints = ""
+  local function printExt(s)
+    prints = prints .. s
+    print(s)
+  end
+
+  local function assertExt(s)
+    assert(prints == s, s)
+    prints = ""
+  end
+
+  local d1 = function() printExt("d1") end
+  local d2 = function() printExt("d2") end
+  local d3 = function() printExt("d3") end
+
+  local f = nil + d1 
+  f()
+  assertExt("d1") 
+  print("--")
+  
+  f = d1 + nil
+  f()
+  assertExt("d1")
+  print("--")
+  
+  f = d1 + d2
+  f()
+  assertExt("d1d2")
+  print("--")
+   
+  f = d1 + (d2 + d3) 
+  f()
+  assertExt("d1d2d3")
+  print("--")
+     
+  f = (d1 + d2) + (d2 + d3)  
+  f()
+  assertExt("d1d2d2d3")
+  print("--")
+  
+  f = d1 + d2 - d1  
+  f()
+  assertExt("d2")
+  print("--")
+   
+  f = d1 + d2 - d2 
+  f()
+  assertExt("d1")
+  print("--")
+   
+  f = d1 + d2 + d1 - d1
+  f()
+  assertExt("d1d2")
+  print("--")
+  
+  f = d1 + d2 + d3 - (d1 + d2) 
+  f()
+  assertExt("d3")
+  print("--")
+    
+  f = d1 + d2 + d3 - (d2 + d1)
+  f()
+  assertExt("d1d2d3")
+  print("--")
+   
+  f = (d1 + d2) + (d3 + d1 + d2) 
+  local f1 = d1 + d2
+  f = f - f1
+  f()
+  assertExt("d1d2d3")
+    
+  print("--")
+  f = (d1 + d2) - (d1 + d2)
+  print(f == nil)
+end
+
+local function testLinq()
+  local Linq = System.Linq.Enumerable
+  local list = System.List(System.Int)()
+  list:Add(10) list:Add(2) list:Add(30) list:Add(4) list:Add(5) list:Add(6) list:Add(7) list:Add(8)
+  printList(Linq.Where(list, function(i) return i >= 4 end))
+  printList(Linq.Take(list, 4))
+  printList(Linq.Select(list, function(i) return i + 2 end, System.Int))
+  print(Linq.Min(list), Linq.Max(list))
+  print(Linq.ElementAtOrDefault(Linq.Where(list, function(i) return i <= 4 end), 5))
+  local ll = Linq.Where(list, function(i) return i <= 4 end)
+  print(Linq.Count(ll))
+  Linq.Any(ll)
+  print(Linq.Count(ll))
+    
+  printList(Linq.OrderByDescending(list, function(i) return i end, nil, System.Int))  
+  list = System.List(System.Object)()
+  local super = { 
+    ToString = function(t)
+      return t[1] .. ',' .. t[2] .. ',' .. t[3] .. '|'
+    end
+  }
+  super.__index = super 
+    
+  list:Add(setmetatable({ 4, 2, 3 }, super))
+  list:Add(setmetatable({ 3, 1, 3 }, super))
+  list:Add(setmetatable({ 1, 2, 3 }, super))
+  list:Add(setmetatable({ 3, 2, 4 }, super))
+  list:Add(setmetatable({ 3, 2, 3 }, super))
+    
+  local t1 = Linq.OrderBy(list, function(i) return i[1] end, nil, System.Int)  
+  printList(t1)
+  t1 = Linq.ThenBy(t1, function(i) return i[2] end, nil, System.Int)
+  t1 = Linq.ThenBy(t1, function(i) return i[3] end, nil, System.Int)
+  printList(t1)
+end 
+
+local function testGroupBy() 
+  local Linq = System.Linq.Enumerable
+  local list = System.List(System.Object)()
+  list:Add({ id = 5, Template = 30 })
+  list:Add({ id = 6, Template = 30 })
+  list:Add({ id = 1, Template = 1 })
+  list:Add({ id = 2, Template = 2 })
+  list:Add({ id = 3, Template = 1 })
+  list:Add({ id = 4, Template = 2 })
+  local groups = Linq.GroupBy(list, function (i) return i.Template end, System.Int)
+  local s = ""
+  for _,  group in System.each(groups) do
+    for _, item in System.each(group) do
+      s = s .. item.id
+    end
+  end
+  print(s)
+  assert(s == "561324");
+end
+
+local function testType()
+  local ins = 2
+  print(System.is(ins, System.Double))
+  local t = ins:GetType()
+  print(t:getName())
+  print(System.is("ddd", System.String))
+  print(System.as("ddd", System.String))
+  print(System.cast(System.String, "ddd"))
+end
+
+local function testNumCast()
+  assert(System.toInt32(-2147483659) == 2147483637)
+  assert(System.toUInt32(-2147483659) == 2147483637)
+  assert(System.toUInt64(-1) == 18446744073709551615)
+end
+
+local function testSplit()
+  local a = "a, b"
+  local aa = a:Split(44 --[[',']])
+  printList(aa)
+end
+
+local function testConsole()
+  print("enter your name")
+  local name = System.Console.ReadLine()
+  print("enter your age")
+  local age = System.Console.ReadLine()
+  System.Console.WriteLine("name {0}, age {1}", name, age)
+end
+
+local function testIO()
+  local path = "iotest.txt"
+  local s = "hero, CSharp.lua\nIO"
+  local File = System.IO.File
+  File.WriteAllText(path, s)
+  local text = File.ReadAllText(path)
+  assert(text == s)
+  File.Delete(path)
+end
+
+local function testStringBuilder()
+  local sb = System.StringBuilder()
+  sb:Append("aa")
+  sb:Append("bbcc")
+  sb:setLength(5)  
+  print(sb, sb:getLength())
+end
+
+local function testAsync()  
+	-- Generated by CSharp.lua Compiler
+	local System = System
+	local Test
+	System.import(function (global)
+		Test = global.Test
+	end)
+	System.namespace("Test", function (namespace)
+		namespace.class("TestAsync", function (namespace)
+			local f, __ctor__
+			__ctor__ = function (this)
+				local t = f(this)
+				System.Console.WriteLine(("{0}, {1}"):Format(t:getStatus():EnumToString(System.TaskStatus), t:getException()))
+			end
+			f = function (this)
+				return System.async(function (async, this)
+					local t = System.Task.Delay(2000)
+					async:await(t)
+					async:await(t)
+					System.Console.WriteLine(("Delay {0}"):Format(t:getStatus():ToEnumString(System.TaskStatus)))
+				end, nil, this)
+			end
+			return {
+				f = f,
+				__ctor__ = __ctor__
+			}
+		end)
+
+		namespace.class("Program", function (namespace)
+			local Main
+			Main = function ()
+				Test.TestAsync()
+			end
+			return {
+				Main = Main
+			}
+		end)
+	end)
+
+	System.init({
+    types = {
+      "Test.Program",
+      "Test.TestAsync"
+    },
+    Main = "Test.Program.Main"
+	})
+
+	Test.Program.Main() 
+  runTimeout()
+end
+
+local function testAsyncForeach()
+  local System = System
+  local ListInt32 = System.List(System.Int32)
+  System.namespace("Test", function (namespace)
+    namespace.class("Program", function (namespace)
+      local GenerateSequence, Main, Test
+      GenerateSequence = function (n)
+        return System.yieldIAsyncEnumerable(function (async, n)
+          for i = 0, n - 1 do
+            async:yield(i)
+          end
+        end, System.Int32, n)
+      end
+      Main = function (args)
+        Test()
+      end
+      Test = function ()
+        System.async(function (async)
+          local l = ListInt32()
+          for _, number in System.asynceach(async, GenerateSequence(10)) do
+            System.Console.WriteLine(number)
+            l:Add(number)
+          end
+          async:await(System.Task.Delay(200))
+          System.Console.WriteLine(System.String.JoinEnumerable(",", l))
+        end, true)
+      end
+      return {
+        GenerateSequence = GenerateSequence,
+        Main = Main
+      }
+    end)
+  end)
+
+    System.init({
+      "Test.Program"
+    }, {
+      Main = "Test.Program.Main"
+    })
+
+    Test.Program.Main() 
+    runTimeout()
+end
+
+test(testDateTimeAndTimeSpan, "DateTime & TimeSpan")
+test(testArray, "Array")
+test(testList, "List")
+test(testDictionary, "Dictionary")
+test(testYeild, "Yeild")
+test(testDelegate, "Delegate")
+test(testLinq, "Linq")
+test(testGroupBy, "GroupBy")
+test(testType, "Type")
+test(testNumCast, "NumCast")
+test(testSplit, "testSplit")
+test(testStringBuilder, "StringBuilder")
+test(testIO, "IO")
+--test(testConsole, "Console")
+--test(testAsync, "Async")
+--test(testAsyncForeach, "testAsyncForeach")
+
+
+
+      
+

+ 1 - 1
Unity/Assets/Bundles/Lua/Main.lua.txt

@@ -6,7 +6,7 @@ function Start()
     require("Model.manifest")("Model")
     require("ModelView.manifest")("ModelView")
     require("Hotfix.manifest")("Hotfix")
-    require("HotfixView.manifest")("HotfixView")
+    require("HotfixView.manifest")("HotfixView") 
     
     print("1111111111111111111111")
     ET.GameStart.Start()

Some files were not shown because too many files changed in this diff