public EventProxyCodeGen(CodeGenerator cg, EventBindingInfo eventBindingInfo)
        {
            this.cg = cg;
            this.eventBindingInfo = eventBindingInfo;

            var eventInfo     = this.eventBindingInfo.eventInfo;
            var declaringType = eventInfo.DeclaringType;
            var tsFieldVar    = BindingManager.GetTSVariable(eventBindingInfo.regName);

            this.cg.cs.AppendLine("DuktapeDLL.duk_push_this(ctx);");
            this.cg.cs.AppendLine($"duk_add_event_instanced(ctx, \"{tsFieldVar}\", {this.eventBindingInfo.adderName}, {this.eventBindingInfo.removerName}, -1);");
            this.cg.cs.AppendLine("DuktapeDLL.duk_remove(ctx, -2);");
            this.cg.cs.AppendLine("return 1;");
        }
Ejemplo n.º 2
0
        protected List <ParameterInfo> WriteTSDeclaration(T method, MethodBaseBindingInfo <T> bindingInfo)
        {
            var    isExtension   = method.IsDefined(typeof(System.Runtime.CompilerServices.ExtensionAttribute));
            var    refParameters = new List <ParameterInfo>();
            string tsMethodDeclaration;

            if (this.cg.bindingManager.GetTSMethodDeclaration(method, out tsMethodDeclaration))
            {
                this.cg.tsDeclare.AppendLine(tsMethodDeclaration);
                return(refParameters);
            }
            //TODO: 需要处理参数类型归并问题, 因为如果类型没有导入 ts 中, 可能会在声明中出现相同参数列表的定义
            //      在 MethodVariant 中创建每个方法对应的TS类型名参数列表, 完全相同的不再输出
            this.cg.AppendJSDoc(method);
            var prefix = "";

            if (method.IsStatic && !isExtension)
            {
                prefix = "static ";
            }
            string tsMethodRename;

            if (this.cg.bindingManager.GetTSMethodRename(method, out tsMethodRename))
            {
                this.cg.tsDeclare.Append($"{prefix}{tsMethodRename}(");
            }
            else
            {
                this.cg.tsDeclare.Append($"{prefix}{bindingInfo.regName}(");
            }
            var parameters = method.GetParameters();

            if (isExtension)
            {
                ArrayUtility.RemoveAt(ref parameters, 0);
            }
            for (var i = 0; i < parameters.Length; i++)
            {
                var parameter        = parameters[i];
                var parameter_prefix = "";
                var parameterType    = parameter.ParameterType;
                if (parameter.IsOut && parameterType.IsByRef)
                {
                    // parameter_prefix = "/*out*/ ";
                    refParameters.Add(parameter);
                }
                else if (parameterType.IsByRef)
                {
                    // parameter_prefix = "/*ref*/ ";
                    refParameters.Add(parameter);
                }
                if (parameter.IsDefined(typeof(ParamArrayAttribute), false) && i == parameters.Length - 1)
                {
                    var elementType      = parameterType.GetElementType();
                    var elementTS        = this.cg.bindingManager.GetTSTypeFullName(elementType);
                    var parameterVarName = BindingManager.GetTSVariable(parameter.Name);
                    this.cg.tsDeclare.AppendL($"{parameter_prefix}...{parameterVarName}: {elementTS}[]");
                }
                else
                {
                    var parameterTS      = this.cg.bindingManager.GetTSTypeFullName(parameterType, parameter.IsOut);
                    var parameterVarName = BindingManager.GetTSVariable(parameter.Name);
                    this.cg.tsDeclare.AppendL($"{parameter_prefix}{parameterVarName}: {parameterTS}");
                }
                if (i != parameters.Length - 1)
                {
                    this.cg.tsDeclare.AppendL(", ");
                }
            }
            this.cg.tsDeclare.AppendL($")");
            WriteTSReturn(method, refParameters);
            return(refParameters);
        }
Ejemplo n.º 3
0
        public override void Dispose()
        {
            using (new PreservedCodeGen(cg))
            {
                using (new RegFuncCodeGen(cg))
                {
                    using (new RegFuncNamespaceCodeGen(cg, bindingInfo))
                    {
                        var constructor = bindingInfo.constructors.available ? bindingInfo.constructors.name : "object_private_ctor";
                        if (!bindingInfo.constructors.available && !bindingInfo.type.IsAbstract)
                        {
                            if (bindingInfo.type.IsSubclassOf(typeof(Component)))
                            {
                                // 因为 ts 泛型约束需要 new() 形式, 所以在定义中产生一个 public 定义
                                // 例如: GetComponent<T extends Component>(type: { new(): T }): T
                                cg.tsDeclare.AppendLine("/*protected*/ constructor()");
                            }
                            else
                            {
                                cg.tsDeclare.AppendLine("protected constructor()");
                            }
                        }
                        cg.cs.AppendLine("duk_begin_class(ctx, \"{0}\", typeof({1}), {2});",
                                         bindingInfo.jsName,
                                         this.cg.bindingManager.GetCSTypeFullName(bindingInfo.type),
                                         constructor);
                        foreach (var kv in bindingInfo.methods)
                        {
                            var    regName  = kv.Value.regName;
                            var    funcName = kv.Value.name;
                            var    bStatic  = false;
                            string redirect;
                            if (this.bindingInfo.transform != null && this.bindingInfo.transform.TryRedirectMethod(regName, out redirect))
                            {
                                funcName = redirect;
                            }
                            cg.cs.AppendLine("duk_add_method(ctx, \"{0}\", {1}, {2});", regName, funcName, bStatic ? -2 : -1);
                        }
                        foreach (var kv in bindingInfo.staticMethods)
                        {
                            var    regName  = kv.Value.regName;
                            var    funcName = kv.Value.name;
                            var    bStatic  = true;
                            string redirect;
                            if (this.bindingInfo.transform != null && this.bindingInfo.transform.TryRedirectMethod(regName, out redirect))
                            {
                                funcName = redirect;
                            }
                            cg.cs.AppendLine("duk_add_method(ctx, \"{0}\", {1}, {2});", regName, funcName, bStatic ? -2 : -1);
                        }
                        foreach (var kv in bindingInfo.properties)
                        {
                            var bindingInfo = kv.Value;
                            if (bindingInfo.staticPair.IsValid())
                            {
                                var tsPropertyVar = BindingManager.GetTSVariable(bindingInfo.regName);
                                cg.cs.AppendLine("duk_add_property(ctx, \"{0}\", {1}, {2}, {3});",
                                                 tsPropertyVar,
                                                 bindingInfo.staticPair.getterName != null ? bindingInfo.staticPair.getterName : "null",
                                                 bindingInfo.staticPair.setterName != null ? bindingInfo.staticPair.setterName : "null",
                                                 -2);

                                var tsPropertyPrefix = "static ";
                                if (bindingInfo.staticPair.setterName == null)
                                {
                                    tsPropertyPrefix += "readonly ";
                                }
                                var tsPropertyType = this.cg.bindingManager.GetTSTypeFullName(bindingInfo.propertyInfo.PropertyType);
                                cg.tsDeclare.AppendLine($"{tsPropertyPrefix}{tsPropertyVar}: {tsPropertyType}");
                            }
                            if (bindingInfo.instancePair.IsValid())
                            {
                                var tsPropertyVar = BindingManager.GetTSVariable(bindingInfo.regName);
                                cg.cs.AppendLine("duk_add_property(ctx, \"{0}\", {1}, {2}, {3});",
                                                 tsPropertyVar,
                                                 bindingInfo.instancePair.getterName != null ? bindingInfo.instancePair.getterName : "null",
                                                 bindingInfo.instancePair.setterName != null ? bindingInfo.instancePair.setterName : "null",
                                                 -1);

                                var tsPropertyPrefix = "";
                                if (bindingInfo.instancePair.setterName == null)
                                {
                                    tsPropertyPrefix += "readonly ";
                                }
                                var tsPropertyType = this.cg.bindingManager.GetTSTypeFullName(bindingInfo.propertyInfo.PropertyType);
                                cg.tsDeclare.AppendLine($"{tsPropertyPrefix}{tsPropertyVar}: {tsPropertyType}");
                            }
                        }
                        foreach (var kv in bindingInfo.fields)
                        {
                            var bindingInfo = kv.Value;
                            var bStatic     = bindingInfo.isStatic;
                            var tsFieldVar  = BindingManager.GetTSVariable(bindingInfo.regName);
                            if (bindingInfo.constantValue != null)
                            {
                                var cv = bindingInfo.constantValue;
                                cg.cs.AppendLine($"duk_add_const(ctx, \"{tsFieldVar}\", {cv}, {-2});");
                            }
                            else
                            {
                                cg.cs.AppendLine("duk_add_field(ctx, \"{0}\", {1}, {2}, {3});",
                                                 tsFieldVar,
                                                 bindingInfo.getterName != null ? bindingInfo.getterName : "null",
                                                 bindingInfo.setterName != null ? bindingInfo.setterName : "null",
                                                 bStatic ? -2 : -1);
                            }
                            var tsFieldPrefix = bStatic ? "static " : "";
                            if (bindingInfo.setterName == null)
                            {
                                tsFieldPrefix += "readonly ";
                            }
                            var tsFieldType = this.cg.bindingManager.GetTSTypeFullName(bindingInfo.fieldInfo.FieldType);
                            cg.tsDeclare.AppendLine($"{tsFieldPrefix}{tsFieldVar}: {tsFieldType}");
                        }
                        foreach (var kv in bindingInfo.events)
                        {
                            var eventBindingInfo = kv.Value;
                            var bStatic          = eventBindingInfo.isStatic;
                            //NOTE: 静态事件在绑定过程直接定义, 非静态事件推迟到构造时直接赋值创建
                            var tsFieldVar    = BindingManager.GetTSVariable(eventBindingInfo.regName);
                            var tsFieldType   = this.cg.bindingManager.GetTSTypeFullName(eventBindingInfo.eventInfo.EventHandlerType);
                            var tsFieldPrefix = "";
                            if (bStatic)
                            {
                                tsFieldPrefix += "static ";
                                cg.cs.AppendLine($"duk_add_event(ctx, \"{tsFieldVar}\", {eventBindingInfo.adderName}, {eventBindingInfo.removerName}, -2);");
                            }
                            else
                            {
                                cg.cs.AppendLine($"duk_add_property(ctx, \"{tsFieldVar}\", {eventBindingInfo.proxyName}, null, -1);");
                            }
                            cg.tsDeclare.AppendLine($"{tsFieldPrefix}{tsFieldVar}: DuktapeJS.event<{tsFieldType}>");
                        }
                        cg.cs.AppendLine("duk_end_class(ctx);");
                    }
                }
                base.Dispose();
            }

            this.cg.tsDeclare.DecTabLevel();
            this.cg.tsDeclare.AppendLine("}");
        }