コード例 #1
0
        public DelegateCodeGen(CodeGenerator cg, DelegateBindingInfo delegateBindingInfo, int index)
        {
            this.cg = cg;
            var nargs          = delegateBindingInfo.parameters.Length;
            var retName        = this.cg.bindingManager.GetUniqueName(delegateBindingInfo.parameters, "ret");
            var firstArgument  = typeof(DuktapeDelegate) + " fn";
            var returnTypeName = this.cg.bindingManager.GetCSTypeFullName(delegateBindingInfo.returnType);
            var delegateName   = DuktapeVM._DuktapeDelegates + index;
            var arglist        = this.cg.bindingManager.GetCSArglistDecl(delegateBindingInfo.parameters);

            foreach (var target in delegateBindingInfo.types)
            {
                this.cg.cs.AppendLine("[{0}(typeof({1}))]",
                                      this.cg.bindingManager.GetCSTypeFullName(typeof(JSDelegateAttribute)),
                                      this.cg.bindingManager.GetCSTypeFullName(target));
                this.cg.bindingManager.log.AppendLine("emitting delegate decl: {0}", target);
            }
            if (!string.IsNullOrEmpty(arglist))
            {
                arglist = ", " + arglist;
            }
            this.cg.cs.AppendLine($"public static {returnTypeName} {delegateName}({firstArgument}{arglist}) {{");
            this.cg.cs.AddTabLevel();

            this.cg.cs.AppendLine("var ctx = fn.ctx;");
            this.cg.cs.AppendLine("if (ctx == IntPtr.Zero)");
            this.cg.cs.AppendLine("{");
            this.cg.cs.AddTabLevel();
            this.cg.cs.AppendLine("throw new InvalidOperationException(\"duktape vm context has already been released.\");");
            this.cg.cs.DecTabLevel();
            this.cg.cs.AppendLine("}");

            if (nargs > 0)
            {
                this.cg.cs.AppendLine("fn.BeginInvoke(ctx);");
                for (var i = 0; i < nargs; i++)
                {
                    var parameter = delegateBindingInfo.parameters[i];
                    this.cg.AppendPushValue(parameter.ParameterType, parameter.Name);
                }
                this.cg.cs.AppendLine("fn.EndInvoke(ctx);");
            }
            else
            {
                this.cg.cs.AppendLine("fn.BeginInvoke(ctx);");
                this.cg.cs.AppendLine("fn.EndInvoke(ctx);");
            }

            if (delegateBindingInfo.returnType != typeof(void))
            {
                this.cg.cs.AppendLine($"{this.cg.bindingManager.GetCSTypeFullName(delegateBindingInfo.returnType)} {retName};");
                this.cg.cs.AppendLine(this.cg.bindingManager.GetDuktapeGetter(delegateBindingInfo.returnType, "ctx", "-1", retName));
                this.cg.cs.AppendLine("DuktapeDLL.duk_pop(ctx);");
                this.cg.cs.AppendLine($"return {retName};");
            }
            else
            {
                this.cg.cs.AppendLine("DuktapeDLL.duk_pop(ctx);");
            }
        }
コード例 #2
0
 public void OnPostGenerateDelegate(DelegateBindingInfo bindingInfo)
 {
     for (int i = 0, size = _bindingProcess.Count; i < size; i++)
     {
         var bp = _bindingProcess[i];
         try
         {
             bp.OnPostGenerateDelegate(this, bindingInfo);
         }
         catch (Exception exception)
         {
             this.Error($"process failed [{bp}][OnPostGenerateDelegate]: {exception}");
         }
     }
 }
コード例 #3
0
 // 收集所有 delegate 类型
 public void CollectDelegate(Type type)
 {
     if (type == null || type.BaseType != typeof(MulticastDelegate))
     {
         return;
     }
     if (!exportedDelegates.ContainsKey(type))
     {
         var invoke     = type.GetMethod("Invoke");
         var returnType = invoke.ReturnType;
         var parameters = invoke.GetParameters();
         if (ContainsPointer(invoke))
         {
             log.AppendLine("skip unsafe (pointer) delegate: [{0}] {1}", type, invoke);
             return;
         }
         // 是否存在等价 delegate
         foreach (var kv in exportedDelegates)
         {
             if (kv.Value.Equals(returnType, parameters))
             {
                 log.AppendLine("skip delegate: {0} && {1}", kv.Value, type);
                 kv.Value.types.Add(type);
                 redirectDelegates[type] = kv.Key;
                 return;
             }
         }
         var delegateBindingInfo = new DelegateBindingInfo(returnType, parameters);
         delegateBindingInfo.types.Add(type);
         exportedDelegates.Add(type, delegateBindingInfo);
         log.AppendLine("add delegate: {0}", type);
         for (var i = 0; i < parameters.Length; i++)
         {
             CollectDelegate(parameters[i].ParameterType);
         }
     }
 }
コード例 #4
0
        public void Generate()
        {
            var cg     = new CodeGenerator(this);
            var outDir = prefs.outDir;
            var tx     = prefs.extraExt;

            // var tx = "";
            if (!Directory.Exists(outDir))
            {
                Directory.CreateDirectory(outDir);
            }
            var cancel  = false;
            var current = 0;
            var total   = exportedTypes.Count;

            foreach (var typeKV in exportedTypes)
            {
                var typeBindingInfo = typeKV.Value;
                try
                {
                    current++;
                    cancel = EditorUtility.DisplayCancelableProgressBar(
                        "Generating",
                        $"{current}/{total}: {typeBindingInfo.FullName}",
                        (float)current / total);
                    if (cancel)
                    {
                        Warn("operation canceled");
                        break;
                    }
                    if (!typeBindingInfo.omit)
                    {
                        cg.Clear();
                        OnPreGenerateType(typeBindingInfo);
                        cg.Generate(typeBindingInfo);
                        OnPostGenerateType(typeBindingInfo);
                        cg.WriteTo(outDir, typeBindingInfo.GetFileName(), tx);
                    }
                }
                catch (Exception exception)
                {
                    Error($"generate failed {typeBindingInfo.type.FullName}: {exception.Message}");
                    Debug.LogError(exception.StackTrace);
                }
            }

            if (!cancel)
            {
                try
                {
                    var exportedDelegatesArray = new DelegateBindingInfo[this.exportedDelegates.Count];
                    this.exportedDelegates.Values.CopyTo(exportedDelegatesArray, 0);

                    cg.Clear();
                    cg.Generate(exportedDelegatesArray);
                    // cg.tsSource.enabled = false;
                    cg.WriteTo(outDir, DuktapeVM._DuktapeDelegates, tx);
                }
                catch (Exception exception)
                {
                    Error($"generate delegates failed: {exception.Message}");
                    Debug.LogError(exception.StackTrace);
                }
            }

            var logPath = prefs.logPath;

            File.WriteAllText(logPath, log.ToString());
            EditorUtility.ClearProgressBar();
        }
コード例 #5
0
 public virtual void OnPostGenerateDelegate(BindingManager bindingManager, DelegateBindingInfo bindingInfo)
 {
 }