private void BuildCfxRuntime(GeneratedFileManager fileManager)
    {
        var b = new CodeBuilder();

        b.BeginCfxNamespace();
        b.BeginClass("CfxRuntime", "public partial");
        b.AppendLine();

        var lxFuncs = new List <CefExportFunction>();

        foreach (var f in decls.ExportFunctions)
        {
            if (f.Platform == CefPlatform.Independent)
            {
                f.EmitPublicFunction(b, "Runtime");
                b.AppendLine();
            }
            else
            {
                lxFuncs.Add(f);
            }
        }
        b.BeginClass("Linux", "public");
        b.AppendLine();
        foreach (var f in lxFuncs)
        {
            f.EmitPublicFunction(b, "Runtime");
            b.AppendLine();
        }
        b.EndBlock();
        b.EndBlock();
        b.EndBlock();
        fileManager.WriteFileIfContentChanged("CfxRuntime.cs", b.ToString());
    }
    public override void EmitRemoteClass(CodeBuilder b)
    {
        b.AppendLine();

        b.AppendSummaryAndRemarks(Comments, true, Category == StructCategory.Client);
        b.BeginClass(RemoteClassName + " : CfrStructure", GeneratorConfig.ClassModifiers(RemoteClassName, "public sealed"));
        b.AppendLine();

        if (NeedsWrapFunction)
        {
            b.BeginFunction("Wrap", RemoteClassName, "RemotePtr remotePtr", "internal static");
            b.AppendLine("if(remotePtr == RemotePtr.Zero) return null;");
            b.AppendLine("var weakCache = CfxRemoteCallContext.CurrentContext.connection.weakCache;");
            b.AppendLine("return ({0})weakCache.GetOrAdd(remotePtr.ptr, () => new {0}(remotePtr));", RemoteClassName);
            b.EndBlock();
            b.AppendLine();
            b.AppendLine();
        }

        b.AppendLine("private {0}(RemotePtr remotePtr) : base(remotePtr) {{}}", RemoteClassName);
        b.AppendLine("public {0}() : base(new {1}CtorRemoteCall(), new {1}DtorRemoteCall()) {{}}", RemoteClassName, ClassName);

        foreach (var sm in StructMembers)
        {
            b.AppendLine();
            b.AppendLine("{0} m_{1};", sm.MemberType.RemoteSymbol, sm.PublicName);
            b.AppendLine("bool m_{0}_fetched;", sm.PublicName);
            b.AppendLine();

            b.AppendSummaryAndRemarks(sm.Comments, true);
            b.BeginBlock("public {1} {0}", CSharp.Escape(sm.PublicName), sm.MemberType.RemoteSymbol);
            b.BeginBlock("get");
            b.BeginIf("!m_{0}_fetched", sm.PublicName);
            b.AppendLine("var call = new {0}Get{1}RemoteCall();", ClassName, sm.PublicName);
            b.AppendLine("call.sender = RemotePtr.ptr;");
            b.AppendLine("call.RequestExecution(RemotePtr.connection);");
            b.AppendLine("m_{0} = {1};", sm.PublicName, sm.MemberType.RemoteWrapExpression("call.value"));
            b.AppendLine("m_{0}_fetched = true;", sm.PublicName);
            b.EndBlock();
            b.AppendLine("return m_{0};", sm.PublicName);
            b.EndBlock();
            b.BeginBlock("set");
            b.AppendLine("var call = new {0}Set{1}RemoteCall();", ClassName, sm.PublicName);
            b.AppendLine("call.sender = RemotePtr.ptr;");
            b.AppendLine("call.value = {0};", sm.MemberType.RemoteUnwrapExpression("value"));
            b.AppendLine("call.RequestExecution(RemotePtr.connection);");
            b.AppendLine("m_{0} = value;", sm.PublicName);
            b.AppendLine("m_{0}_fetched = true;", sm.PublicName);
            b.EndBlock();
            b.EndBlock();
        }

        b.EndBlock();
    }
Beispiel #3
0
    public void EmitApiClass(CodeBuilder b)
    {
        b.BeginClass(ClassName.Substring(3), "internal static");
        b.AppendLine();

        b.BeginBlock("static {0} ()", ApiClassName);
        b.AppendLine("CfxApiLoader.Load{0}Api();", ClassName);
        b.EndBlock();
        b.AppendLine();

        EmitApiDeclarations(b);

        b.EndBlock();
    }
Beispiel #4
0
    public override void EmitRemoteClass(CodeBuilder b)
    {
        b.AppendLine();

        b.AppendSummaryAndRemarks(Comments, true, Category == StructCategory.ApiCallbacks);
        b.BeginClass(RemoteClassName + " : CfrStructure", GeneratorConfig.ClassModifiers(RemoteClassName, "public sealed"));
        b.AppendLine();

        EmitRemoteClassWrapperFunction(b);

        b.AppendLine("private {0}(RemotePtr remotePtr) : base(remotePtr) {{}}", RemoteClassName);
        b.AppendLine("public {0}() : base(new {1}CtorRemoteCall(), new {1}DtorRemoteCall()) {{}}", RemoteClassName, ClassName);

        foreach (var sm in StructMembers)
        {
            b.AppendLine();
            b.AppendLine("{0} m_{1};", sm.MemberType.RemoteSymbol, sm.PublicName);
            b.AppendLine("bool m_{0}_fetched;", sm.PublicName);
            b.AppendLine();

            b.AppendSummaryAndRemarks(sm.Comments, true);
            b.BeginBlock("public {1} {0}", CSharp.Escape(sm.PublicName), sm.MemberType.RemoteSymbol);
            b.BeginBlock("get");
            b.BeginIf("!m_{0}_fetched", sm.PublicName);
            b.AppendLine("var call = new {0}Get{1}RemoteCall();", ClassName, sm.PublicName);
            b.AppendLine("call.sender = RemotePtr.ptr;");
            b.AppendLine("call.RequestExecution(RemotePtr.connection);");
            b.AppendLine("m_{0} = {1};", sm.PublicName, sm.MemberType.RemoteWrapExpression("call.value"));
            b.AppendLine("m_{0}_fetched = true;", sm.PublicName);
            b.EndBlock();
            b.AppendLine("return m_{0};", sm.PublicName);
            b.EndBlock();
            b.BeginBlock("set");
            b.AppendLine("var call = new {0}Set{1}RemoteCall();", ClassName, sm.PublicName);
            b.AppendLine("call.sender = RemotePtr.ptr;");
            b.AppendLine("call.value = {0};", sm.MemberType.RemoteUnwrapExpression("value"));
            b.AppendLine("call.RequestExecution(RemotePtr.connection);");
            b.AppendLine("m_{0} = value;", sm.PublicName);
            b.AppendLine("m_{0}_fetched = true;", sm.PublicName);
            b.EndBlock();
            b.EndBlock();
        }

        b.EndBlock();
    }
    private void BuildCfrRuntime(GeneratedFileManager fileManager)
    {
        var b = new CodeBuilder();

        b.BeginCfxNamespace(".Remote");
        b.BeginClass("CfrRuntime", "public partial");
        b.AppendLine();

        foreach (var f in remoteDecls.ExportFunctions)
        {
            if (!f.PrivateWrapper)
            {
                f.EmitRemoteFunction(b);
                b.AppendLine();
            }
        }
        b.EndBlock();
        b.EndBlock();
        fileManager.WriteFileIfContentChanged("CfrRuntime.cs", b.ToString());
    }
    public override void EmitRemoteClass(CodeBuilder b)
    {
        b.AppendLine("using Event;");

        b.AppendLine();

        b.AppendSummaryAndRemarks(Comments, true, Category == StructCategory.Client);
        b.BeginClass(RemoteClassName + " : CfrBaseClient", GeneratorConfig.ClassModifiers(RemoteClassName));
        b.AppendLine();

        if (NeedsWrapFunction)
        {
            b.BeginFunction("Wrap", RemoteClassName, "RemotePtr remotePtr", "internal static");
            b.AppendLine("if(remotePtr == RemotePtr.Zero) return null;");
            b.AppendLine("var call = new {0}GetGcHandleRemoteCall();", ClassName);
            b.AppendLine("call.self = remotePtr.ptr;");
            b.AppendLine("call.RequestExecution(remotePtr.connection);");
            b.AppendLine("return ({0})System.Runtime.InteropServices.GCHandle.FromIntPtr(call.gc_handle).Target;", RemoteClassName);
            b.EndBlock();
            b.AppendLine();
            b.AppendLine();
        }

        b.AppendLine();

        b.AppendLine("private {0}(RemotePtr remotePtr) : base(remotePtr) {{}}", RemoteClassName);


        b.BeginBlock("public {0}() : base(new {1}CtorWithGCHandleRemoteCall())", RemoteClassName, ClassName);
        b.BeginBlock("lock(RemotePtr.connection.weakCache)");
        b.AppendLine("RemotePtr.connection.weakCache.Add(RemotePtr.ptr, this);");
        b.EndBlock();
        b.EndBlock();

        b.AppendLine();

        foreach (var cb in CallbackFunctions)
        {
            if (!GeneratorConfig.IsBrowserProcessOnly(CefStruct.Name + "::" + cb.Name))
            {
                b.AppendSummaryAndRemarks(cb.Comments, true, true);
                b.BeginBlock("public event {0} {1}", cb.RemoteEventHandlerName, CSharp.Escape(cb.PublicName));
                b.BeginBlock("add");
                b.BeginBlock("if(m_{0} == null)", cb.PublicName);
                b.AppendLine("var call = new {0}SetCallbackRemoteCall();", ClassName);
                b.AppendLine("call.self = RemotePtr.ptr;");
                b.AppendLine("call.index = {0};", cb.ClientCallbackIndex);
                b.AppendLine("call.active = true;");
                b.AppendLine("call.RequestExecution(RemotePtr.connection);");
                b.EndBlock();
                b.AppendLine("m_{0} += value;", cb.PublicName);
                b.EndBlock();
                b.BeginBlock("remove");
                b.AppendLine("m_{0} -= value;", cb.PublicName);
                b.BeginBlock("if(m_{0} == null)", cb.PublicName);
                b.AppendLine("var call = new {0}SetCallbackRemoteCall();", ClassName);
                b.AppendLine("call.self = RemotePtr.ptr;");
                b.AppendLine("call.index = {0};", cb.ClientCallbackIndex);
                b.AppendLine("call.active = false;");
                b.AppendLine("call.RequestExecution(RemotePtr.connection);");
                b.EndBlock();
                b.EndBlock();
                b.EndBlock();
                b.AppendLine();
                b.AppendLine("internal {0} m_{1};", cb.RemoteEventHandlerName, cb.PublicName);
                b.AppendLine();
                b.AppendLine();
            }
        }

        b.EndBlock();

        b.AppendLine();
        b.BeginBlock("namespace Event");
        b.AppendLine();

        foreach (var cb in CallbackFunctions)
        {
            if (!GeneratorConfig.IsBrowserProcessOnly(CefStruct.Name + "::" + cb.Name))
            {
                EmitRemoteEventArgsAndHandler(b, cb);
                b.AppendLine();
            }
        }

        b.EndBlock();
    }
    public void EmitRemoteEventArgsAndHandler(CodeBuilder b, CefCallbackFunction cb)
    {
        if (cb.IsBasicEvent)
        {
            return;
        }

        if (!ShouldEmitEventHandler(emittedRemoteHandlers, cb))
        {
            return;
        }

        b.AppendSummaryAndRemarks(cb.Comments, true, true);
        b.AppendLine("public delegate void {0}(object sender, {1} e);", cb.RemoteEventHandlerName, cb.RemoteEventArgsClassName);
        b.AppendLine();

        b.AppendSummaryAndRemarks(cb.Comments, true, true);
        b.BeginClass(cb.RemoteEventArgsClassName + " : CfrEventArgs", GeneratorConfig.ClassModifiers(cb.RemoteEventArgsClassName));
        b.AppendLine();

        b.AppendLine("private {0}RemoteEventCall call;", cb.RemoteCallName);
        b.AppendLine();

        for (var i = 1; i <= cb.Signature.ManagedParameters.Count() - 1; i++)
        {
            cb.Signature.ManagedParameters[i].EmitRemoteEventArgFields(b);
        }
        b.AppendLine();

        if (!cb.Signature.PublicReturnType.IsVoid)
        {
            b.AppendLine("internal {0} m_returnValue;", cb.Signature.PublicReturnType.RemoteSymbol);
            b.AppendLine("private bool returnValueSet;");
            b.AppendLine();
        }

        b.AppendLine("internal {0}({1}RemoteEventCall call) {{ this.call = call; }}", cb.RemoteEventArgsClassName, cb.RemoteCallName);
        b.AppendLine();

        for (var i = 1; i <= cb.Signature.ManagedParameters.Count() - 1; i++)
        {
            var arg = cb.Signature.ManagedParameters[i];
            var cd  = new CommentNode();
            if (arg.ParameterType.IsIn && arg.ParameterType.IsOut)
            {
                cd.Lines = new string[] { string.Format("Get or set the {0} parameter for the <see cref=\"{1}.{2}\"/> render process callback.", arg.PublicPropertyName, CefStruct.RemoteSymbol, cb.PublicFunctionName) };
            }
            else if (arg.ParameterType.IsIn)
            {
                cd.Lines = new string[] { string.Format("Get the {0} parameter for the <see cref=\"{1}.{2}\"/> render process callback.", arg.PublicPropertyName, CefStruct.RemoteSymbol, cb.PublicFunctionName) };
            }
            else
            {
                cd.Lines = new string[] { string.Format("Set the {0} out parameter for the <see cref=\"{1}.{2}\"/> render process callback.", arg.PublicPropertyName, CefStruct.RemoteSymbol, cb.PublicFunctionName) };
            }
            if (arg.ParameterType is CefStructArrayType && arg.ParameterType.IsIn)
            {
                cd.Lines = cd.Lines.Concat(new string[] { "Do not keep a reference to the elements of this array outside of this function." }).ToArray();
            }
            b.AppendSummary(cd);
            b.BeginBlock("public {0} {1}", arg.ParameterType.RemoteSymbol, arg.PublicPropertyName);
            if (arg.ParameterType.IsIn)
            {
                b.BeginBlock("get");
                b.AppendLine("CheckAccess();");
                arg.EmitRemoteEventArgGetterStatements(b);
                b.EndBlock();
            }
            if (arg.ParameterType.IsOut)
            {
                b.BeginBlock("set");
                b.AppendLine("CheckAccess();");
                arg.EmitRemoteEventArgSetterStatements(b);
                b.EndBlock();
            }
            b.EndBlock();
        }
        if (!cb.Signature.PublicReturnType.IsVoid)
        {
            var cd = new CommentNode();
            cd.Lines = new string[] {
                string.Format("Set the return value for the <see cref=\"{0}.{1}\"/> render process callback.", CefStruct.RemoteClassName, cb.PublicFunctionName),
                "Calling SetReturnValue() more then once per callback or from different event handlers will cause an exception to be thrown."
            };
            b.AppendSummary(cd);
            b.BeginBlock("public void SetReturnValue({0} returnValue)", cb.Signature.PublicReturnType.RemoteSymbol);
            b.BeginIf("returnValueSet");
            b.AppendLine("throw new CfxException(\"The return value has already been set\");");
            b.EndBlock();
            b.AppendLine("m_returnValue = returnValue;");
            b.AppendLine("returnValueSet = true;");
            b.EndBlock();
        }

        if (cb.Signature.ManagedParameters.Count() > 1)
        {
            b.AppendLine();
            EmitEventToString(b, cb);
        }
        b.EndBlock();
    }
    public override void EmitPublicClass(CodeBuilder b)
    {
        b.AppendLine("using Event;");
        b.AppendLine();

        b.AppendSummaryAndRemarks(Comments, false, true);

        b.BeginClass(ClassName + " : CfxBaseClient", GeneratorConfig.ClassModifiers(ClassName));
        b.AppendLine();

        if (NeedsWrapFunction)
        {
            b.BeginFunction("Wrap", ClassName, "IntPtr nativePtr", "internal static");
            b.AppendLine("if(nativePtr == IntPtr.Zero) return null;");
            b.AppendLine("var handlePtr = CfxApi.{0}.{1}_get_gc_handle(nativePtr);", ApiClassName, CfxName);
            b.AppendLine("return ({0})System.Runtime.InteropServices.GCHandle.FromIntPtr(handlePtr).Target;", ClassName);
            b.EndBlock();
            b.AppendLine();
            b.AppendLine();
        }

        b.AppendLine("private static object eventLock = new object();");
        b.AppendLine();

        b.BeginBlock("internal static void SetNativeCallbacks()");

        foreach (var sm in CallbackFunctions)
        {
            b.AppendLine("{0}_native = {0};", sm.Name);
        }
        b.AppendLine();
        foreach (var sm in CallbackFunctions)
        {
            b.AppendLine("{0}_native_ptr = System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate({0}_native);", sm.Name);
        }

        b.EndBlock();
        b.AppendLine();

        foreach (var cb in CallbackFunctions)
        {
            var sig = cb.Signature;

            b.AppendComment(cb.ToString());
            CodeSnippets.EmitPInvokeCallbackDelegate(b, cb.Name, cb.Signature);
            b.AppendLine("private static {0}_delegate {0}_native;", cb.Name);
            b.AppendLine("private static IntPtr {0}_native_ptr;", cb.Name);
            b.AppendLine();

            b.BeginFunction(cb.Name, "void", sig.PInvokeParameterList, "internal static");
            //b.AppendLine("var handle = System.Runtime.InteropServices.GCHandle.FromIntPtr(gcHandlePtr);")
            b.AppendLine("var self = ({0})System.Runtime.InteropServices.GCHandle.FromIntPtr(gcHandlePtr).Target;", ClassName);
            b.BeginIf("self == null || self.CallbacksDisabled");
            if (!sig.ReturnType.IsVoid)
            {
                sig.ReturnType.EmitSetCallbackReturnValueToDefaultStatements(b);
            }
            foreach (var arg in sig.Parameters)
            {
                if (!arg.IsThisArgument)
                {
                    arg.ParameterType.EmitSetCallbackArgumentToDefaultStatements(b, arg.VarName);
                }
            }
            b.AppendLine("return;");
            b.EndBlock();
            b.AppendLine("var e = new {0}();", cb.PublicEventArgsClassName);
            for (var i = 1; i <= sig.ManagedParameters.Count() - 1; i++)
            {
                if (sig.ManagedParameters[i].ParameterType.IsIn)
                {
                    sig.ManagedParameters[i].EmitPublicEventFieldInitializers(b);
                }
            }
            b.AppendLine("self.m_{0}?.Invoke(self, e);", cb.PublicName);
            b.AppendLine("e.m_isInvalid = true;");

            for (var i = 1; i <= sig.ManagedParameters.Count() - 1; i++)
            {
                sig.ManagedParameters[i].EmitPostPublicRaiseEventStatements(b);
            }

            sig.EmitPostPublicEventHandlerReturnValueStatements(b);

            b.EndBlock();
            b.AppendLine();
        }

        if (NeedsWrapFunction)
        {
            b.AppendLine("internal {0}(IntPtr nativePtr) : base(nativePtr) {{}}", ClassName);
        }
        b.AppendLine("public {0}() : base(CfxApi.{1}.{2}_ctor) {{}}", ClassName, ApiClassName, CfxName);
        b.AppendLine();

        var cbIndex = 0;

        foreach (var cb in CallbackFunctions)
        {
            EmitPublicEvent(b, cbIndex, cb);
            b.AppendLine();
            cbIndex += 1;
        }

        var onlyBasicEvents = true;

        b.BeginFunction("OnDispose", "void", "IntPtr nativePtr", "internal override");
        cbIndex = 0;
        foreach (var cb in CallbackFunctions)
        {
            onlyBasicEvents &= cb.IsBasicEvent;
            b.BeginIf("m_{0} != null", cb.PublicName);
            b.AppendLine("m_{0} = null;", cb.PublicName);
            b.AppendLine("CfxApi.{0}.{1}_set_callback(NativePtr, {2}, IntPtr.Zero);", ApiClassName, CfxName, cbIndex);
            b.EndBlock();
            cbIndex += 1;
        }
        b.AppendLine("base.OnDispose(nativePtr);");
        b.EndBlock();

        b.EndBlock();

        if (!onlyBasicEvents)
        {
            b.AppendLine();
            b.AppendLine();

            b.BeginBlock("namespace Event");
            b.AppendLine();

            foreach (var cb in CallbackFunctions)
            {
                EmitPublicEventArgsAndHandler(b, cb);
                b.AppendLine();
            }

            b.EndBlock();
        }
    }
    public void EmitRemoteClient(CodeBuilder b)
    {
        b.BeginClass(ClassName + "RemoteClient", "internal static");
        b.AppendLine();

        b.BeginBlock("static {0}RemoteClient()", ClassName);

        foreach (var sm in RemoteCallbackFunctions)
        {
            b.AppendLine("{0}_native = {0};", sm.Name);
        }
        foreach (var sm in RemoteCallbackFunctions)
        {
            b.AppendLine("{0}_native_ptr = System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate({0}_native);", sm.Name);
        }

        b.EndBlock();
        b.AppendLine();

        b.BeginBlock("internal static void SetCallback(IntPtr self, int index, bool active)");
        b.BeginBlock("switch(index)");
        foreach (var cb in RemoteCallbackFunctions)
        {
            b.AppendLine("case {0}:", cb.ClientCallbackIndex);
            b.IncreaseIndent();
            b.AppendLine("CfxApi.{0}.{1}_set_callback(self, index, active ? {2}_native_ptr : IntPtr.Zero);", ApiClassName, CfxName, cb.Name);
            b.AppendLine("break;");
            b.DecreaseIndent();
        }
        b.EndBlock();
        b.EndBlock();
        b.AppendLine();

        foreach (var cb in RemoteCallbackFunctions)
        {
            var sig = cb.Signature;

            b.AppendComment(cb.ToString());
            CodeSnippets.EmitPInvokeCallbackDelegate(b, cb.Name, cb.Signature);
            b.AppendLine("private static {0}_delegate {0}_native;", cb.Name);
            b.AppendLine("private static IntPtr {0}_native_ptr;", cb.Name);
            b.AppendLine();

            var inArgumentList = new List <string>();

            foreach (var arg in sig.Parameters)
            {
                if (!arg.IsThisArgument)
                {
                    foreach (var pm in arg.ParameterType.RemoteCallbackParameterList(arg.VarName))
                    {
                        if (!pm.StartsWith("out "))
                        {
                            inArgumentList.Add(pm.Substring(pm.LastIndexOf(' ') + 1));
                        }
                    }
                }
            }

            b.BeginFunction(cb.Name, "void", sig.PInvokeParameterList, "internal static");
            b.AppendLine("var call = new {0}RemoteEventCall();", cb.RemoteCallName);
            b.AppendLine("call.gcHandlePtr = gcHandlePtr;");
            foreach (var pm in inArgumentList)
            {
                b.AppendLine("call.{0} = {0};", pm);
            }
            b.AppendLine("call.RequestExecution();");
            foreach (var arg in sig.Parameters)
            {
                if (!arg.IsThisArgument)
                {
                    arg.ParameterType.EmitPostRemoteCallbackStatements(b, arg.VarName);
                }
            }
            if (!sig.ReturnType.IsVoid)
            {
                b.AppendLine("__retval = call.__retval;");
            }

            //sig.EmitPostPublicEventHandlerCallStatements(b);

            b.EndBlock();
            b.AppendLine();
        }


        b.EndBlock();
    }
Beispiel #10
0
    public void EmitRemoteEventArgsAndHandler(CodeBuilder b, CommentData comments)
    {
        if (IsBasicEvent)
        {
            return;
        }

        b.AppendSummaryAndRemarks(comments, true, true);
        b.AppendLine("public delegate void {0}(object sender, {1} e);", RemoteEventHandlerName, RemoteEventArgsClassName);
        b.AppendLine();

        b.AppendSummaryAndRemarks(comments, true, true);
        b.BeginClass(RemoteEventArgsClassName + " : CfrEventArgs", GeneratorConfig.ClassModifiers(RemoteEventArgsClassName));
        b.AppendLine();

        for (var i = 1; i <= Signature.ManagedArguments.Count() - 1; i++)
        {
            if (Signature.ManagedArguments[i].ArgumentType.IsIn)
            {
                b.AppendLine("bool {0}Fetched;", Signature.ManagedArguments[i].PublicPropertyName);
                b.AppendLine("{0} m_{1};", Signature.ManagedArguments[i].ArgumentType.RemoteSymbol, Signature.ManagedArguments[i].PublicPropertyName);
            }
        }
        b.AppendLine();

        if (!Signature.PublicReturnType.IsVoid)
        {
            b.AppendLine("private bool returnValueSet;");
            b.AppendLine();
        }

        b.AppendLine("internal {0}(ulong eventArgsId) : base(eventArgsId) {{}}", RemoteEventArgsClassName);
        b.AppendLine();

        for (var i = 1; i <= Signature.ManagedArguments.Count() - 1; i++)
        {
            var arg = Signature.ManagedArguments[i];
            var cd  = new CommentData();
            if (arg.ArgumentType.IsIn && arg.ArgumentType.IsOut)
            {
                cd.Lines = new string[] { string.Format("Get or set the {0} parameter for the <see cref=\"{1}.{2}\"/> render process callback.", arg.PublicPropertyName, Parent.RemoteSymbol, PublicFunctionName) };
            }
            else if (arg.ArgumentType.IsIn)
            {
                cd.Lines = new string[] { string.Format("Get the {0} parameter for the <see cref=\"{1}.{2}\"/> render process callback.", arg.PublicPropertyName, Parent.RemoteSymbol, PublicFunctionName) };
            }
            else
            {
                cd.Lines = new string[] { string.Format("Set the {0} out parameter for the <see cref=\"{1}.{2}\"/> render process callback.", arg.PublicPropertyName, Parent.RemoteSymbol, PublicFunctionName) };
            }
            b.AppendSummary(cd);
            b.BeginBlock("public {0} {1}", arg.ArgumentType.RemoteSymbol, arg.PublicPropertyName);
            if (arg.ArgumentType.IsIn)
            {
                b.BeginBlock("get");
                b.AppendLine("CheckAccess();");
                b.BeginBlock("if(!{0}Fetched)", arg.PublicPropertyName);
                b.AppendLine("{0}Fetched = true;", arg.PublicPropertyName);
                b.AppendLine("var call = new {0}Get{1}RenderProcessCall();", EventName, arg.PublicPropertyName);
                b.AppendLine("call.eventArgsId = eventArgsId;");
                b.AppendLine("call.RequestExecution(CfxRemoteCallContext.CurrentContext.connection);");
                b.AppendLine("m_{0} = {1};", arg.PublicPropertyName, arg.ArgumentType.RemoteWrapExpression("call.value"));
                b.EndBlock();
                b.AppendLine("return m_{0};", arg.PublicPropertyName);
                b.EndBlock();
            }
            if (arg.ArgumentType.IsOut)
            {
                b.BeginBlock("set");
                b.AppendLine("CheckAccess();");
                if (arg.ArgumentType.IsIn)
                {
                    b.AppendLine("m_{0} = value;", arg.PublicPropertyName);
                    b.AppendLine("{0}Fetched = true;", arg.PublicPropertyName);
                }
                b.AppendLine("var call = new {0}Set{1}RenderProcessCall();", EventName, arg.PublicPropertyName);
                b.AppendLine("call.eventArgsId = eventArgsId;");
                b.AppendLine("call.value = {0};", arg.ArgumentType.RemoteUnwrapExpression("value"));
                b.AppendLine("call.RequestExecution(CfxRemoteCallContext.CurrentContext.connection);");
                b.EndBlock();
            }
            b.EndBlock();
        }
        if (!Signature.PublicReturnType.IsVoid)
        {
            var cd = new CommentData();
            cd.Lines = new string[] {
                string.Format("Set the return value for the <see cref=\"{0}.{1}\"/> render process callback.", Parent.RemoteClassName, PublicFunctionName),
                "Calling SetReturnValue() more then once per callback or from different event handlers will cause an exception to be thrown."
            };
            b.AppendSummary(cd);
            b.BeginBlock("public void SetReturnValue({0} returnValue)", Signature.PublicReturnType.RemoteSymbol);
            b.BeginIf("returnValueSet");
            b.AppendLine("throw new CfxException(\"The return value has already been set\");");
            b.EndBlock();
            b.AppendLine("var call = new {0}SetReturnValueRenderProcessCall();", EventName);
            b.AppendLine("call.eventArgsId = eventArgsId;");
            b.AppendLine("call.value = {0};", Signature.PublicReturnType.RemoteUnwrapExpression("returnValue"));
            b.AppendLine("call.RequestExecution(CfxRemoteCallContext.CurrentContext.connection);");
            b.AppendLine("returnValueSet = true;");
            b.EndBlock();
        }

        if (Signature.ManagedArguments.Count() > 1)
        {
            b.AppendLine();
            EmitEventToString(b);
        }
        b.EndBlock();
    }
Beispiel #11
0
    public override void EmitRemoteClass(CodeBuilder b)
    {
        b.AppendLine("using Event;");

        b.AppendLine();

        b.AppendSummaryAndRemarks(Comments, true, Category == StructCategory.ApiCallbacks);
        b.BeginClass(RemoteClassName + " : CfrClientBase", GeneratorConfig.ClassModifiers(RemoteClassName));
        b.AppendLine();

        EmitRemoteClassWrapperFunction(b);
        b.AppendLine();

        b.AppendLine("private {0}(RemotePtr remotePtr) : base(remotePtr) {{}}", RemoteClassName);


        b.BeginBlock("public {0}() : base(new {1}CtorWithGCHandleRemoteCall())", RemoteClassName, ClassName);
        b.AppendLine("RemotePtr.connection.weakCache.Add(RemotePtr.ptr, this);");
        b.EndBlock();

        b.AppendLine();

        foreach (var cb in CallbackFunctions)
        {
            if (!GeneratorConfig.IsBrowserProcessOnly(CefStruct.Name + "::" + cb.Name))
            {
                b.AppendSummaryAndRemarks(cb.Comments, true, true);
                b.BeginBlock("public event {0} {1}", cb.RemoteEventHandlerName, CSharp.Escape(cb.PublicName));
                b.BeginBlock("add");
                b.BeginBlock("if(m_{0} == null)", cb.PublicName);
                b.AppendLine("var call = new {0}SetCallbackRemoteCall();", ClassName);
                b.AppendLine("call.self = RemotePtr.ptr;");
                b.AppendLine("call.index = {0};", cb.ClientCallbackIndex);
                b.AppendLine("call.active = true;");
                b.AppendLine("call.RequestExecution(RemotePtr.connection);");
                b.EndBlock();
                b.AppendLine("m_{0} += value;", cb.PublicName);
                b.EndBlock();
                b.BeginBlock("remove");
                b.AppendLine("m_{0} -= value;", cb.PublicName);
                b.BeginBlock("if(m_{0} == null)", cb.PublicName);
                b.AppendLine("var call = new {0}SetCallbackRemoteCall();", ClassName);
                b.AppendLine("call.self = RemotePtr.ptr;");
                b.AppendLine("call.index = {0};", cb.ClientCallbackIndex);
                b.AppendLine("call.active = false;");
                b.AppendLine("call.RequestExecution(RemotePtr.connection);");
                b.EndBlock();
                b.EndBlock();
                b.EndBlock();
                b.AppendLine();
                b.AppendLine("internal {0} m_{1};", cb.RemoteEventHandlerName, cb.PublicName);
                b.AppendLine();
                b.AppendLine();
            }
        }

        b.EndBlock();

        b.AppendLine();
        b.BeginBlock("namespace Event");
        b.AppendLine();

        foreach (var cb in CallbackFunctions)
        {
            if (!GeneratorConfig.IsBrowserProcessOnly(CefStruct.Name + "::" + cb.Name))
            {
                EmitRemoteEventArgsAndHandler(b, cb);
                b.AppendLine();
            }
        }

        b.EndBlock();
    }
    private void BuildRemoteCalls(GeneratedFileManager fileManager)
    {
        var callIds = new List <string>();

        var b = new CodeBuilder();

        b.BeginCfxNamespace(".Remote");
        foreach (var f in remoteDecls.ExportFunctions)
        {
            if (!f.PrivateWrapper)
            {
                b.BeginRemoteCallClass("CfxRuntime" + f.PublicName, callIds);
                f.Signature.EmitRemoteCallClassBody(b, "Runtime", f.CfxApiFunctionName);
                b.EndBlock();
                b.AppendLine();
            }
        }
        b.EndBlock();
        fileManager.WriteFileIfContentChanged("CfxRuntimeRemoteCalls.cs", b.ToString());

        foreach (var t in remoteDecls.CefStructTypes)
        {
            b.Clear();
            b.BeginCfxNamespace(".Remote");
            t.ClassBuilder.EmitRemoteCalls(b, callIds);
            b.EndBlock();
            fileManager.WriteFileIfContentChanged(t.ClassName + "RemoteCalls.cs", b.ToString());
        }

        foreach (var t in remoteDecls.CefStructTypes)
        {
            if (t.ClassBuilder is CfxClientClass)
            {
                b.Clear();
                b.BeginCfxNamespace(".Remote");
                (t.ClassBuilder as CfxClientClass).EmitRemoteClient(b);
                b.EndBlock();
                fileManager.WriteFileIfContentChanged(t.ClassName + "RemoteClient.cs", b.ToString());
            }
        }

        callIds.AddRange(GeneratorConfig.AdditionalCallIds);
        callIds.Sort();

        b.Clear();

        b.BeginCfxNamespace(".Remote");
        b.BeginBlock("internal enum RemoteCallId : ushort");
        foreach (var id in callIds)
        {
            b.AppendLine(id + ",");
        }
        b.TrimRight();
        b.CutRight(1);
        b.AppendLine();
        b.EndBlock();
        b.EndBlock();
        fileManager.WriteFileIfContentChanged("RemoteCallId.cs", b.ToString());

        b.Clear();
        b.BeginCfxNamespace(".Remote");
        b.BeginClass("RemoteCallFactory", "internal");
        b.AppendLine("private delegate RemoteCall RemoteCallCtor();");
        b.BeginBlock("private static RemoteCallCtor[] callConstructors = ");
        foreach (var id in callIds)
        {
            b.AppendLine("() => {{ return new {0}(); }},", id);
        }
        b.EndBlock(";");
        b.AppendLine();

        b.BeginBlock("internal static RemoteCall ForCallId(RemoteCallId id)");
        b.AppendLine("return callConstructors[(int)id]();");
        b.EndBlock();
        b.EndBlock();
        b.EndBlock();
        fileManager.WriteFileIfContentChanged("RemoteCallFactory.cs", b.ToString());
    }
Beispiel #13
0
    public void EmitPublicEventArgsAndHandler(CodeBuilder b, CommentData comments)
    {
        if (emittedHandlers.ContainsKey(EventName))
        {
            var c0 = emittedHandlers[EventName];
            if (c0 != null)
            {
                if (c0.Lines.Length != comments.Lines.Length)
                {
                    System.Diagnostics.Debugger.Break();
                }
                for (var i = 0; i <= c0.Lines.Length - 1; i++)
                {
                    if (c0.Lines[i] != comments.Lines[i])
                    {
                        // two handlers use same event but with different comments
                        System.Diagnostics.Debugger.Break();
                    }
                }
            }
            return;
        }
        emittedHandlers.Add(EventName, comments);

        if (IsBasicEvent)
        {
            return;
        }

        b.AppendSummaryAndRemarks(comments, false, true);
        b.AppendLine("public delegate void {0}(object sender, {1} e);", EventHandlerName, PublicEventArgsClassName);
        b.AppendLine();

        b.AppendSummaryAndRemarks(comments, false, true);
        b.BeginClass(PublicEventArgsClassName + " : CfxEventArgs", GeneratorConfig.ClassModifiers(PublicEventArgsClassName));
        b.AppendLine();

        for (var i = 1; i <= Signature.ManagedArguments.Count() - 1; i++)
        {
            Signature.ManagedArguments[i].EmitPublicEventArgFields(b);
        }
        b.AppendLine();

        if (!Signature.PublicReturnType.IsVoid)
        {
            b.AppendLine("internal {0} m_returnValue;", Signature.PublicReturnType.PublicSymbol);
            b.AppendLine("private bool returnValueSet;");
            b.AppendLine();
        }

        b.BeginBlock("internal {0}({1})", PublicEventArgsClassName, Signature.PublicEventConstructorArgumentList);
        Signature.EmitPublicEventCtorStatements(b);
        b.EndBlock();
        b.AppendLine();

        for (var i = 1; i <= Signature.ManagedArguments.Count() - 1; i++)
        {
            var arg = Signature.ManagedArguments[i];
            var cd  = new CommentData();
            if (arg.ArgumentType.IsIn && arg.ArgumentType.IsOut)
            {
                cd.Lines = new string[] { string.Format("Get or set the {0} parameter for the <see cref=\"{1}.{2}\"/> callback.", arg.PublicPropertyName, Parent.ClassName, PublicName) };
            }
            else if (arg.ArgumentType.IsIn)
            {
                cd.Lines = new string[] { string.Format("Get the {0} parameter for the <see cref=\"{1}.{2}\"/> callback.", arg.PublicPropertyName, Parent.ClassName, PublicName) };
            }
            else
            {
                cd.Lines = new string[] { string.Format("Set the {0} out parameter for the <see cref=\"{1}.{2}\"/> callback.", arg.PublicPropertyName, Parent.ClassName, PublicName) };
            }
            if (arg.ArgumentType is CefStructArrayType && arg.ArgumentType.IsIn)
            {
                cd.Lines = cd.Lines.Concat(new string[] { "Do not keep a reference to the elements of this array outside of this function." }).ToArray();
            }
            b.AppendSummary(cd);
            b.BeginBlock("public {0} {1}", arg.ArgumentType.PublicSymbol, arg.PublicPropertyName);
            if (arg.ArgumentType.IsIn)
            {
                b.BeginBlock("get");
                b.AppendLine("CheckAccess();");
                arg.EmitPublicEventArgGetterStatements(b);
                b.EndBlock();
            }
            if (arg.ArgumentType.IsOut)
            {
                b.BeginBlock("set");
                b.AppendLine("CheckAccess();");
                arg.EmitPublicEventArgSetterStatements(b);
                b.EndBlock();
            }
            b.EndBlock();
        }

        if (!Signature.PublicReturnType.IsVoid)
        {
            var cd = new CommentData();
            cd.Lines = new string[] {
                string.Format("Set the return value for the <see cref=\"{0}.{1}\"/> callback.", Parent.ClassName, PublicFunctionName),
                "Calling SetReturnValue() more then once per callback or from different event handlers will cause an exception to be thrown."
            };
            b.AppendSummary(cd);
            b.BeginBlock("public void SetReturnValue({0} returnValue)", Signature.PublicReturnType.PublicSymbol);
            b.AppendLine("CheckAccess();");
            b.BeginIf("returnValueSet");
            b.AppendLine("throw new CfxException(\"The return value has already been set\");");
            b.EndBlock();
            b.AppendLine("returnValueSet = true;");
            b.AppendLine("this.m_returnValue = returnValue;");
            b.EndBlock();
        }

        if (Signature.ManagedArguments.Count() > 1)
        {
            b.AppendLine();
            EmitEventToString(b);
        }
        b.EndBlock();
    }
    public override void EmitPublicClass(CodeBuilder b)
    {
        //asserts

        foreach (var sm in StructMembers)
        {
            if (sm.MemberType.IsCefStructPtrType)
            {
                System.Diagnostics.Debugger.Break();
            }
            if (sm.MemberType.IsCefStructType && sm.MemberType.AsCefStructType.IsRefCounted)
            {
                System.Diagnostics.Debugger.Break();
            }
        }

        b.AppendSummaryAndRemarks(Comments);

        if (CefStruct.IsCefPlatformStructType)
        {
            b.BeginClass(ClassName + " : CfxStructure", GeneratorConfig.ClassModifiers(ClassName, "internal sealed"));
        }
        else
        {
            b.BeginClass(ClassName + " : CfxStructure", GeneratorConfig.ClassModifiers(ClassName, "public sealed"));
        }
        b.AppendLine();

        if (NeedsWrapFunction)
        {
            b.BeginFunction("Wrap", ClassName, "IntPtr nativePtr", "internal static");
            b.AppendLine("if(nativePtr == IntPtr.Zero) return null;");
            b.AppendLine("return new {0}(nativePtr);", ClassName);
            b.EndBlock();
            b.AppendLine();
            b.BeginFunction("WrapOwned", ClassName, "IntPtr nativePtr", "internal static");
            b.AppendLine("if(nativePtr == IntPtr.Zero) return null;");
            b.AppendLine("return new {0}(nativePtr, CfxApi.{1}.{2}_dtor);", ClassName, ApiClassName, CfxName);
            b.EndBlock();
            b.AppendLine();
        }

        if (CefStruct.IsCefPlatformStructType)
        {
            b.AppendLine("public {0}() : base(CfxApi.{1}.{2}_ctor, CfxApi.{1}.{2}_dtor) {{ CfxApi.CheckPlatformOS(CfxPlatformOS.{3}); }}", ClassName, ApiClassName, CfxName, CefStruct.AsCefPlatformStructType.Platform.ToString());
        }
        else
        {
            b.AppendLine("public {0}() : base(CfxApi.{1}.{2}_ctor, CfxApi.{1}.{2}_dtor) {{}}", ClassName, ApiClassName, CfxName);
        }

        if (NeedsWrapFunction)
        {
            b.AppendLine("internal {0}(IntPtr nativePtr) : base(nativePtr) {{}}", ClassName);
            b.AppendLine("internal {0}(IntPtr nativePtr, CfxApi.cfx_dtor_delegate cfx_dtor) : base(nativePtr, cfx_dtor) {{}}", ClassName);
        }
        b.AppendLine();

        foreach (var sm in StructMembers)
        {
            b.AppendSummaryAndRemarks(sm.Comments);
            b.BeginBlock("public {1} {0}", CSharp.Escape(sm.PublicName), sm.MemberType.PublicSymbol);
            b.BeginBlock("get");
            sm.MemberType.EmitValueStructGetterVars(b, "value");
            b.AppendLine("CfxApi.{3}.{0}_get_{1}(nativePtrUnchecked, {2});", CfxName, sm.Name, sm.MemberType.PInvokeOutArgument("value"), ApiClassName);
            b.AppendLine("return {0};", sm.MemberType.PublicWrapExpression("value"));
            b.EndBlock();
            b.BeginBlock("set");
            sm.MemberType.EmitPublicPreCallStatements(b, "value");
            b.AppendLine("CfxApi.{3}.{0}_set_{1}(nativePtrUnchecked, {2});", CfxName, sm.Name, sm.MemberType.PublicUnwrapExpression("value"), ApiClassName);
            sm.MemberType.EmitPublicPostCallStatements(b, "value");
            b.EndBlock();
            b.EndBlock();
            b.AppendLine();
        }

        b.EndBlock();
    }
    private void BuildPInvokeApi(GeneratedFileManager fileManager)
    {
        var b = new CodeBuilder();

        b.AppendLine("using System.Runtime.InteropServices;");
        b.AppendLine();
        b.BeginCfxNamespace();
        b.BeginClass("CfxApi", "internal partial");

        b.AppendLine();

        b.BeginClass("Runtime", "internal static");

        foreach (var f in decls.ExportFunctions)
        {
            f.EmitPInvokeDeclaration(b);
        }
        b.AppendLine();

        foreach (var f in decls.StringCollectionFunctions)
        {
            f.EmitPInvokeDeclaration(b);
        }
        b.EndBlock();

        b.AppendLine();

        foreach (var t in decls.CefStructTypes)
        {
            t.ClassBuilder.EmitApiClass(b);
            b.AppendLine();
        }

        b.EndBlock();
        b.EndBlock();

        fileManager.WriteFileIfContentChanged("CfxApi.cs", b.ToString());
        b.Clear();

        var cfxfuncs = decls.GetCfxApiFunctionNames();

        b.BeginCfxNamespace();
        b.BeginClass("CfxApiLoader", "internal partial");
        b.BeginBlock("internal enum FunctionIndex");
        foreach (var f in cfxfuncs)
        {
            b.AppendLine(f + ",");
        }

        b.EndBlock();
        b.AppendLine();

        b.BeginFunction("void LoadCfxRuntimeApi()", "internal static");
        foreach (var f in decls.ExportFunctions)
        {
            if (f.Platform != CefPlatform.Independent)
            {
                b.BeginIf("CfxApi.PlatformOS == CfxPlatformOS.{0}", f.Platform.ToString());
            }
            CodeSnippets.EmitPInvokeDelegateInitialization(b, "Runtime", f.CfxApiFunctionName);
            if (f.Platform != CefPlatform.Independent)
            {
                b.EndBlock();
            }
        }
        b.EndBlock();
        b.AppendLine();

        b.BeginFunction("void LoadStringCollectionApi()", "internal static");
        b.AppendLine("CfxApi.Probe();");
        foreach (var f in decls.StringCollectionFunctions)
        {
            CodeSnippets.EmitPInvokeDelegateInitialization(b, "Runtime", f.CfxApiFunctionName);
        }
        b.EndBlock();
        b.AppendLine();

        foreach (var cefStruct in decls.CefStructTypes)
        {
            b.BeginBlock("internal static void Load{0}Api()", cefStruct.ClassName);
            b.AppendLine("CfxApi.Probe();");

            var apiClassName = cefStruct.ClassName.Substring(3);

            switch (cefStruct.ClassBuilder.Category)
            {
            case StructCategory.Library:
                foreach (var f in cefStruct.ClassBuilder.ExportFunctions)
                {
                    CodeSnippets.EmitPInvokeDelegateInitialization(b, f.PublicClassName.Substring(3), f.CfxApiFunctionName);
                }
                foreach (var cb in cefStruct.ClassBuilder.CallbackFunctions)
                {
                    CodeSnippets.EmitPInvokeDelegateInitialization(b, cb.PublicClassName.Substring(3), cb.CfxApiFunctionName);
                }

                break;

            case StructCategory.Client:
                b.AppendLine("CfxApi.{0}.{1}_ctor = (CfxApi.cfx_ctor_with_gc_handle_delegate)CfxApi.GetDelegate(FunctionIndex.{1}_ctor, typeof(CfxApi.cfx_ctor_with_gc_handle_delegate));", apiClassName, cefStruct.CfxName);
                if (cefStruct.ClassBuilder.NeedsWrapFunction)
                {
                    b.AppendLine("CfxApi.{0}.{1}_get_gc_handle = (CfxApi.cfx_get_gc_handle_delegate)CfxApi.GetDelegate(FunctionIndex.{1}_get_gc_handle, typeof(CfxApi.cfx_get_gc_handle_delegate));", apiClassName, cefStruct.CfxName);
                }
                b.AppendLine("CfxApi.{0}.{1}_set_callback = (CfxApi.cfx_set_callback_delegate)CfxApi.GetDelegate(FunctionIndex.{1}_set_callback, typeof(CfxApi.cfx_set_callback_delegate));", apiClassName, cefStruct.CfxName);
                b.AppendLine("{0}.SetNativeCallbacks();", cefStruct.ClassName);
                break;

            case StructCategory.Values:
                b.AppendLine("CfxApi.{0}.{1}_ctor = (CfxApi.cfx_ctor_delegate)CfxApi.GetDelegate(FunctionIndex.{1}_ctor, typeof(CfxApi.cfx_ctor_delegate));", apiClassName, cefStruct.CfxName);
                b.AppendLine("CfxApi.{0}.{1}_dtor = (CfxApi.cfx_dtor_delegate)CfxApi.GetDelegate(FunctionIndex.{1}_dtor, typeof(CfxApi.cfx_dtor_delegate));", apiClassName, cefStruct.CfxName);

                foreach (var sm in cefStruct.ClassBuilder.StructMembers)
                {
                    CodeSnippets.EmitPInvokeDelegateInitialization(b, apiClassName, cefStruct.CfxName + "_set_" + sm.Name);
                    CodeSnippets.EmitPInvokeDelegateInitialization(b, apiClassName, cefStruct.CfxName + "_get_" + sm.Name);
                }

                break;
            }
            b.EndBlock();
            b.AppendLine();
        }

        b.EndBlock();
        b.EndBlock();

        fileManager.WriteFileIfContentChanged("CfxApiLoader.cs", b.ToString());
    }
    public override void EmitPublicClass(CodeBuilder b)
    {
        b.AppendSummaryAndRemarks(Comments);

        if (CefStruct.IsRefCounted)
        {
            b.BeginClass(ClassName + " : CfxBaseLibrary", GeneratorConfig.ClassModifiers(ClassName));
        }
        else if (CefStruct.IsScoped)
        {
            b.BeginClass(ClassName + " : CfxBaseScoped", GeneratorConfig.ClassModifiers(ClassName));
        }
        else
        {
            throw new Exception();
        }

        b.AppendLine();

        b.BeginFunction("Wrap", ClassName, "IntPtr nativePtr", "internal static");
        b.AppendLine("if(nativePtr == IntPtr.Zero) return null;");
        if (CefStruct.IsRefCounted)
        {
            b.AppendLine("bool isNew = false;");
            b.BeginBlock("var wrapper = ({0})weakCache.GetOrAdd(nativePtr, () => ", ClassName);
            b.AppendLine("isNew = true;");
            b.AppendLine("return new {0}(nativePtr);", ClassName);
            b.EndBlock(");");
            b.BeginBlock("if(!isNew)");
            //release the new ref and reuse the existing ref
            b.AppendLine("CfxApi.cfx_release(nativePtr);");
            b.EndBlock();
            b.AppendLine("return wrapper;");
        }
        else
        {
            b.AppendLine("return new {0}(nativePtr);", ClassName);
        }
        b.EndBlock();
        b.AppendLine();
        b.AppendLine();

        b.AppendLine("internal {0}(IntPtr nativePtr) : base(nativePtr) {{}}", ClassName);

        foreach (var f in ExportFunctions)
        {
            b.AppendLine();
            f.EmitPublicFunction(b, ApiClassName);
        }

        foreach (var p in m_structProperties)
        {
            b.AppendLine();
            if (p.Setter != null && p.Setter.Comments != null)
            {
                var summary = new CommentNode();
                summary.FileName = p.Getter.Comments.FileName;

                if (p.Getter.Comments.Lines.Length == 1 && p.Setter.Comments.Lines.Length == 1 && p.Getter.Comments.Lines[0].StartsWith("Get ") && p.Setter.Comments.Lines[0].StartsWith("Set ") && p.Getter.Comments.Lines[0].Substring(4).Equals(p.Setter.Comments.Lines[0].Substring(4)))
                {
                    summary.Lines = new string[] { "Get or set " + p.Getter.Comments.Lines[0].Substring(4) };
                }
                else
                {
                    List <string> summaryLines = new List <string>();
                    summaryLines.AddRange(p.Getter.Comments.Lines);
                    summaryLines.Add("");
                    summaryLines.AddRange(p.Setter.Comments.Lines);
                    summary.Lines = summaryLines.ToArray();
                }

                b.AppendSummaryAndRemarks(summary);
            }
            else
            {
                b.AppendSummaryAndRemarks(p.Getter.Comments);
            }
            EmitPublicProperty(b, p);
        }

        foreach (var sf in m_structFunctions)
        {
            b.AppendLine();
            b.AppendSummaryAndRemarks(sf.Comments);
            if (GeneratorConfig.HasPrivateWrapper(sf.Parent.Name + "::" + sf.Name))
            {
                b.BeginFunction(sf.Signature.PublicFunctionHeader(sf.PublicName), "private");
            }
            else
            {
                b.BeginFunction(sf.Signature.PublicFunctionHeader(sf.PublicName));
            }
            sf.Signature.EmitPublicCall(b, ApiClassName, sf.CfxApiFunctionName);
            b.EndBlock();
        }

        b.EndBlock();
    }
    private void BuildPInvokeApi(GeneratedFileManager fileManager)
    {
        var b = new CodeBuilder();

        b.AppendLine("using System.Runtime.InteropServices;");
        b.AppendLine();
        b.BeginCfxNamespace();
        b.BeginClass("CfxApi", "internal partial");

        b.AppendLine();

        b.AppendComment("global cef export functions");
        b.AppendLine();

        foreach (var f in decls.ExportFunctions)
        {
            f.EmitPInvokeDeclaration(b);
        }
        b.AppendLine();

        foreach (var f in decls.StringCollectionFunctions)
        {
            f.EmitPInvokeDeclaration(b);
        }
        b.AppendLine();

        b.AppendLine();

        foreach (var t in decls.CefStructTypes)
        {
            t.ClassBuilder.EmitApiDeclarations(b);
            b.AppendLine();
        }

        b.EndBlock();
        b.EndBlock();

        fileManager.WriteFileIfContentChanged("CfxApi.cs", b.ToString());
        b.Clear();

        var cfxfuncs = decls.GetCfxApiFunctionNames();

        b.BeginCfxNamespace();
        b.BeginClass("CfxApiLoader", "internal partial");
        b.BeginBlock("internal enum FunctionIndex");
        foreach (var f in cfxfuncs)
        {
            b.AppendLine(f + ",");
        }

        b.EndBlock();
        b.AppendLine();

        b.BeginFunction("void LoadCfxRuntimeApi()", "internal static");
        foreach (var f in decls.ExportFunctions)
        {
            if (f.Platform != CefPlatform.Independent)
            {
                b.BeginIf("CfxApi.PlatformOS == CfxPlatformOS.{0}", f.Platform.ToString());
            }
            CodeSnippets.EmitPInvokeDelegateInitialization(b, f.CfxName);
            if (f.Platform != CefPlatform.Independent)
            {
                b.EndBlock();
            }
        }
        b.EndBlock();
        b.AppendLine();

        b.BeginFunction("void LoadStringCollectionApi()", "internal static");
        b.AppendLine("CfxApi.Probe();");
        foreach (var f in decls.StringCollectionFunctions)
        {
            CodeSnippets.EmitPInvokeDelegateInitialization(b, f.CfxName);
        }
        b.EndBlock();
        b.AppendLine();

        foreach (var cefStruct in decls.CefStructTypes)
        {
            b.AppendLine("private static bool {0}ApiLoaded;", cefStruct.ClassName);
            b.BeginBlock("internal static void Load{0}Api()", cefStruct.ClassName);
            b.AppendLine("if({0}ApiLoaded) return;", cefStruct.ClassName);
            b.AppendLine("{0}ApiLoaded = true;", cefStruct.ClassName);
            b.AppendLine("CfxApi.Probe();");
            switch (cefStruct.ClassBuilder.Category)
            {
            case StructCategory.ApiCalls:
                if (cefStruct.ClassBuilder.ExportFunctions.Count() > 0)
                {
                    foreach (var f in cefStruct.ClassBuilder.ExportFunctions)
                    {
                        CodeSnippets.EmitPInvokeDelegateInitialization(b, f.CfxName);
                    }
                }
                foreach (var sm in cefStruct.ClassBuilder.StructMembers)
                {
                    if (sm.MemberType.IsCefCallbackType)
                    {
                        CodeSnippets.EmitPInvokeDelegateInitialization(b, cefStruct.CfxName + "_" + sm.Name);
                    }
                }

                break;

            case StructCategory.ApiCallbacks:
                b.AppendLine("CfxApi.{0}_ctor = (CfxApi.cfx_ctor_with_gc_handle_delegate)CfxApi.GetDelegate(FunctionIndex.{0}_ctor, typeof(CfxApi.cfx_ctor_with_gc_handle_delegate));", cefStruct.CfxName);
                b.AppendLine("CfxApi.{0}_get_gc_handle = (CfxApi.cfx_get_gc_handle_delegate)CfxApi.GetDelegate(FunctionIndex.{0}_get_gc_handle, typeof(CfxApi.cfx_get_gc_handle_delegate));", cefStruct.CfxName);
                b.AppendLine("CfxApi.{0}_set_managed_callback = (CfxApi.cfx_set_callback_delegate)CfxApi.GetDelegate(FunctionIndex.{0}_set_managed_callback, typeof(CfxApi.cfx_set_callback_delegate));", cefStruct.CfxName);
                if (cefStruct.ClassBuilder.ExportFunctions.Count() > 0)
                {
                    System.Diagnostics.Debugger.Break();
                }
                break;

            case StructCategory.Values:
                b.AppendLine("CfxApi.{0}_ctor = (CfxApi.cfx_ctor_delegate)CfxApi.GetDelegate(FunctionIndex.{0}_ctor, typeof(CfxApi.cfx_ctor_delegate));", cefStruct.CfxName);
                b.AppendLine("CfxApi.{0}_dtor = (CfxApi.cfx_dtor_delegate)CfxApi.GetDelegate(FunctionIndex.{0}_dtor, typeof(CfxApi.cfx_dtor_delegate));", cefStruct.CfxName);

                foreach (var sm in cefStruct.ClassBuilder.StructMembers)
                {
                    if (sm.Name != "size")
                    {
                        CodeSnippets.EmitPInvokeDelegateInitialization(b, cefStruct.CfxName + "_set_" + sm.Name);
                        CodeSnippets.EmitPInvokeDelegateInitialization(b, cefStruct.CfxName + "_get_" + sm.Name);
                    }
                }

                if (cefStruct.ClassBuilder.ExportFunctions.Count() > 0)
                {
                    System.Diagnostics.Debugger.Break();
                }

                break;
            }
            b.EndBlock();
            b.AppendLine();
        }

        b.EndBlock();
        b.EndBlock();

        fileManager.WriteFileIfContentChanged("CfxApiLoader.cs", b.ToString());
    }
Beispiel #18
0
    public override void EmitPublicClass(CodeBuilder b)
    {
        b.AppendSummaryAndRemarks(Comments);

        b.BeginClass(ClassName + " : CfxLibraryBase", GeneratorConfig.ClassModifiers(ClassName));
        b.AppendLine();

        b.AppendLine("private static readonly WeakCache weakCache = new WeakCache();");
        b.AppendLine();
        b.BeginFunction("Wrap", ClassName, "IntPtr nativePtr", "internal static");
        b.AppendLine("if(nativePtr == IntPtr.Zero) return null;");
        b.BeginBlock("lock(weakCache)");
        b.AppendLine("var wrapper = ({0})weakCache.Get(nativePtr);", ClassName);
        b.BeginBlock("if(wrapper == null)");
        b.AppendLine("wrapper = new {0}(nativePtr);", ClassName);
        b.AppendLine("weakCache.Add(wrapper);");
        b.BeginElse();
        //release the new ref and reuse the existing ref
        b.AppendLine("CfxApi.cfx_release(nativePtr);");
        b.EndBlock();
        b.AppendLine("return wrapper;");
        b.EndBlock();
        b.EndBlock();
        b.AppendLine();
        b.AppendLine();

        b.AppendLine("internal {0}(IntPtr nativePtr) : base(nativePtr) {{}}", ClassName);

        b.AppendLine();

        foreach (var f in ExportFunctions)
        {
            f.EmitPublicFunction(b, ApiClassName);
            b.AppendLine();
        }

        foreach (var p in m_structProperties)
        {
            if (p.Setter != null && p.Setter.Comments != null)
            {
                var summary = new CommentData();
                summary.FileName = p.Getter.Comments.FileName;

                if (p.Getter.Comments.Lines.Length == 1 && p.Setter.Comments.Lines.Length == 1 && p.Getter.Comments.Lines[0].StartsWith("Get ") && p.Setter.Comments.Lines[0].StartsWith("Set ") && p.Getter.Comments.Lines[0].Substring(4).Equals(p.Setter.Comments.Lines[0].Substring(4)))
                {
                    summary.Lines = new string[] { "Get or set " + p.Getter.Comments.Lines[0].Substring(4) };
                }
                else
                {
                    List <string> summaryLines = new List <string>();
                    summaryLines.AddRange(p.Getter.Comments.Lines);
                    summaryLines.Add("");
                    summaryLines.AddRange(p.Setter.Comments.Lines);
                    summary.Lines = summaryLines.ToArray();
                }

                b.AppendSummaryAndRemarks(summary);
            }
            else
            {
                b.AppendSummaryAndRemarks(p.Getter.Comments);
            }
            EmitPublicProperty(b, p);
            b.AppendLine();
        }

        foreach (var sf in m_structFunctions)
        {
            b.AppendSummaryAndRemarks(sf.Comments);
            if (GeneratorConfig.HasPrivateWrapper(sf.Parent.Name + "::" + sf.Name))
            {
                b.BeginFunction(sf.Signature.PublicFunctionHeader(sf.PublicName), "private");
            }
            else
            {
                b.BeginFunction(sf.Signature.PublicFunctionHeader(sf.PublicName));
            }
            sf.Signature.EmitPublicCall(b, ApiClassName, sf.CfxApiFunctionName);
            b.EndBlock();
            b.AppendLine();
        }

        b.BeginFunction("OnDispose", "void", "IntPtr nativePtr", "internal override");
        b.AppendLine("weakCache.Remove(nativePtr);");
        b.AppendLine("base.OnDispose(nativePtr);");
        b.EndBlock();

        b.EndBlock();
    }
Beispiel #19
0
    public override void EmitRemoteClass(CodeBuilder b)
    {
        b.AppendLine();

        b.AppendSummaryAndRemarks(Comments, true, Category == StructCategory.ApiCallbacks);
        b.BeginClass(RemoteClassName + " : CfrLibraryBase", GeneratorConfig.ClassModifiers(RemoteClassName));
        b.AppendLine();

        EmitRemoteClassWrapperFunction(b);

        foreach (var f in ExportFunctions)
        {
            if (!GeneratorConfig.IsBrowserProcessOnly(f.Name) && !f.PrivateWrapper)
            {
                f.EmitRemoteFunction(b);
                b.AppendLine();
            }
        }

        b.AppendLine();

        b.AppendLine("private {0}(RemotePtr remotePtr) : base(remotePtr) {{}}", RemoteClassName);

        foreach (var p in m_structProperties)
        {
            if (GeneratorConfig.CreateRemoteProxy(CefStruct.Name + "::" + p.Getter.Name))
            {
                var cb = p.Getter;

                b.AppendLine();

                if (p.Setter != null && p.Setter.Comments != null)
                {
                    List <string> summaryLines = new List <string>();
                    summaryLines.AddRange(p.Getter.Comments.Lines);
                    summaryLines.Add("");
                    summaryLines.AddRange(p.Setter.Comments.Lines);
                    var summary = new CommentData();
                    summary.Lines    = summaryLines.ToArray();
                    summary.FileName = p.Getter.Comments.FileName;
                    //If RemoteClassName = "CfrRequest" AndAlso p.Getter.PublicName = "GetFlags" Then Stop
                    b.AppendSummaryAndRemarks(summary, true);
                }
                else
                {
                    b.AppendSummaryAndRemarks(p.Getter.Comments, true);
                }

                b.BeginBlock("public {0} {1}", cb.RemoteReturnType.RemoteSymbol, p.PropertyName);
                b.BeginBlock("get");
                p.Getter.Signature.EmitRemoteCall(b, p.Getter.RemoteCallId, false);
                b.EndBlock();
                if (p.Setter != null)
                {
                    b.BeginBlock("set");
                    p.Setter.Signature.EmitRemoteCall(b, p.Setter.RemoteCallId, false);
                    b.EndBlock();
                }
                b.EndBlock();
            }
        }

        foreach (var cb in m_structFunctions)
        {
            if (GeneratorConfig.CreateRemoteProxy(CefStruct.Name + "::" + cb.Name))
            {
                b.AppendLine();
                b.AppendSummaryAndRemarks(cb.Comments, true);
                b.BeginFunction(cb.PublicName, cb.RemoteReturnType.RemoteSymbol, cb.Signature.RemoteParameterList);
                cb.Signature.EmitRemoteCall(b, cb.RemoteCallId, false);
                b.EndBlock();
            }
        }


        b.EndBlock();
    }
    public override void EmitRemoteClass(CodeBuilder b)
    {
        b.AppendLine();

        b.AppendSummaryAndRemarks(Comments, true, Category == StructCategory.Client);

        if (CefStruct.IsRefCounted)
        {
            b.BeginClass(RemoteClassName + " : CfrBaseLibrary", GeneratorConfig.ClassModifiers(RemoteClassName));
        }
        else if (CefStruct.IsScoped)
        {
            b.BeginClass(RemoteClassName + " : CfrBaseScoped", GeneratorConfig.ClassModifiers(RemoteClassName));
        }
        else
        {
            throw new Exception();
        }

        b.AppendLine();

        b.BeginFunction("Wrap", RemoteClassName, "RemotePtr remotePtr", "internal static");
        b.AppendLine("if(remotePtr == RemotePtr.Zero) return null;");
        if (CefStruct.IsRefCounted)
        {
            b.AppendLine("var weakCache = CfxRemoteCallContext.CurrentContext.connection.weakCache;");
            b.AppendLine("bool isNew = false;");
            b.BeginBlock("var wrapper = ({0})weakCache.GetOrAdd(remotePtr.ptr, () => ", RemoteClassName);
            b.AppendLine("isNew = true;");
            b.AppendLine("return new {0}(remotePtr);", RemoteClassName);
            b.EndBlock(");");
            b.BeginBlock("if(!isNew)");
            //release the new ref and reuse the existing ref
            b.AppendLine("var call = new CfxApiReleaseRemoteCall();");
            b.AppendLine("call.nativePtr = remotePtr.ptr;");
            b.AppendLine("call.RequestExecution(remotePtr.connection);");
            b.EndBlock();
            b.AppendLine("return wrapper;");
        }
        else
        {
            b.AppendLine("return new {0}(remotePtr);", RemoteClassName);
        }
        b.EndBlock();
        b.AppendLine();
        b.AppendLine();

        foreach (var f in ExportFunctions)
        {
            if (!GeneratorConfig.IsBrowserProcessOnly(f.Name) && !f.PrivateWrapper)
            {
                f.EmitRemoteFunction(b);
                b.AppendLine();
            }
        }

        b.AppendLine();

        b.AppendLine("private {0}(RemotePtr remotePtr) : base(remotePtr) {{}}", RemoteClassName);

        foreach (var p in m_structProperties)
        {
            if (GeneratorConfig.CreateRemote(CefStruct.Name + "::" + p.Getter.Name))
            {
                var cb = p.Getter;

                b.AppendLine();

                if (p.Setter != null && p.Setter.Comments != null)
                {
                    List <string> summaryLines = new List <string>();
                    summaryLines.AddRange(p.Getter.Comments.Lines);
                    summaryLines.Add("");
                    summaryLines.AddRange(p.Setter.Comments.Lines);
                    var summary = new CommentNode();
                    summary.Lines    = summaryLines.ToArray();
                    summary.FileName = p.Getter.Comments.FileName;
                    //If RemoteClassName = "CfrRequest" AndAlso p.Getter.PublicName = "GetFlags" Then Stop
                    b.AppendSummaryAndRemarks(summary, true);
                }
                else
                {
                    b.AppendSummaryAndRemarks(p.Getter.Comments, true);
                }

                b.BeginBlock("public {0} {1}", cb.RemoteReturnType.RemoteSymbol, p.PropertyName);
                b.BeginBlock("get");
                p.Getter.Signature.EmitRemoteCall(b, p.Getter.RemoteCallId, false);
                b.EndBlock();
                if (p.Setter != null)
                {
                    b.BeginBlock("set");
                    p.Setter.Signature.EmitRemoteCall(b, p.Setter.RemoteCallId, false);
                    b.EndBlock();
                }
                b.EndBlock();
            }
        }

        foreach (var cb in m_structFunctions)
        {
            if (GeneratorConfig.CreateRemote(CefStruct.Name + "::" + cb.Name))
            {
                b.AppendLine();
                b.AppendSummaryAndRemarks(cb.Comments, true);
                b.BeginFunction(cb.PublicName, cb.RemoteReturnType.RemoteSymbol, cb.Signature.RemoteParameterList);
                cb.Signature.EmitRemoteCall(b, cb.RemoteCallId, false);
                b.EndBlock();
            }
        }


        b.EndBlock();
    }