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;"); }
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); }
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("}"); }