/// <summary> /// 计算继承的操作符重载 /// </summary> /// <param name="bin"></param> public void ComputeExtendOverrides(CSWC bin) { //***先收集继承关系**** extendstree tree = new extendstree(); tree.root = new extendstree.extendnode(bin.ObjectClass); Dictionary <RunTimeDataType, extendstree.extendnode> dictClsNode = new Dictionary <RunTimeDataType, extendstree.extendnode>(); dictClsNode.Add(bin.ObjectClass.getRtType(), tree.root); Stack <extendstree.extendnode> tosearchchild = new Stack <extendstree.extendnode>(); tosearchchild.Push(tree.root); while (tosearchchild.Count > 0) { var tosearch = tosearchchild.Pop(); foreach (var item in bin.classes) { if (item.super == tosearch.nodecls) { var node = new extendstree.extendnode(item); tosearch.extends.Add(node); dictClsNode.Add(item.getRtType(), node); tosearchchild.Push(node); } } } for (int i = 0; i < (int)OverrideableOperator.op_explicit; i++) { var opset = operFunctions[i]; List <KeyValuePair <OperatorFunctionKey, DefineAndFunc> > opsetkvs = new List <KeyValuePair <OperatorFunctionKey, DefineAndFunc> >(); opsetkvs.AddRange(opset); foreach (var kv in opsetkvs) { List <RunTimeDataType> v1clslist = new List <RunTimeDataType>(); List <RunTimeDataType> v2clslist = new List <RunTimeDataType>(); var key = kv.Key; if (key.v1 > RunTimeDataType.unknown) { if (bin.getClassByRunTimeDataType(key.v1).isLink_System&& !bin.getClassByRunTimeDataType(key.v1).isStruct) { v2clslist.Add(RunTimeDataType.rt_null); } } if (key.v2 > RunTimeDataType.unknown) { if (bin.getClassByRunTimeDataType(key.v2).isLink_System&& !bin.getClassByRunTimeDataType(key.v2).isStruct) { v1clslist.Add(RunTimeDataType.rt_null); } } v1clslist.Add(key.v1); v2clslist.Add(key.v2); //***查找所有继承的类*** if (key.v1 > RunTimeDataType.unknown) { if (dictClsNode.ContainsKey(key.v1)) { var node = dictClsNode[key.v1]; Stack <extendstree.extendnode> stacktocheck = new Stack <extendstree.extendnode>(); stacktocheck.Push(node); while (stacktocheck.Count > 0) { var p = stacktocheck.Pop(); foreach (var item in p.extends) { v1clslist.Add(item.nodecls.getRtType()); stacktocheck.Push(item); } } } } if (key.v2 > RunTimeDataType.unknown) { if (dictClsNode.ContainsKey(key.v2)) { var node = dictClsNode[key.v2]; Stack <extendstree.extendnode> stacktocheck = new Stack <extendstree.extendnode>(); stacktocheck.Push(node); while (stacktocheck.Count > 0) { var p = stacktocheck.Pop(); foreach (var item in p.extends) { v2clslist.Add(item.nodecls.getRtType()); stacktocheck.Push(item); } } } } //***排列组合*** foreach (var v1 in v1clslist) { foreach (var v2 in v2clslist) { if (v1 != RunTimeDataType.rt_null || v2 != RunTimeDataType.rt_null) { if (!opset.ContainsKey(new OperatorFunctionKey(v1, v2))) { opset.Add(new OperatorFunctionKey(v1, v2), kv.Value); } } } } } } }
public System.Reflection.MethodInfo GetMethodInfo(ASBinCode.rtti.FunctionDefine functionDefine,ASBinCode.CSWC swc,ASRuntime.Player player) { if (method == null) { method = typeof(RefOutStore).GetMethod("GetValue",new Type[] { typeof(System.String) });; } return(method); }
IEnumerator LoadHotFixAssembly() { //***创建flashplayer*** //***建议全局只使用一个as3运行时。因此将此脚本设置为一直存在,并将flashplayer保存在此对象中。 var flashplayer = new ASRuntime.Player(); //此处从StreamingAssetsPath中加载字节码,实际热更可从网络下载后执行。 //The byte code is loaded from the Streamingassetspath, and the actual project can be downloaded from the network and executed. #if UNITY_ANDROID WWW www = new WWW(Application.streamingAssetsPath + "/hotfix.cswc"); #else WWW www = new WWW("file:///" + Application.streamingAssetsPath + "/hotfix.cswc"); #endif while (!www.isDone) { yield return(null); } if (!string.IsNullOrEmpty(www.error)) { UnityEngine.Debug.LogError(www.error); } //加载as3编译器生成的字节码。 //Loads the byte code generated by the compiler. ASBinCode.CSWC swc = ASBinCode.CSWC.loadFromBytes(www.bytes); www.Dispose(); ASRuntime.nativefuncs.BuildInFunctionLoader.loadBuildInFunctions(swc); var extfunctions = new ASRuntime.extFunctions(); //加载导出的Unity API //Loading exported APIs var regenumerator = extfunctions.registrationFunction(swc); //**注册本地代码有可能非常之多。所以提供了一个进度条** //API code can be very much. So a progress bar is provided int functioncount = 0; while (regenumerator.MoveNext()) { functioncount++; if (functioncount % 50 == 0) { if (progress != null) { progress.value = extfunctions.progress; progressValue.text = "loading:" + extfunctions.progress * 100 + "%"; } yield return(null); } } if (progress != null) { progress.value = extfunctions.progress; progressValue.text = "loading:" + extfunctions.progress * 100 + "%"; } yield return(null); //注册额外的代码,这些代码为MonoBehaviour提供支持 //Register additional code that provides support for MonoBehaviour GObj_Special.registSpecialFunctions(swc); if (progress != null) { progress.gameObject.SetActive(false); progressValue.gameObject.SetActive(false); } this.player = flashplayer; flashplayer.loadCode(swc); if (string.IsNullOrEmpty(DocumentClass)) { Debug.LogError("请指定AS3入口文档类"); yield break; } main = flashplayer.createInstance(DocumentClass); updatemethod = flashplayer.getMethod(main, "update"); }
IEnumerator LoadHotFixAssembly() { //首先实例化ILRuntime的AppDomain,AppDomain是一个应用程序域,每个AppDomain都是一个独立的沙盒 appdomain = new ILRuntime.Runtime.Enviorment.AppDomain(); //正常项目中应该是自行从其他地方下载dll,或者打包在AssetBundle中读取,平时开发以及为了演示方便直接从StreammingAssets中读取, //正式发布的时候需要大家自行从其他地方读取dll //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //这个DLL文件是直接编译HotFix_Project.sln生成的,已经在项目中设置好输出目录为StreamingAssets,在VS里直接编译即可生成到对应目录,无需手动拷贝 #if UNITY_ANDROID WWW www = new WWW(Application.streamingAssetsPath + "/HotFixProto.dll"); #else WWW www = new WWW("file:///" + Application.streamingAssetsPath + "/HotFixProto.dll"); #endif while (!www.isDone) { yield return(null); } if (!string.IsNullOrEmpty(www.error)) { UnityEngine.Debug.LogError(www.error); } byte[] dll = www.bytes; www.Dispose(); //PDB文件是调试数据库,如需要在日志中显示报错的行号,则必须提供PDB文件,不过由于会额外耗用内存,正式发布时请将PDB去掉,下面LoadAssembly的时候pdb传null即可 #if UNITY_ANDROID www = new WWW(Application.streamingAssetsPath + "/HotFixProto.pdb"); #else www = new WWW("file:///" + Application.streamingAssetsPath + "/HotFixProto.pdb"); #endif while (!www.isDone) { yield return(null); } if (!string.IsNullOrEmpty(www.error)) { UnityEngine.Debug.LogError(www.error); } byte[] pdb = www.bytes; using (System.IO.MemoryStream fs = new MemoryStream(dll)) { using (System.IO.MemoryStream p = new MemoryStream(pdb)) { appdomain.LoadAssembly(fs, p, new Mono.Cecil.Pdb.PdbReaderProvider()); } } //***创建flashplayer*** //***我修改了Appdomain的代码,让Appdomain保存一个as3运行时的引用。这样可以避免静态变量。 var flashplayer = new ASRuntime.Player(new Assets.AS3Proto.UnityOutput()); //加载as3编译器生成的protobuf代码。 #if UNITY_ANDROID //www = new WWW(Application.streamingAssetsPath + "/as3test.cswc");// "/proto.cswc"); www = new WWW(Application.streamingAssetsPath + "/proto.cswc"); #else //www = new WWW("file:///" + Application.streamingAssetsPath + "/as3test.cswc");// "/proto.cswc"); www = new WWW("file:///" + Application.streamingAssetsPath + "/proto.cswc"); #endif while (!www.isDone) { yield return(null); } if (!string.IsNullOrEmpty(www.error)) { UnityEngine.Debug.LogError(www.error); } ASBinCode.CSWC swc = ASBinCode.CSWC.loadFromBytes(www.bytes); flashplayer.loadCode(swc); appdomain.Tag = flashplayer; www.Dispose(); //flashplayer.run(null); InitializeILRuntime(); OnHotFixLoaded(); }
public CSWC Deserialize(byte[] bin) { serizlizedObjects.Clear(); stringpool.Clear(); dictSerizlized.Clear(); CSWC swc = new CSWC(); loadingSwc = swc; using (System.IO.MemoryStream ms = new System.IO.MemoryStream(bin)) { using (System.IO.BinaryReader br = new System.IO.BinaryReader(ms, System.Text.Encoding.UTF8)) { int classcount = br.ReadInt32(); for (int i = 0; i < classcount; i++) { swc.classes.Add(DeserializeObject <rtti.Class>(br, rtti.Class.LoadClass)); } int functioncount = br.ReadInt32(); for (int i = 0; i < functioncount; i++) { swc.functions.Add(DeserializeObject <rtti.FunctionDefine>(br, rtti.FunctionDefine.LoadFunctionDefine)); } int blockcount = br.ReadInt32(); for (int i = 0; i < blockcount; i++) { swc.blocks.Add(DeserializeObject <CodeBlock>(br, CodeBlock.Deserialize)); } swc.primitive_to_class_table.Clear(); int tablecount = br.ReadInt32(); for (int i = 0; i < tablecount; i++) { swc.primitive_to_class_table.Add(DeserializeObject <rtti.Class>(br, rtti.Class.LoadClass)); } int dict_vector_type_count = br.ReadInt32(); for (int i = 0; i < dict_vector_type_count; i++) { rtti.Class _class = DeserializeObject <rtti.Class>(br, rtti.Class.LoadClass); RunTimeDataType t = br.ReadInt32(); swc.dict_Vector_type.Add(_class, t); } int _dictlinkcreatorcount = br.ReadInt32(); for (int i = 0; i < _dictlinkcreatorcount; i++) { string key = br.ReadString(); rtti.Class _class = DeserializeObject <rtti.Class>(br, rtti.Class.LoadClass); swc._dictlinkcreatorfunctionname.Add(key, _class); } swc.operatorOverrides = DeserializeObject <OperatorFunctions>(br, OperatorFunctions.LoadOperatorFunctions); /////// <summary> /////// 链接到系统Object的类型 /////// </summary> ////public Class LinkObjectClass; //SerializeObject<rtti.Class>(bw, swc.LinkObjectClass); swc.LinkObjectClass = DeserializeObject <rtti.Class>(br, rtti.Class.LoadClass); /////// <summary> /////// Class类型 /////// </summary> ////public Class TypeClass; //SerializeObject<rtti.Class>(bw, swc.TypeClass); swc.TypeClass = DeserializeObject <rtti.Class>(br, rtti.Class.LoadClass); /////// <summary> /////// Object类 /////// </summary> ////public Class ObjectClass; //SerializeObject<rtti.Class>(bw, swc.ObjectClass); swc.ObjectClass = DeserializeObject <rtti.Class>(br, rtti.Class.LoadClass); /////// <summary> /////// IEnumerator接口 /////// </summary> ////public Class IEnumeratorInterface; //SerializeObject<rtti.Class>(bw, swc.IEnumeratorInterface); swc.IEnumeratorInterface = DeserializeObject <rtti.Class>(br, rtti.Class.LoadClass); /////// <summary> /////// IEnumerable接口 /////// </summary> ////public Class IEnumerableInterface; //SerializeObject<rtti.Class>(bw, swc.IEnumerableInterface); swc.IEnumerableInterface = DeserializeObject <rtti.Class>(br, rtti.Class.LoadClass); /////// <summary> /////// yielditerator类 /////// </summary> ////public Class YieldIteratorClass; //SerializeObject<rtti.Class>(bw, swc.YieldIteratorClass); swc.YieldIteratorClass = DeserializeObject <rtti.Class>(br, rtti.Class.LoadClass); /////// <summary> /////// Function类 /////// </summary> ////public Class FunctionClass; //SerializeObject<rtti.Class>(bw, swc.FunctionClass); swc.FunctionClass = DeserializeObject <rtti.Class>(br, rtti.Class.LoadClass); /////// <summary> /////// 异常类 /////// </summary> ////public Class ErrorClass; //SerializeObject<rtti.Class>(bw, swc.ErrorClass); swc.ErrorClass = DeserializeObject <rtti.Class>(br, rtti.Class.LoadClass); /////// <summary> /////// 字典特殊类 /////// </summary> ////public Class DictionaryClass; //SerializeObject<rtti.Class>(bw, swc.DictionaryClass); swc.DictionaryClass = DeserializeObject <rtti.Class>(br, rtti.Class.LoadClass); /////// <summary> /////// 正则类 /////// </summary> ////public Class RegExpClass; //SerializeObject<rtti.Class>(bw, swc.RegExpClass); swc.RegExpClass = DeserializeObject <rtti.Class>(br, rtti.Class.LoadClass); swc.MaxMemNumberCount = br.ReadInt32(); swc.MaxMemIntCount = br.ReadInt32(); swc.MaxMemUIntCount = br.ReadInt32(); swc.MaxMemBooleanCount = br.ReadInt32(); } } loadingSwc = null; return(swc); }
public byte[] Serialize(CSWC swc) { serizlizedObjects.Clear(); stringpool.Clear(); dictSerizlized.Clear(); swc._dictlinkcreatorfunctionname.Clear(); foreach (var item in swc.class_Creator) { NativeFunctionBase nativeFunctionBase = (NativeFunctionBase)item.Value; swc._dictlinkcreatorfunctionname.Add(nativeFunctionBase.name, item.Key); } using (System.IO.MemoryStream ms = new System.IO.MemoryStream()) { using (System.IO.BinaryWriter bw = new System.IO.BinaryWriter(ms, System.Text.Encoding.UTF8)) { bw.Write(swc.classes.Count); for (int i = 0; i < swc.classes.Count; i++) { SerializeObject <rtti.Class>(bw, swc.classes[i]); } bw.Write(swc.functions.Count); for (int i = 0; i < swc.functions.Count; i++) { SerializeObject <rtti.FunctionDefine>(bw, swc.functions[i]); } bw.Write(swc.blocks.Count); for (int i = 0; i < swc.blocks.Count; i++) { SerializeObject <CodeBlock>(bw, swc.blocks[i]); } bw.Write(swc.primitive_to_class_table.Count); for (int i = 0; i < swc.primitive_to_class_table.Count; i++) { SerializeObject <rtti.Class>(bw, swc.primitive_to_class_table[i]); } bw.Write(swc.dict_Vector_type.Count); foreach (var item in swc.dict_Vector_type) { SerializeObject <rtti.Class>(bw, item.Key); bw.Write(item.Value); } bw.Write(swc._dictlinkcreatorfunctionname.Count); foreach (var item in swc._dictlinkcreatorfunctionname) { bw.Write(item.Key); SerializeObject <rtti.Class>(bw, item.Value); } SerializeObject <OperatorFunctions>(bw, swc.operatorOverrides); ///// <summary> ///// 链接到系统Object的类型 ///// </summary> //public Class LinkObjectClass; SerializeObject <rtti.Class>(bw, swc.LinkObjectClass); ///// <summary> ///// Class类型 ///// </summary> //public Class TypeClass; SerializeObject <rtti.Class>(bw, swc.TypeClass); ///// <summary> ///// Object类 ///// </summary> //public Class ObjectClass; SerializeObject <rtti.Class>(bw, swc.ObjectClass); ///// <summary> ///// IEnumerator接口 ///// </summary> //public Class IEnumeratorInterface; SerializeObject <rtti.Class>(bw, swc.IEnumeratorInterface); ///// <summary> ///// IEnumerable接口 ///// </summary> //public Class IEnumerableInterface; SerializeObject <rtti.Class>(bw, swc.IEnumerableInterface); ///// <summary> ///// yielditerator类 ///// </summary> //public Class YieldIteratorClass; SerializeObject <rtti.Class>(bw, swc.YieldIteratorClass); ///// <summary> ///// Function类 ///// </summary> //public Class FunctionClass; SerializeObject <rtti.Class>(bw, swc.FunctionClass); ///// <summary> ///// 异常类 ///// </summary> //public Class ErrorClass; SerializeObject <rtti.Class>(bw, swc.ErrorClass); ///// <summary> ///// 字典特殊类 ///// </summary> //public Class DictionaryClass; SerializeObject <rtti.Class>(bw, swc.DictionaryClass); ///// <summary> ///// 正则类 ///// </summary> //public Class RegExpClass; SerializeObject <rtti.Class>(bw, swc.RegExpClass); bw.Write(swc.MaxMemNumberCount); bw.Write(swc.MaxMemIntCount); bw.Write(swc.MaxMemUIntCount); bw.Write(swc.MaxMemBooleanCount); } serizlizedObjects.Clear(); stringpool.Clear(); dictSerizlized.Clear(); return(ms.ToArray()); } }
public System.Reflection.MethodInfo GetMethodInfo(ASBinCode.rtti.FunctionDefine functionDefine,ASBinCode.CSWC swc,ASRuntime.Player player) { if (method == null) { method = typeof(System.ICloneable).GetMethod("Clone",Type.EmptyTypes);; } return(method); }