private ParameterDef BuildParameter(XElement parameterNode, List <Tuple <string, string> > argParams)
        {
            var def = new ParameterDef();

            def.Name  = parameterNode.Element("parameternamelist").Element("parametername").Value;
            def.Brief = parameterNode.Element("parameterdescription").Element("para").Value;

            var arg = argParams.FirstOrDefault(_ => _.Item2 == def.Name);

            if (arg != null)
            {
                def.Type.Parse(settings, arg.Item1);
            }

            return(def);
        }
示例#2
0
        public void Export(string libDirPath, string dllDirPath)
        {
            string dllH_Header = @"
#pragma once

#include <stdio.h>
#include <stdint.h>
#include <memory>
#include <vector>

#include <asd.common.Base.h>
#include ""asd.Core.Base.h""

extern ""C""
{
	ASD_DLLEXPORT void* ASD_STDCALL CreateWrapperDLL();
	ASD_DLLEXPORT void ASD_STDCALL DeleteWrapperDLL(void* o);
}

namespace asd
{
";

            string dllH_Footer = @"
};
";

            string dllCpp_Header = @"
#include ""asd.WrapperDLL.h""

#include ""Sound/asd.Sound.h""
#include ""Sound/asd.SoundSource.h""

#include ""IO/asd.File.h""
#include ""IO/asd.StaticFile.h""
#include ""IO/asd.StreamFile.h""

#include ""Graphics/Media/asd.MediaPlayer.h""

#include ""Tool/asd.Tool.h""

namespace asd
{

";

            string dllCpp_Footer = @"
};

extern ""C""
{

ASD_DLLEXPORT void* ASD_STDCALL CreateWrapperDLL()
{
	return new asd::WrapperDLL();
}

ASD_DLLEXPORT void ASD_STDCALL DeleteWrapperDLL(void* o)
{
	auto o_ = (asd::WrapperDLL*)o;
	delete o_;
}

}

";
            string libH_Header   = @"
#pragma once

#include <stdio.h>
#include <stdint.h>
#include <memory>
#include <vector>

#include ""asd.CoreToEngine.h""

namespace asd {

";
            string libH_Footer   = @"
};
";

            string libCpp_Header = @"
#include ""asd.WrapperLib.h""
#include ""asd.WrapperLib.Internal.h""
#include ""asd.CoreToEngine.h""

namespace asd
{

static WrapperDLL* dll = nullptr;

void InitializeWrapper(CreateWrapperDLLFunc func) {
	dll = (WrapperDLL*)func();
};

void TerminateWrapper(DeleteWrapperDLLFunc func) {
	func(dll);
};

";
            string libCpp_Footer = @"
};
";

            string StreamFile_Additional = @"
/**
	@brief	指定したサイズ分、ファイルを読み込む。
	@param	buffer	出力先
	@param	size	読み込まれるサイズ
*/
void Read(std::vector<uint8_t>& buffer, int32_t size)
{
	auto result = Read(size);
	buffer.resize(result);
	memcpy(buffer.data(), GetTempBuffer(), result);
}
";

            AddDLLH(dllH_Header);

            AddDLLH("class " + dllClassName + " {");
            AddDLLH("public:");

            AddDLLCPP(dllCpp_Header);

            AddLIBH(libH_Header);
            AddLIBCPP(libCpp_Header);

            PushDLLHIndent();

            // predefined
            foreach (var c in doxygen.ClassDefs)
            {
                if (!settings.ClassWhiteList.Any(_ => _ == c.Name))
                {
                    continue;
                }
                AddLIBH("class " + c.Name + ";");
            }
            AddLIBH("class AutoGeneratedWrapperAccessor;");

            AddLIBH("");

            foreach (var c in doxygen.ClassDefs)
            {
                if (!settings.ClassWhiteList.Any(_ => _ == c.Name))
                {
                    continue;
                }

                var dllFuncPrefix = c.Name + "_";


                AddLIBH("/**");
                AddLIBH("\t@brief " + c.Brief);
                AddLIBH("*/");
                AddLIBH("class " + c.Name + " {");
                PushLIBHIndent();
                AddLIBH("void* self = nullptr;");
                AddLIBH("bool isCtrlSelf = false;");

                // friend class (TODO smart)
                foreach (var c2 in doxygen.ClassDefs)
                {
                    if (!settings.ClassWhiteList.Any(_ => _ == c2.Name))
                    {
                        continue;
                    }

                    AddLIBH("friend class " + c2.Name + ";");
                }

                foreach (var c2 in settings.FriendClassList)
                {
                    AddLIBH("friend class " + c2 + ";");
                }

                AddLIBH("friend class AutoGeneratedWrapperAccessor;");

                // Default constructor
                if (!c.Methods.Any(m => string.IsNullOrEmpty(m.ReturnType.Name) && !m.Name.Contains("~") && m.IsPublic))
                {
                    AddLIBH(c.Name + "(void* self, bool isCtrlSelf);");
                    AddLIBCPP(c.Name + "::" + c.Name + "(void* self, bool isCtrlSelf) {");
                    AddLIBCPP("\tthis->self = self;");
                    AddLIBCPP("\tthis->isCtrlSelf = isCtrlSelf;");
                    AddLIBCPP("}");
                }

                bool isDestructorPrivate = c.Methods.Any(_ => _.Name.Contains("~") && !_.IsPublic);

                AddLIBH("public:");

                foreach (var m in c.Methods)
                {
                    if (m.IsStatic)
                    {
                        continue;
                    }

                    var isConstract = string.IsNullOrEmpty(m.ReturnType.Name) && !m.Name.Contains("~");
                    var isDestruct  = string.IsNullOrEmpty(m.ReturnType.Name) && m.Name.Contains("~");

                    // A method note is none
                    if (string.IsNullOrEmpty(m.Brief) && !isConstract && !isDestruct)
                    {
                        continue;
                    }

                    // A method whose note has a #Ignore is ignored.
                    if (m.Note?.Contains("#Ignore") ?? false)
                    {
                        continue;
                    }

                    // A method which has an argument whose type is shared_ptr<T> is ignored.
                    if (m.Parameters.Any(_ => _.Type.IsSharedPtr))
                    {
                        continue;
                    }

                    // A method whose return type is shared_ptr<T> is ignored.
                    if (m.ReturnType.IsSharedPtr)
                    {
                        continue;
                    }



                    // non public functions are not valid without destructor
                    if (!isDestruct && !m.IsPublic)
                    {
                        continue;
                    }

                    var methodName    = m.Name;
                    var returnType    = m.ReturnType;
                    var libParameters = m.Parameters.ToArray().ToList();
                    var dllParameters = m.Parameters.ToArray().ToList();

                    if (isConstract)
                    {
                        methodName      = "Construct";
                        returnType.Name = "void *";
                    }
                    else if (isDestruct)
                    {
                        methodName      = "Destruct";
                        returnType.Name = "void";

                        ParameterDef def = new ParameterDef();
                        def.Type.Name = "void *";
                        def.Name      = "self";
                        dllParameters.Insert(0, def);
                    }
                    else
                    {
                        ParameterDef def = new ParameterDef();
                        def.Type.Name = "void *";
                        def.Name      = "self";
                        dllParameters.Insert(0, def);
                    }

                    var dllFuncName = dllFuncPrefix + methodName;

                    // dll
                    var dllFuncArg = "(" + string.Join(",", dllParameters.Select((_, i) => GetDLLHArg(_.Type, m) + " " + _.Name).ToArray()) + ")";

                    // dll header
                    AddDLLH("virtual " + GetDLLRet(returnType, m) + " " + dllFuncName + dllFuncArg + ";");

                    // dll cpp
                    AddDLLCPP(GetDLLRet(returnType, m) + " " + dllClassName + "::" + dllFuncName + dllFuncArg + "{");

                    PushDLLCppIndent();

                    if (isConstract)
                    {
                        var argConverters = libParameters.Select((_, i) => GetDLLCppArg(_.Type, i, _.Name, m));
                        foreach (var a in argConverters)
                        {
                            AddDLLCPP(a);
                        }

                        AddDLLCPP("return " + c.Name + "(" + string.Join(",", libParameters.Select((_, i) => "arg" + i).ToArray()) + ");");
                    }
                    else if (isDestruct)
                    {
                        AddDLLCPP("auto self_ = (" + c.Name + "*)self;");

                        var f = GetDLLDestructor(new TypeDef()
                        {
                            Name = c.Name
                        }, !m.IsPublic);

                        if (f != "")
                        {
                            AddDLLCPP(f);
                        }
                    }
                    else
                    {
                        AddDLLCPP("auto self_ = (" + c.Name + "*)self;");

                        var argConverters = libParameters.Select((_, i) => GetDLLCppArg(_.Type, i, _.Name, m));
                        foreach (var a in argConverters)
                        {
                            AddDLLCPP(a);
                        }

                        if (returnType.Name == "void" && !returnType.IsPointer)
                        {
                            AddDLLCPP("self_->" + methodName + "(" + string.Join(",", libParameters.Select((_, i) => "arg" + i).ToArray()) + ");");
                        }
                        else
                        {
                            var retType = "auto";
                            if (returnType.IsRef)
                            {
                                retType = "auto&";
                            }

                            AddDLLCPP(retType + " ret = self_->" + methodName + "(" + string.Join(",", libParameters.Select((_, i) => "arg" + i).ToArray()) + ");");
                            AddDLLCPP(GetDLLCppRet(returnType, m));
                        }
                    }

                    PopDLLCppIndent();

                    AddDLLCPP("};");
                    AddDLLCPP("");

                    // lib
                    var libFuncArg = "(" + string.Join(",", libParameters.Select(_ => GetLIBHArg(_.Type, m) + " " + _.Name).ToArray()) + ")";

                    if (m.IsConst)
                    {
                        libFuncArg += " const";
                    }

                    // lib header

                    AddLIBH("/**");
                    AddLIBH("\t@brief " + m.Brief);

                    foreach (var p in m.Parameters)
                    {
                        AddLIBH("\t@param " + p.Name + " " + p.Brief);
                    }

                    if (!string.IsNullOrEmpty(m.BriefOfReturn))
                    {
                        AddLIBH("\t@return " + m.BriefOfReturn);
                    }

                    AddLIBH("*/");

                    if (isConstract)
                    {
                        AddLIBH(c.Name + libFuncArg + ";");
                    }
                    else if (isDestruct)
                    {
                        AddLIBH("virtual ~" + c.Name + libFuncArg + ";");
                    }
                    else
                    {
                        AddLIBH(GetLIBRet(returnType, m) + " " + methodName + libFuncArg + ";");
                    }
                    AddLIBH("");

                    // lib cpp
                    if (isConstract)
                    {
                        AddLIBCPP(c.Name + "::" + c.Name + libFuncArg + "{");
                        PushLIBCppIndent();
                        {
                            AddLIBCPP("auto arg0 = self;");
                            var argConverters = libParameters.Select((_, i) => GetLIBCppArg(_.Type, i + 1, _.Name, m));
                            foreach (var a in argConverters)
                            {
                                AddLIBCPP(a);
                            }

                            AddLIBCPP("self = dll->" + dllFuncName + "(" + string.Join(",", dllParameters.Select((_, i) => "arg" + i).ToArray()) + ");");
                            AddLIBCPP("isCtrlSelf = true;");
                        }
                        PopLIBCppIndent();
                        AddLIBCPP("};");
                    }
                    else if (isDestruct)
                    {
                        AddLIBCPP(c.Name + "::~" + c.Name + libFuncArg + "{");
                        PushLIBCppIndent();
                        {
                            AddLIBCPP("if (isCtrlSelf) {");
                            PushLIBCppIndent();
                            AddLIBCPP("dll->" + dllFuncName + "(" + string.Join(",", dllParameters.Select(_ => _.Name).ToArray()) + ");");
                            PopLIBCppIndent();
                            AddLIBCPP("}");
                        }
                        PopLIBCppIndent();
                        AddLIBCPP("};");
                    }
                    else
                    {
                        AddLIBCPP(GetLIBRet(returnType, m) + " " + c.Name + "::" + methodName + libFuncArg + "{");
                        PushLIBCppIndent();
                        {
                            AddLIBCPP("auto arg0 = self;");
                            var argConverters = libParameters.Select((_, i) => GetLIBCppArg(_.Type, i + 1, _.Name, m));
                            foreach (var a in argConverters)
                            {
                                AddLIBCPP(a);
                            }

                            if (returnType.Name == "void" && !returnType.IsPointer)
                            {
                                AddLIBCPP("dll->" + dllFuncName + "(" + string.Join(",", dllParameters.Select((_, i) => "arg" + i).ToArray()) + ");");
                            }
                            else
                            {
                                var retType = "auto";
                                if (returnType.IsRef)
                                {
                                    retType = "auto&";
                                }

                                AddLIBCPP(retType + " ret = dll->" + dllFuncName + "(" + string.Join(",", dllParameters.Select((_, i) => "arg" + i).ToArray()) + ");");
                                AddLIBCPP(GetLIBCppRet(returnType, m));
                            }
                        }
                        PopLIBCppIndent();
                        AddLIBCPP("};");
                    }

                    AddLIBCPP("");
                }

                if (c.Name == "StreamFile")
                {
                    AddLIBH(StreamFile_Additional);
                }

                PopLIBHIndent();
                AddLIBH("};");
                AddLIBH("");
            }


            PopDLLHIndent();

            AddDLLH("};");

            AddDLLH(dllH_Footer);
            AddDLLCPP(dllCpp_Footer);
            AddLIBH(libH_Footer);
            AddLIBCPP(libCpp_Footer);

            System.IO.File.WriteAllLines(dllDirPath + "asd.WrapperDLL.h", dll_headerText.ToArray(), System.Text.Encoding.UTF8);
            System.IO.File.WriteAllLines(dllDirPath + "asd.WrapperDLL.cpp", dll_cppText.ToArray(), System.Text.Encoding.UTF8);
            System.IO.File.WriteAllLines(libDirPath + "asd.WrapperLib.h", lib_headerText.ToArray(), System.Text.Encoding.UTF8);
            System.IO.File.WriteAllLines(libDirPath + "asd.WrapperLib.cpp", lib_cppText.ToArray(), System.Text.Encoding.UTF8);
        }