Ejemplo n.º 1
0
        public SourceCode GenerateArgumentedConstructor()
        {
            // msg argumented constructor
            var paramArgs      = new List <string>();
            var initializeArgs = new List <string>();

            foreach (var field in Fields.OfType <SimpleField>())
            {
                paramArgs.Add(string.Format("{0} _{1}", TypeUtil.ToArgumentTypeName(field.Type), field.Name));
                initializeArgs.Add(string.Format("{0}(_{0})", field.Name));
            }
            var code = new SourceCode();

            if (initializeArgs.Count == 0)
            {
                return(code);
            }

            code.Append("{0}({1})", ClassName, string.Join(", ", paramArgs));
            code.IndentRight();
            code.Append(": {0} {{}}", string.Join(", ", initializeArgs));
            code.IndentLeft();
            code.NewLine();
            return(code);
        }
Ejemplo n.º 2
0
 public override SourceCode GenerateHandler(CodeContext context)
 {
     var code = new SourceCode();
     var listAccessor = GetVarAccessor(context);
     var iteratorName = context.StartIterator();
     code.Append(CodeUtil.ForEachCode(TypeName, listAccessor, iteratorName, true));
     code.IndentRight();
     code.Append("{0}::handle(session, *{1});", CanonicalTarget, iteratorName);
     code.BracketEnd();
     context.EndIterator();
     return code;
 }
Ejemplo n.º 3
0
        public override SourceCode GenerateHandler(CodeContext context)
        {
            var code         = new SourceCode();
            var listAccessor = GetVarAccessor(context);
            var iteratorName = context.StartIterator();

            code.Append(CodeUtil.ForEachCode(TypeName, listAccessor, iteratorName, true));
            code.IndentRight();
            code.Append("{0}::handle(session, *{1});", CanonicalTarget, iteratorName);
            code.BracketEnd();
            context.EndIterator();
            return(code);
        }
Ejemplo n.º 4
0
 public override SourceCode GenerateWriter(CodeContext context)
 {
     var code = new SourceCode();
     var listAccessor = GetVarAccessor(context);
     var iteratorName = context.StartIterator();
     code.Append("(*this) << static_cast<uint32_t>({0}size());", listAccessor);
     code.Append(CodeUtil.ForEachCode(CanonicalType, listAccessor, iteratorName, true));
     code.IndentRight();
     code.Append("(*this) << (*{0});", iteratorName);
     code.BracketEnd();
     context.EndIterator();
     return code;
 }
Ejemplo n.º 5
0
 public override SourceCode GenerateField(CodeContext context)
 {
     var code = new SourceCode();
     code.Append("struct {0} {{", Name);
     code.IndentRight();
     Fields.ForEach(field => code.Append(field.GenerateField(context)));
     code.NewLine();
     code.Append(Fields.GenerateDefaultConstructor(Name));
     code.BracketEnd(";");
     code.Append("typedef std::vector<{0}> {1};", Name, TypeName);
     code.Append("{0} {1};", TypeName, VarName);
     return code;
 }
Ejemplo n.º 6
0
        public override SourceCode GenerateWriter(CodeContext context)
        {
            var code         = new SourceCode();
            var listAccessor = GetVarAccessor(context);
            var iteratorName = context.StartIterator();

            code.Append("(*this) << static_cast<uint32_t>({0}size());", listAccessor);
            code.Append(CodeUtil.ForEachCode(CanonicalType, listAccessor, iteratorName, true));
            code.IndentRight();
            code.Append("(*this) << (*{0});", iteratorName);
            code.BracketEnd();
            context.EndIterator();
            return(code);
        }
Ejemplo n.º 7
0
        public override SourceCode GenerateField(CodeContext context)
        {
            var code = new SourceCode();

            code.Append("struct {0} {{", Name);
            code.IndentRight();
            Fields.ForEach(field => code.Append(field.GenerateField(context)));
            code.NewLine();
            code.Append(Fields.GenerateDefaultConstructor(Name));
            code.BracketEnd(";");
            code.Append("typedef std::vector<{0}> {1};", Name, TypeName);
            code.Append("{0} {1};", TypeName, VarName);
            return(code);
        }
Ejemplo n.º 8
0
        public override SourceCode GenerateHandler(CodeContext context)
        {
            var code = new SourceCode();
            if (Fields.Count(field => field is RefField) == 0)
                return code;

            var listAccessor = GetVarAccessor(context);
            var iteratorName = context.StartIterator();
            code.Append(CodeUtil.ForEachCode(TypeName, listAccessor, iteratorName, true));
            code.IndentRight();
            Fields.ForEach(field => code.Append(field.GenerateHandler(context)));
            code.BracketEnd();
            context.EndIterator();
            return code;
        }
Ejemplo n.º 9
0
        public override SourceCode GenerateHandler(CodeContext context)
        {
            var code = new SourceCode();

            if (Fields.Count(field => field is RefField) == 0)
            {
                return(code);
            }

            var listAccessor = GetVarAccessor(context);
            var iteratorName = context.StartIterator();

            code.Append(CodeUtil.ForEachCode(TypeName, listAccessor, iteratorName, true));
            code.IndentRight();
            Fields.ForEach(field => code.Append(field.GenerateHandler(context)));
            code.BracketEnd();
            context.EndIterator();
            return(code);
        }
Ejemplo n.º 10
0
        public override SourceCode GenerateReader(CodeContext context)
        {
            var code = new SourceCode();
            var countVar = Name + "_count";
            code.Append("uint32_t {0};", countVar);
            code.Append("(*this) >> {0};", countVar);

            var listAccessor = GetVarAccessor(context);
            code.Append("for (uint32_t index = 0; index < {0}; ++index) {{", countVar);
            code.IndentRight();
            var eachVariable = context.StartAccessor("each");
            code.Append("{0} {1};", CanonicalTarget, eachVariable);
            code.Append("this->skip(static_cast<msg_size_t>(sizeof(msg_type_t)));");
            code.Append("(*this) >> {0};", eachVariable);
            code.Append("{0}push_back({1});", listAccessor, eachVariable);
            context.EndAccessor();
            code.BracketEnd();
            return code;
        }
Ejemplo n.º 11
0
        public override SourceCode GenerateReader(CodeContext context)
        {
            var code = new SourceCode();
            var countVar = Name + "_count";
            code.Append("uint32_t {0};", countVar);
            code.Append("(*this) >> {0};", countVar);

            code.Append("for (uint32_t index = 0; index < {0}; ++index) {{", countVar);
            code.IndentRight();

            var listAccessor = GetVarAccessor(context);
            var eachVariable = context.StartAccessor("each");
            code.Append("{0} {1};", CanonicalName, eachVariable);
            Fields.ForEach(field => code.Append(field.GenerateReader(context)));
            code.Append("{0}push_back({1});", listAccessor, eachVariable);
            code.BracketEnd();
            context.EndAccessor();
            return code;
        }
Ejemplo n.º 12
0
        public override SourceCode GenerateReader(CodeContext context)
        {
            var code     = new SourceCode();
            var countVar = Name + "_count";

            code.Append("uint32_t {0};", countVar);
            code.Append("(*this) >> {0};", countVar);

            code.Append("for (uint32_t index = 0; index < {0}; ++index) {{", countVar);
            code.IndentRight();

            var listAccessor = GetVarAccessor(context);
            var eachVariable = context.StartAccessor("each");

            code.Append("{0} {1};", CanonicalName, eachVariable);
            Fields.ForEach(field => code.Append(field.GenerateReader(context)));
            code.Append("{0}push_back({1});", listAccessor, eachVariable);
            code.BracketEnd();
            context.EndAccessor();
            return(code);
        }
Ejemplo n.º 13
0
        public static SourceCode GenerateDefaultConstructor(this IEnumerable<Field> fields, string className)
        {
            // msg default constructor
            var primitiveArgs = fields.OfType<SimpleField>().Select(
                e => string.Format("{0}({1})", e.Name, TypeUtil.ToDefaultValueInInitializer(e.Type))).ToArray();

            var code = new SourceCode();
            if (primitiveArgs.Any())
            {
                code.Append("#ifdef _DEBUG");
                code.Append("{0}()", className);
                code.IndentRight();
                code.Append(": {0} {{}}", string.Join(", ", primitiveArgs));
                code.IndentLeft();
                code.Append("#else");
            }
            code.Append("{0}() {{}}", className);
            if (primitiveArgs.Any())
                code.Append("#endif");
            return code;
        }
Ejemplo n.º 14
0
        public SourceCode GenerateHandlerBody(CodeContext context)
        {
            var code = new SourceCode();

            code.Append("inline void {0}::handle(msg_session_ref session, const type& msg)", CanonicalName);
            code.BracketStart();
            code.Append("_ASSERT(_handler != NULL);");
            code.Append("_handler(session, msg);");
            Fields.ForEach(field => code.Append(field.GenerateHandler(context)));
            code.BracketEnd();
            code.NewLine();

            code.Append("inline void {0}::handle(msg_session_ref session, msg_reader reader)", CanonicalName);
            code.BracketStart();
            var accessor = context.StartAccessor("msg");

            {
                code.Append("{0} {1};", ClassName, accessor);
                code.Append("reader >> {0};", accessor);
                code.Append("handle(session, {0});", accessor);
            }
            context.EndAccessor();
            code.BracketEnd();
            code.NewLine();

            code.Append("inline void {0}::broadcast(const type& msg)", CanonicalName);
            code.BracketStart();
            context.StartAccessor("msg");
            {
                code.Append(CodeUtil.ForEachCode("listener_list", "_listeners.", "iter", false));
                code.IndentRight();
                // not-recursive ref
                code.Append("(*iter)(msg);");
                code.BracketEnd();
            }
            context.EndAccessor();
            code.BracketEnd();
            return(code);
        }
Ejemplo n.º 15
0
        public override SourceCode GenerateReader(CodeContext context)
        {
            var code     = new SourceCode();
            var countVar = Name + "_count";

            code.Append("uint32_t {0};", countVar);
            code.Append("(*this) >> {0};", countVar);

            var listAccessor = GetVarAccessor(context);

            code.Append("for (uint32_t index = 0; index < {0}; ++index) {{", countVar);
            code.IndentRight();
            var eachVariable = context.StartAccessor("each");

            code.Append("{0} {1};", CanonicalTarget, eachVariable);
            code.Append("this->skip(static_cast<msg_size_t>(sizeof(msg_type_t)));");
            code.Append("(*this) >> {0};", eachVariable);
            code.Append("{0}push_back({1});", listAccessor, eachVariable);
            context.EndAccessor();
            code.BracketEnd();
            return(code);
        }
Ejemplo n.º 16
0
        public SourceCode GenerateModelCode()
        {
            var code = new SourceCode();

            code.BracketStart("struct {0}", TypeName);
            code.IndentRight();
            foreach (var field in Fields.Values)
            {
                code.Append(field.GenerateModelCode());
            }
            if (HasContent)
            {
                code.Append("std::string {0};", IsNameContent ? "name" : "content");
            }

            if (NodeCount > 1)
            {
                code.NewLine();
                code.Append("~{0}()", TypeName);
                code.BracketStart();
                foreach (var field in DataClassFields)
                {
                    if (field.Class.HasId)
                    {
                        code.Append("CLEAR_POINTER_MAP({0}, {1});", field.Class.CollectionTypeName, field.Class.CollectionName);
                    }
                    else
                    {
                        code.Append("CLEAR_POINTER_LIST({0}, {1});", field.Class.TypeName, field.Class.CollectionName);
                    }
                }
                code.BracketEnd();
            }
            code.BracketEnd(";");
            return(code);
        }
Ejemplo n.º 17
0
        public static SourceCode GenerateDefaultConstructor(this IEnumerable <Field> fields, string className)
        {
            // msg default constructor
            var primitiveArgs = fields.OfType <SimpleField>().Select(
                e => string.Format("{0}({1})", e.Name, TypeUtil.ToDefaultValueInInitializer(e.Type))).ToArray();

            var code = new SourceCode();

            if (primitiveArgs.Any())
            {
                code.Append("#ifdef _DEBUG");
                code.Append("{0}()", className);
                code.IndentRight();
                code.Append(": {0} {{}}", string.Join(", ", primitiveArgs));
                code.IndentLeft();
                code.Append("#else");
            }
            code.Append("{0}() {{}}", className);
            if (primitiveArgs.Any())
            {
                code.Append("#endif");
            }
            return(code);
        }
Ejemplo n.º 18
0
        public SourceCode GenerateArgumentedConstructor()
        {
            // msg argumented constructor
            var paramArgs = new List<string>();
            var initializeArgs = new List<string>();
            foreach (var field in Fields.OfType<SimpleField>())
            {
                paramArgs.Add(string.Format("{0} _{1}", TypeUtil.ToArgumentTypeName(field.Type), field.Name));
                initializeArgs.Add(string.Format("{0}(_{0})", field.Name));
            }
            var code = new SourceCode();
            if (initializeArgs.Count == 0)
                return code;

            code.Append("{0}({1})", ClassName, string.Join(", ", paramArgs));
            code.IndentRight();
            code.Append(": {0} {{}}", string.Join(", ", initializeArgs));
            code.IndentLeft();
            code.NewLine();
            return code;
        }
Ejemplo n.º 19
0
        public SourceCode GenerateModelCode()
        {
            var code = new SourceCode();
            code.BracketStart("struct {0}", TypeName);
            code.IndentRight();
            foreach (var field in Fields.Values)
                code.Append(field.GenerateModelCode());
            if (HasContent)
                code.Append("std::string {0};", IsNameContent ? "name" : "content");

            if (NodeCount > 1)
            {
                code.NewLine();
                code.Append("~{0}()", TypeName);
                code.BracketStart();
                foreach (var field in DataClassFields)
                {
                    if (field.Class.HasId) code.Append("CLEAR_POINTER_MAP({0}, {1});", field.Class.CollectionTypeName, field.Class.CollectionName);
                    else code.Append("CLEAR_POINTER_LIST({0}, {1});", field.Class.TypeName, field.Class.CollectionName);
                }
                code.BracketEnd();
            }
            code.BracketEnd(";");
            return code;
        }
Ejemplo n.º 20
0
        private void GenerateHeaders(AttributeClass attributeClass)
        {
            var code = new SourceCode();

            code.Append("#pragma once");
            code.NewLine();
            code.Append("#include \"cbes/attribute.h\"");
            code.NewLine();
            code.BracketStart("struct {0} : public attribute_t<{0}>", attributeClass.StructName);
            foreach (var attributeField in attributeClass.Fields)
            {
                code.Append("{2}{0} {1};", TypeUtil.ToDeclareTypeName(attributeField.Type), attributeField.Name, attributeField.Volatile ? "volatile " : "");
            }

            code.NewLine();
            code.Append("// default constructor");
            var constructorArgs = attributeClass.Fields.Select(
                e => string.Format("{0}({1})", e.Name, e.Default ?? TypeUtil.ToDefaultValueInInitializer(e.Type))).ToList();

            if (constructorArgs.Count > 0)
            {
                code.Append("{0}()", attributeClass.StructName);
                code.IndentRight();
                code.Append(": {0} {{}}", string.Join(", ", constructorArgs));
                code.IndentLeft();
            }
            else
            {
                code.Append("{0}() {{}}", attributeClass.StructName);
            }

            if (attributeClass.NonDefaultFields.Any())
            {
                code.NewLine();
                code.Append("// argumented constructor");
                var paramArgs      = new List <string>();
                var initializeArgs = new List <string>();
                // default가 없는 field를 대상으로만 argumented constructor를 만들어준다.
                foreach (var attributeField in attributeClass.Fields)
                {
                    if (attributeField.Default == null)
                    {
                        paramArgs.Add(string.Format("{0} _{1}", TypeUtil.ToArgumentTypeName(attributeField.Type), attributeField.Name));
                        initializeArgs.Add(string.Format("{0}(_{0})", attributeField.Name));
                    }
                    else
                    {
                        initializeArgs.Add(string.Format("{0}({1})", attributeField.Name, attributeField.Default));
                    }
                }

                if (initializeArgs.Count > 0)
                {
                    code.Append("{0}({1})", attributeClass.StructName, string.Join(", ", paramArgs));
                    code.IndentRight();
                    code.Append(": {0} {{}}", string.Join(", ", initializeArgs));
                    code.IndentLeft();
                }
            }

            code.NewLine();
            code.Append(SourceCode.Parse(@"
virtual void from_bson(bson_iterator*);
virtual void to_bson(bson*);
virtual void from_xml(TiXmlElement*);
virtual void to_xml(std::ostream&);".Trim()));

            if (attributeClass.CustomCode != null)
            {
                code.NewLine();
                code.Append(SourceCode.Parse(attributeClass.CustomCode));
            }

            code.BracketEnd(";");

            code.Append("typedef boost::shared_ptr<{0}> {1};", attributeClass.StructName, attributeClass.ReferenceName);
            code.NewLine();

            var headerPath = Path.Combine(_outputDirectory, attributeClass.HeaderFileName);

            code.WriteToFile(headerPath);
        }
Ejemplo n.º 21
0
        private void GenerateCpp()
        {
            _cppCode = new SourceCode();
            _cppCode.Append("#include \"{0}\"", Configuration.Stdafx);
            foreach (var dependancy in new[] { "singleton.h", "cbes/attribute.h" })
            {
                _cppCode.Append("#include \"{0}\"", dependancy);
            }
            _cppCode.NewLine();
            _cppCode.Append("#pragma warning (disable: 4189 4100 4505)");
            _cppCode.NewLine();

            foreach (var attributeClass in _attributes)
            {
                _cppCode.Append("#include \"{0}\"", attributeClass.HeaderFileName);
            }
            _cppCode.NewLine();

            #region factory

            _cppCode.Append("#pragma region /* factory-register */");
            _cppCode.StaticInitializerStart();
            foreach (var attributeClass in _attributes)
            {
                _cppCode.Append("sys<attribute_factory>().factory_map.insert(std::make_pair(\"{0}\", [=] () {{ return attribute_ref(new {1}); }}));", attributeClass.Name,
                                attributeClass.StructName);
            }
            _cppCode.StaticInitializerEnd();

            _cppCode.Append("#pragma endregion");
            _cppCode.NewLine();

            #endregion

            foreach (var attributeClass in _attributes)
            {
                _cppCode.Append("#pragma region /* {0} */", attributeClass.Name);

                #region from_bson

                {
                    var nonVolatiles = attributeClass.NonVolatileFields.ToArray();
                    if (nonVolatiles.Any())
                    {
                        _cppCode.Append("void {0}::from_bson(bson_iterator*)", attributeClass.StructName);
                        _cppCode.Append("{");
                        _cppCode.Append("}");
                    }
                    else
                    {
                        _cppCode.Append("void {0}::from_bson(bson_iterator* iterator)", attributeClass.StructName);
                        _cppCode.BracketStart();
                        _cppCode.BracketStart("while (bson_iterator_next(iterator))");
                        _cppCode.Append("const char* field_name = bson_iterator_key(iterator);");
                        _cppCode.Append("const char* field_value = bson_iterator_string(iterator);");
                        foreach (var attributeField in nonVolatiles)
                        {
                            _cppCode.Append("if (stricmp(\"{0}\", field_name) == 0) {0} = boost::lexical_cast<{1}>(field_value);",
                                            attributeField.Name, TypeUtil.ToDeclareTypeName(attributeField.Type));
                        }
                        _cppCode.BracketEnd();
                        _cppCode.BracketEnd();
                    }
                }

                #endregion

                #region to_bson

                {
                    _cppCode.Append("void {0}::to_bson(bson* obj)", attributeClass.StructName);
                    _cppCode.BracketStart();
                    _cppCode.Append("bson_append_start_object(obj, \"{0}\");", attributeClass.Name);
                    foreach (var attributeField in attributeClass.NonVolatileFields)
                    {
                        _cppCode.Append("bson_append_string(obj, \"{0}\", boost::lexical_cast<std::string>({0}).c_str());",
                                        attributeField.Name);
                    }
                    _cppCode.Append("bson_append_finish_object(obj);");
                    _cppCode.BracketEnd();
                }

                #endregion

                #region from_xml

                {
                    var nonVolatileFields = attributeClass.NonVolatileFields.ToArray();
                    var primitives        = nonVolatileFields.Where(e => TypeUtil.IsPrimitiveType(e.Type)).ToArray();
                    var nonPrimitives     = nonVolatileFields.Where(e => !TypeUtil.IsPrimitiveType(e.Type)).ToArray();

                    if (!primitives.Any() && !nonPrimitives.Any())
                    {
                        _cppCode.Append("void {0}::from_xml(TiXmlElement*)", attributeClass.StructName);
                        _cppCode.Append("{");
                        _cppCode.Append("}");
                    }
                    else
                    {
                        _cppCode.Append("void {0}::from_xml(TiXmlElement* node)", attributeClass.StructName);
                        _cppCode.BracketStart();
                        // primitive type은 attribute로 값을 넣어준다.
                        _cppCode.Append("const char* attr_value = nullptr;");
                        foreach (var attributeField in primitives)
                        {
                            if (attributeField.Type == TypeEnum.INT || attributeField.Type == TypeEnum.DOUBLE)
                            {
                                _cppCode.Append("node->Attribute(\"{0}\", &{0});", attributeField.Name);
                            }
                            else
                            {
                                _cppCode.Append("attr_value = node->Attribute(\"{0}\");", attributeField.Name);
                                _cppCode.Append("if (attr_value != nullptr) {0} = boost::lexical_cast<{1}>(attr_value);", attributeField.Name,
                                                TypeUtil.ToDeclareTypeName(attributeField.Type));
                            }
                        }

                        // non-primitive type은 child element로 값을 넣어준다.
                        if (nonPrimitives.Any())
                        {
                            _cppCode.BracketStart("for (TiXmlElement* each_node = node->FirstChildElement(); each_node != nullptr; each_node = each_node->NextSiblingElement())");
                            _cppCode.Append("const char* node_name = each_node->Value();");
                            foreach (var attributeField in nonPrimitives)
                            {
                                _cppCode.BracketStart("if (stricmp(\"{0}\", node_name) == 0)", attributeField.Name);
                                _cppCode.Append(
                                    attributeField.Type == TypeEnum.STRING
                                        ? "{0} = std::string(each_node->GetText() != nullptr? each_node->GetText(): \"\");"
                                        : "xml_custom_convert(each_node, &{0});", attributeField.Name);
                                _cppCode.BracketEnd();
                            }
                            _cppCode.BracketEnd();
                        }
                        _cppCode.BracketEnd();
                    }
                }

                #endregion

                #region to_xml

                {
                    _cppCode.Append("void {0}::to_xml(std::ostream& out)", attributeClass.StructName);
                    _cppCode.BracketStart();

                    var nonVolatileFields = attributeClass.NonVolatileFields.ToArray();
                    var primitives        = nonVolatileFields.Where(e => TypeUtil.IsPrimitiveType(e.Type)).ToArray();
                    var nonPrimitives     = nonVolatileFields.Where(e => !TypeUtil.IsPrimitiveType(e.Type)).ToArray();

                    if (!primitives.Any() && !nonPrimitives.Any())
                    {
                        _cppCode.Append("out << \"<{0}/>\";", attributeClass.Name);
                    }
                    else
                    {
                        _cppCode.Append("out << \"<{0}\";", attributeClass.Name);

                        if (primitives.Any())
                        {
                            _cppCode.IndentRight();
                            // primitive type은 attribute로 값을 넣어준다.
                            foreach (var attributeField in primitives)
                            {
                                _cppCode.Append(@"out << "" {0}=\"""" << {0} << ""\"""";", attributeField.Name);
                            }
                            _cppCode.IndentLeft();
                        }
                        if (!nonPrimitives.Any())
                        {
                            _cppCode.Append("out << \"/>\";");
                        }
                        else
                        {
                            _cppCode.Append("out << \">\";");
                            _cppCode.IndentRight();
                            // non-primitive type은 child element로 값을 넣어준다.
                            foreach (var attributeField in nonPrimitives)
                            {
                                _cppCode.Append(@"out << ""<{0}>"" << {0} << ""</{0}>"";", attributeField.Name);
                            }
                            _cppCode.IndentLeft();
                            _cppCode.Append("out << \"</{0}>\";", attributeClass.Name);
                        }
                    }
                    _cppCode.Append("out << std::endl;");
                    _cppCode.BracketEnd();
                }

                #endregion

                _cppCode.Append("#pragma endregion");
                _cppCode.NewLine();
            }

            var cppFileName = Path.Combine(_outputDirectory, "bind_attributes.cpp");
            _cppCode.WriteToFile(cppFileName);
        }
Ejemplo n.º 22
0
        private void GenerateCpp()
        {
            _cppCode = new SourceCode();
            _cppCode.Append("#include \"{0}\"", Configuration.Stdafx);
            foreach (var dependancy in new[] {"singleton.h", "cbes/attribute.h"})
                _cppCode.Append("#include \"{0}\"", dependancy);
            _cppCode.NewLine();
            _cppCode.Append("#pragma warning (disable: 4189 4100 4505)");
            _cppCode.NewLine();

            foreach (var attributeClass in _attributes)
                _cppCode.Append("#include \"{0}\"", attributeClass.HeaderFileName);
            _cppCode.NewLine();

            #region factory

            _cppCode.Append("#pragma region /* factory-register */");
            _cppCode.StaticInitializerStart();
            foreach (var attributeClass in _attributes)
                _cppCode.Append("sys<attribute_factory>().factory_map.insert(std::make_pair(\"{0}\", [=] () {{ return attribute_ref(new {1}); }}));", attributeClass.Name,
                                attributeClass.StructName);
            _cppCode.StaticInitializerEnd();

            _cppCode.Append("#pragma endregion");
            _cppCode.NewLine();

            #endregion

            foreach (var attributeClass in _attributes)
            {
                _cppCode.Append("#pragma region /* {0} */", attributeClass.Name);

                #region from_bson

                {
                    var nonVolatiles = attributeClass.NonVolatileFields.ToArray();
                    if (nonVolatiles.Any())
                    {
                        _cppCode.Append("void {0}::from_bson(bson_iterator*)", attributeClass.StructName);
                        _cppCode.Append("{");
                        _cppCode.Append("}");
                    }
                    else
                    {
                        _cppCode.Append("void {0}::from_bson(bson_iterator* iterator)", attributeClass.StructName);
                        _cppCode.BracketStart();
                        _cppCode.BracketStart("while (bson_iterator_next(iterator))");
                        _cppCode.Append("const char* field_name = bson_iterator_key(iterator);");
                        _cppCode.Append("const char* field_value = bson_iterator_string(iterator);");
                        foreach (var attributeField in nonVolatiles)
                        {
                            _cppCode.Append("if (stricmp(\"{0}\", field_name) == 0) {0} = boost::lexical_cast<{1}>(field_value);",
                                            attributeField.Name, TypeUtil.ToDeclareTypeName(attributeField.Type));
                        }
                        _cppCode.BracketEnd();
                        _cppCode.BracketEnd();
                    }
                }

                #endregion

                #region to_bson

                {
                    _cppCode.Append("void {0}::to_bson(bson* obj)", attributeClass.StructName);
                    _cppCode.BracketStart();
                    _cppCode.Append("bson_append_start_object(obj, \"{0}\");", attributeClass.Name);
                    foreach (var attributeField in attributeClass.NonVolatileFields)
                    {
                        _cppCode.Append("bson_append_string(obj, \"{0}\", boost::lexical_cast<std::string>({0}).c_str());",
                                        attributeField.Name);
                    }
                    _cppCode.Append("bson_append_finish_object(obj);");
                    _cppCode.BracketEnd();
                }

                #endregion

                #region from_xml

                {
                    var nonVolatileFields = attributeClass.NonVolatileFields.ToArray();
                    var primitives = nonVolatileFields.Where(e => TypeUtil.IsPrimitiveType(e.Type)).ToArray();
                    var nonPrimitives = nonVolatileFields.Where(e => !TypeUtil.IsPrimitiveType(e.Type)).ToArray();

                    if (!primitives.Any() && !nonPrimitives.Any())
                    {
                        _cppCode.Append("void {0}::from_xml(TiXmlElement*)", attributeClass.StructName);
                        _cppCode.Append("{");
                        _cppCode.Append("}");
                    }
                    else
                    {
                        _cppCode.Append("void {0}::from_xml(TiXmlElement* node)", attributeClass.StructName);
                        _cppCode.BracketStart();
                        // primitive type은 attribute로 값을 넣어준다.
                        _cppCode.Append("const char* attr_value = nullptr;");
                        foreach (var attributeField in primitives)
                        {
                            if (attributeField.Type == TypeEnum.INT || attributeField.Type == TypeEnum.DOUBLE)
                            {
                                _cppCode.Append("node->Attribute(\"{0}\", &{0});", attributeField.Name);
                            }
                            else
                            {
                                _cppCode.Append("attr_value = node->Attribute(\"{0}\");", attributeField.Name);
                                _cppCode.Append("if (attr_value != nullptr) {0} = boost::lexical_cast<{1}>(attr_value);", attributeField.Name,
                                                TypeUtil.ToDeclareTypeName(attributeField.Type));
                            }
                        }

                        // non-primitive type은 child element로 값을 넣어준다.
                        if (nonPrimitives.Any())
                        {
                            _cppCode.BracketStart("for (TiXmlElement* each_node = node->FirstChildElement(); each_node != nullptr; each_node = each_node->NextSiblingElement())");
                            _cppCode.Append("const char* node_name = each_node->Value();");
                            foreach (var attributeField in nonPrimitives)
                            {
                                _cppCode.BracketStart("if (stricmp(\"{0}\", node_name) == 0)", attributeField.Name);
                                _cppCode.Append(
                                    attributeField.Type == TypeEnum.STRING
                                        ? "{0} = std::string(each_node->GetText() != nullptr? each_node->GetText(): \"\");"
                                        : "xml_custom_convert(each_node, &{0});", attributeField.Name);
                                _cppCode.BracketEnd();
                            }
                            _cppCode.BracketEnd();
                        }
                        _cppCode.BracketEnd();
                    }
                }

                #endregion

                #region to_xml

                {
                    _cppCode.Append("void {0}::to_xml(std::ostream& out)", attributeClass.StructName);
                    _cppCode.BracketStart();

                    var nonVolatileFields = attributeClass.NonVolatileFields.ToArray();
                    var primitives = nonVolatileFields.Where(e => TypeUtil.IsPrimitiveType(e.Type)).ToArray();
                    var nonPrimitives = nonVolatileFields.Where(e => !TypeUtil.IsPrimitiveType(e.Type)).ToArray();

                    if (!primitives.Any() && !nonPrimitives.Any())
                        _cppCode.Append("out << \"<{0}/>\";", attributeClass.Name);
                    else
                    {
                        _cppCode.Append("out << \"<{0}\";", attributeClass.Name);

                        if (primitives.Any())
                        {
                            _cppCode.IndentRight();
                            // primitive type은 attribute로 값을 넣어준다.
                            foreach (var attributeField in primitives)
                                _cppCode.Append(@"out << "" {0}=\"""" << {0} << ""\"""";", attributeField.Name);
                            _cppCode.IndentLeft();
                        }
                        if (!nonPrimitives.Any())
                            _cppCode.Append("out << \"/>\";");
                        else
                        {
                            _cppCode.Append("out << \">\";");
                            _cppCode.IndentRight();
                            // non-primitive type은 child element로 값을 넣어준다.
                            foreach (var attributeField in nonPrimitives)
                                _cppCode.Append(@"out << ""<{0}>"" << {0} << ""</{0}>"";", attributeField.Name);
                            _cppCode.IndentLeft();
                            _cppCode.Append("out << \"</{0}>\";", attributeClass.Name);
                        }
                    }
                    _cppCode.Append("out << std::endl;");
                    _cppCode.BracketEnd();
                }

                #endregion

                _cppCode.Append("#pragma endregion");
                _cppCode.NewLine();
            }

            var cppFileName = Path.Combine(_outputDirectory, "bind_attributes.cpp");
            _cppCode.WriteToFile(cppFileName);
        }
Ejemplo n.º 23
0
        private void GenerateHeaders(AttributeClass attributeClass)
        {
            var code = new SourceCode();
            code.Append("#pragma once");
            code.NewLine();
            code.Append("#include \"cbes/attribute.h\"");
            code.NewLine();
            code.BracketStart("struct {0} : public attribute_t<{0}>", attributeClass.StructName);
            foreach (var attributeField in attributeClass.Fields)
            {
                code.Append("{2}{0} {1};", TypeUtil.ToDeclareTypeName(attributeField.Type), attributeField.Name, attributeField.Volatile ? "volatile " : "");
            }

            code.NewLine();
            code.Append("// default constructor");
            var constructorArgs = attributeClass.Fields.Select(
                e => string.Format("{0}({1})", e.Name, e.Default ?? TypeUtil.ToDefaultValueInInitializer(e.Type))).ToList();

            if (constructorArgs.Count > 0)
            {
                code.Append("{0}()", attributeClass.StructName);
                code.IndentRight();
                code.Append(": {0} {{}}", string.Join(", ", constructorArgs));
                code.IndentLeft();
            }
            else code.Append("{0}() {{}}", attributeClass.StructName);

            if (attributeClass.NonDefaultFields.Any())
            {
                code.NewLine();
                code.Append("// argumented constructor");
                var paramArgs = new List<string>();
                var initializeArgs = new List<string>();
                // default가 없는 field를 대상으로만 argumented constructor를 만들어준다.
                foreach (var attributeField in attributeClass.Fields)
                {
                    if (attributeField.Default == null)
                    {
                        paramArgs.Add(string.Format("{0} _{1}", TypeUtil.ToArgumentTypeName(attributeField.Type), attributeField.Name));
                        initializeArgs.Add(string.Format("{0}(_{0})", attributeField.Name));
                    }
                    else
                    {
                        initializeArgs.Add(string.Format("{0}({1})", attributeField.Name, attributeField.Default));
                    }
                }

                if (initializeArgs.Count > 0)
                {
                    code.Append("{0}({1})", attributeClass.StructName, string.Join(", ", paramArgs));
                    code.IndentRight();
                    code.Append(": {0} {{}}", string.Join(", ", initializeArgs));
                    code.IndentLeft();
                }
            }

            code.NewLine();
            code.Append(SourceCode.Parse(@"
            virtual void from_bson(bson_iterator*);
            virtual void to_bson(bson*);
            virtual void from_xml(TiXmlElement*);
            virtual void to_xml(std::ostream&);".Trim()));

            if (attributeClass.CustomCode != null)
            {
                code.NewLine();
                code.Append(SourceCode.Parse(attributeClass.CustomCode));
            }

            code.BracketEnd(";");

            code.Append("typedef boost::shared_ptr<{0}> {1};", attributeClass.StructName, attributeClass.ReferenceName);
            code.NewLine();

            var headerPath = Path.Combine(_outputDirectory, attributeClass.HeaderFileName);
            code.WriteToFile(headerPath);
        }
Ejemplo n.º 24
0
        public SourceCode GenerateHandlerBody(CodeContext context)
        {
            var code = new SourceCode();
            code.Append("inline void {0}::handle(msg_session_ref session, const type& msg)", CanonicalName);
            code.BracketStart();
            code.Append("_ASSERT(_handler != NULL);");
            code.Append("_handler(session, msg);");
            Fields.ForEach(field => code.Append(field.GenerateHandler(context)));
            code.BracketEnd();
            code.NewLine();

            code.Append("inline void {0}::handle(msg_session_ref session, msg_reader reader)", CanonicalName);
            code.BracketStart();
            var accessor = context.StartAccessor("msg");
            {
                code.Append("{0} {1};", ClassName, accessor);
                code.Append("reader >> {0};", accessor);
                code.Append("handle(session, {0});", accessor);
            }
            context.EndAccessor();
            code.BracketEnd();
            code.NewLine();

            code.Append("inline void {0}::broadcast(const type& msg)", CanonicalName);
            code.BracketStart();
            context.StartAccessor("msg");
            {
                code.Append(CodeUtil.ForEachCode("listener_list", "_listeners.", "iter", false));
                code.IndentRight();
                // not-recursive ref
                code.Append("(*iter)(msg);");
                code.BracketEnd();
            }
            context.EndAccessor();
            code.BracketEnd();
            return code;
        }