Exemple #1
0
    def generate(self):
        package = self.cppPackage.package
        guard = re.sub(
            "_+", "_",
            re.sub("[^a-zA-Z0-9]+", "_",
                   os.path.basename(self.filePath))).strip("_").upper()

        includes = [
            cpp_path_norm(package.cpp.filenames["opMessageDeclaration"]),
            "modules/protobuf/src/protobuf_input.h",
            "modules/protobuf/src/protobuf_output.h",
            "modules/protobuf/src/protobuf_message.h",
            "modules/protobuf/src/protobuf_data.h",
            "modules/protobuf/src/generated/g_protobuf_descriptors.h",
        ]

        text = fileHeader()
        text += "\n" + render(
            """
            // Generated from %(proto_file)s

            #include "core/pch.h"
            
            #ifndef %(guard)s
            #define %(guard)s

            %(defines)s

            %(includes)s

            """, {
                "proto_file": self.cppPackage.makeRelativePath(
                    package.filename),
                "guard": guard,
                "defines": self.renderDefines(self.cppPackage.defines),
                "includes": self.renderIncludes(includes),
            }) + "\n"

        set_gen = CppOpMessageSetGenerator(package,
                                           self.cppPackage.messages,
                                           options=self.cppPackage)
        text += set_gen.getImplementation()

        text += render(
            """

            %(endifs)s

            #endif // %(guard)s
            """, {
                "endifs": self.renderEndifs(self.cppPackage.defines),
                "guard": guard,
            }) + "\n"

        return text
Exemple #2
0
    def renderServiceDeclaration(self, service, requests, events):
        enums = self.enums()

        text = "\n" + self.indent(
            render("""
            	virtual OP_STATUS             DoReceive( OpScopeClient *client, const OpScopeTPMessage &msg );
            	virtual int                   GetCommandCount() const;
            	virtual CommandRange          GetCommands() const;

            	virtual const OpProtobufMessage *GetMessage(unsigned int message_id) const;
            	virtual unsigned                 GetMessageCount() const;
            	virtual MessageIDRange           GetMessageIDs() const;
            	virtual MessageRange             GetMessages() const;
            """)) + "\n\n"

        if enums:
            text += self.indent(
                render("""
                // Introspection of enums
                virtual EnumIDRange GetEnumIDs() const;
                virtual unsigned  GetEnumCount() const;
                virtual BOOL      HasEnum(unsigned enum_id) const;
                virtual OP_STATUS GetEnum(unsigned enum_id, const uni_char *&name, unsigned &value_count) const;
                virtual OP_STATUS GetEnumValue(unsigned enum_id, unsigned idx, const uni_char *&value_name, unsigned &value_number) const;
                """)) + "\n\n"

        text += self.indent(
            render("""
            virtual const char *GetVersionString() const;
            virtual int         GetMajorVersion() const;
            virtual int         GetMinorVersion() const;
            virtual const char *GetPatchVersion() const;
            """)) + "\n\n"

        if requests:
            text += "	// Request/Response functions\n"
            for command in requests:
                text += "	%(function)s\n" % {
                    "function": request_functionSignature(command)
                }
            text += "\n"

        if events:
            text += "	// Event functions\n"
            for command in events:
                text += "	%(function)s\n" % {
                    "function": event_functionSignature(command)
                }
            text += "\n"

        text += "\n	Descriptors *GetDescriptors() const;\n"
        return text
Exemple #3
0
    def generate(self):
        package = self.cppPackage.package
        guard = re.sub(
            "_+", "_",
            re.sub("[^a-zA-Z0-9]+", "_",
                   os.path.basename(self.filePath))).strip("_").upper()

        includes = [
            cpp_path_norm(package.cpp.filenames["messageDeclaration"]),
            "modules/hardcore/component/OpTypedMessage.h",
        ]

        text = fileHeader()
        text += "\n" + render(
            """
            // Generated from %(proto_file)s
            
            #ifndef %(guard)s
            #define %(guard)s

            %(defines)s

            %(includes)s
            
            """, {
                "proto_file": self.cppPackage.makeRelativePath(
                    package.filename),
                "guard": guard,
                "defines": self.renderDefines(self.cppPackage.defines),
                "includes": self.renderIncludes(includes),
            }) + "\n"

        set_gen = CppOpMessageSetGenerator(package,
                                           self.cppPackage.messages,
                                           options=self.cppPackage)
        text += set_gen.getInterface()

        text += render(
            """

            %(endifs)s

            #endif // %(guard)s
            """, {
                "endifs": self.renderEndifs(self.cppPackage.defines),
                "guard": guard,
            }) + "\n"

        return text
Exemple #4
0
    def generate(self):
        text = fileHeader()
        text += (
            "\n"
            + render(
                """
            #include "core/pch.h"

            %(defines)s

            #include "%(interfaceInclude)s"

            """,
                {
                    "defines": self.renderDefines(self.defines),
                    "interfaceInclude": cpp_path_norm(self.includes["interfaceDeclaration"]),
                    "serviceStr": strQuote(self.service.name),
                },
            )
            + "\n"
        )

        className = self.service.iparent.cpp.cppMessageSet().name
        set_gen = CppMessageSetGenerator(
            self.service.iparent, serviceMessages2(self.service), className, self.operaRoot
        )
        text += set_gen.renderDescriptorImplementation()
        text += set_gen.getImplementation()

        gen = CppServiceGenerator(self.service)
        text += gen.getInterfaceImplementation()

        text += "\n// Service implementation: BEGIN\n"
        text += gen.getServiceImplementation(generate_instance=self.cppService.generateInstance)
        text += "\n// Service implementation: END\n\n"

        text += (
            render(
                """

            %(endifs)s
            """,
                {"endifs": self.renderEndifs(self.defines)},
            )
            + "\n"
        )

        return text
Exemple #5
0
    def renderInterface(self):
        # all_messages are sorted topologically
        all_messages = [msg for msg in self.messages if msg != defaultMessage]
        # sorted_messages are sorted alphabetically
        sorted_messages = sorted(all_messages, key=lambda i: i.name)
        message_count = len(sorted_messages)
        # generators are sorted topologically to ensure class references compiles
        message_set = self.package.cpp.cppOpMessageSet()
        text = ""

        if self.package.cpp.useOpMessageSet:
            text += "\n" + render("""
                class %(class)s
                {
                public:
                """, {
                    "class": message_set.name,
                }) + "\n\n"

        text += "\n	// BEGIN: Message classes\n"

        for msg in sorted_messages:
            text += self.indent(self.renderMessage(msg)) + "\n\n"

        text += "\n	// END: Message classes\n"

        if self.package.cpp.useOpMessageSet:
            text += "\n};\n\n"

        return text
Exemple #6
0
 def code():
     text = ""
     for message in messages:
         message_defines = getPackage(
             message).cpp.defines() + message.cpp.defines()
         if message_defines:
             text += self.renderDefines(message_defines) + "\n"
         text += self.indent(
             render(
                 """
             case %(class)s::Type:
                 // %(file)s: %(messagePath)s
                 return %(class)s::Deserialize(src, dst, delay, data);
             """, {
                     "opMessageID":
                     message.cpp.opMessageID,
                     "messagePath":
                     ".".join(message.path()),
                     "file":
                     os.path.normpath(
                         getPackage(message).filename).replace(
                             "\\", "/"),
                     "class":
                     message.cpp.opMessage().symbol(),
                 })) + "\n\n"
         if message_defines:
             text += self.renderEndifs(message_defines) + "\n"
     return text
Exemple #7
0
    def renderInterface(self):
        # all_messages are sorted topologically
        all_messages = [msg for msg in self.messages if msg != defaultMessage]
        # sorted_messages are sorted alphabetically
        sorted_messages = sorted(all_messages, key=lambda i: i.name)
        message_count = len(sorted_messages)
        # generators are sorted topologically to ensure class references compiles
        message_set = self.package.cpp.cppOpMessageSet()
        text = ""

        if self.package.cpp.useOpMessageSet:
            text += "\n" + render(
                """
                class %(class)s
                {
                public:
                """, {
                    "class": message_set.name,
                }) + "\n\n"

        text += "\n	// BEGIN: Message classes\n"

        for msg in sorted_messages:
            text += self.indent(self.renderMessage(msg)) + "\n\n"

        text += "\n	// END: Message classes\n"

        if self.package.cpp.useOpMessageSet:
            text += "\n};\n\n"

        return text
Exemple #8
0
    def generate(self):
        package = self.cppPackage.package
        guard = re.sub("_+", "_", re.sub("[^a-zA-Z0-9]+", "_", os.path.basename(self.filePath))).strip("_").upper()

        includes = [cpp_path_norm(package.cpp.filenames["opMessageDeclaration"]),
                    "modules/protobuf/src/protobuf_input.h",
                    "modules/protobuf/src/protobuf_output.h",
                    "modules/protobuf/src/protobuf_message.h",
                    "modules/protobuf/src/protobuf_data.h",
                    "modules/protobuf/src/generated/g_protobuf_descriptors.h",
                    ]

        text = fileHeader()
        text += "\n" + render("""
            // Generated from %(proto_file)s

            #include "core/pch.h"
            
            #ifndef %(guard)s
            #define %(guard)s

            %(defines)s

            %(includes)s

            """, {
                "proto_file": self.cppPackage.makeRelativePath(package.filename),
                "guard": guard,
                "defines": self.renderDefines(self.cppPackage.defines),
                "includes": self.renderIncludes(includes),
            }) + "\n"

        set_gen = CppOpMessageSetGenerator(package, self.cppPackage.messages, options=self.cppPackage)
        text += set_gen.getImplementation()

        text += render("""

            %(endifs)s

            #endif // %(guard)s
            """, {
                "endifs": self.renderEndifs(self.cppPackage.defines),
                "guard": guard,
            }) + "\n"

        return text
Exemple #9
0
    def renderVerify(self, messages):
        text = "\n" + render(
            """
            /*static*/ BOOL
            %(class)s::VerifyType(int type)
            {
            \tswitch(type)
            \t{
            """, {
                "class": "OpTypedMessageBase",
            }) + "\n"
        for message in messages:
            message_defines = getPackage(
                message).cpp.defines() + message.cpp.defines()
            if message_defines:
                text += self.renderDefines(message_defines) + "\n"
            text += self.indent(
                render(
                    """
                case %(class)s::Type:
                // %(file)s: %(messagePath)s
                """, {
                        "opMessageID":
                        message.cpp.opMessageID,
                        "messagePath":
                        ".".join(message.path()),
                        "file":
                        os.path.normpath(getPackage(message).filename).replace(
                            "\\", "/"),
                        "class":
                        message.cpp.opMessage().symbol(),
                    }), 2) + "\n\n"
            if message_defines:
                text += self.renderEndifs(message_defines) + "\n"
        text += "\n\t\t\t" + render(
            """
            \t\t\treturn TRUE;

            \t\tdefault:
            \t\t\treturn FALSE;
            \t}
            }
            """, {
                "class": "OpTypedMessageBase",
            }) + "\n"
        return text
Exemple #10
0
 def renderVerify(self, enums):
     text = "\n" + render("""
         /**
          * Check if the type value @a type can be mapped to a type in an OpTypedMessage sub-class.
          * @param type Integer value corresponding to type.
          * @return @c TRUE if the value is valid, @c FALSE otherwise.
          */
         static BOOL VerifyType(int type);
         """) + "\n"
     return text
Exemple #11
0
 def renderVerify(self, enums):
     text = "\n" + render("""
         /**
          * Check if the type value @a type can be mapped to a type in an OpTypedMessage sub-class.
          * @param type Integer value corresponding to type.
          * @return @c TRUE if the value is valid, @c FALSE otherwise.
          */
         static BOOL VerifyType(int type);
         """) + "\n"
     return text
Exemple #12
0
    def generate(self):
        text = fileHeader()
        text += "\n" + render(
            """
            #include "core/pch.h"

            %(defines)s

            #include "%(interfaceInclude)s"

            """, {
                "defines":
                self.renderDefines(self.defines),
                "interfaceInclude":
                cpp_path_norm(self.includes["interfaceDeclaration"]),
                "serviceStr":
                strQuote(self.service.name),
            }) + "\n"

        className = self.service.iparent.cpp.cppMessageSet().name
        set_gen = CppMessageSetGenerator(self.service.iparent,
                                         serviceMessages2(self.service),
                                         className, self.operaRoot)
        text += set_gen.renderDescriptorImplementation()
        text += set_gen.getImplementation()

        gen = CppServiceGenerator(self.service)
        text += gen.getInterfaceImplementation()

        text += "\n// Service implementation: BEGIN\n"
        text += gen.getServiceImplementation(
            generate_instance=self.cppService.generateInstance)
        text += "\n// Service implementation: END\n\n"

        text += render("""

            %(endifs)s
            """, {
            "endifs": self.renderEndifs(self.defines),
        }) + "\n"

        return text
Exemple #13
0
    def renderDeserialize(self, messages):
        def code():
            text = ""
            for message in messages:
                message_defines = getPackage(
                    message).cpp.defines() + message.cpp.defines()
                if message_defines:
                    text += self.renderDefines(message_defines) + "\n"
                text += self.indent(
                    render(
                        """
                    case %(class)s::Type:
                        // %(file)s: %(messagePath)s
                        return %(class)s::Deserialize(src, dst, delay, data);
                    """, {
                            "opMessageID":
                            message.cpp.opMessageID,
                            "messagePath":
                            ".".join(message.path()),
                            "file":
                            os.path.normpath(
                                getPackage(message).filename).replace(
                                    "\\", "/"),
                            "class":
                            message.cpp.opMessage().symbol(),
                        })) + "\n\n"
                if message_defines:
                    text += self.renderEndifs(message_defines) + "\n"
            return text

        text = "\n" + render(
            """
            /*static*/ OpTypedMessage*
            OpTypedMessageBase::DeserializeData(
                int type,
                const OpMessageAddress& src,
                const OpMessageAddress& dst,
                double delay,
                const OpData& data)
            {
            \t// Decode the serialized data by matching @a type against the Type in one of the sub-classes of OpTypedMessage
            \tswitch(type)
            \t{
            %(code)s
            
            \t\tdefault:
            \t\t\tOP_ASSERT(!"Unknown message type, cannot decode");
            \t\t\treturn NULL;
            \t}
            }
            """, {
                "code": self.indent(code()),
            }) + "\n"
        return text
    def generate(self):
        text = ""

        text += fileHeader()
        text += "\n" + render("""
#include "core/pch.h"

#ifdef SCOPE_SUPPORT

#include "modules/scope/src/generated/g_scope_manager.h"

""") + "\n"

        gen = CppManagerGenerator(self.services)
        text += gen.getImplementation()

        text += render("""
#endif // SCOPE_SUPPORT
""") + "\n"

        return text
Exemple #15
0
    def generate(self):
        text = ""

        text += fileHeader()
        text += "\n" + render("""
#include "core/pch.h"

#ifdef SCOPE_SUPPORT

#include "modules/scope/src/generated/g_scope_manager.h"

""") + "\n"

        gen = CppManagerGenerator(self.services)
        text += gen.getImplementation()

        text += render("""
#endif // SCOPE_SUPPORT
""") + "\n"

        return text
Exemple #16
0
    def generate(self):
        package = self.cppPackage.package
        guard = re.sub("_+", "_", re.sub("[^a-zA-Z0-9]+", "_", os.path.basename(self.filePath))).strip("_").upper()

        includes = [cpp_path_norm(package.cpp.filenames["messageDeclaration"]),
                    "modules/hardcore/component/OpTypedMessage.h",
                    ]

        text = fileHeader()
        text += "\n" + render("""
            // Generated from %(proto_file)s
            
            #ifndef %(guard)s
            #define %(guard)s

            %(defines)s

            %(includes)s
            
            """, {
                "proto_file": self.cppPackage.makeRelativePath(package.filename),
                "guard": guard,
                "defines": self.renderDefines(self.cppPackage.defines),
                "includes": self.renderIncludes(includes),
            }) + "\n"

        set_gen = CppOpMessageSetGenerator(package, self.cppPackage.messages, options=self.cppPackage)
        text += set_gen.getInterface()

        text += render("""

            %(endifs)s

            #endif // %(guard)s
            """, {
                "endifs": self.renderEndifs(self.cppPackage.defines),
                "guard": guard,
            }) + "\n"

        return text
Exemple #17
0
    def generate(self):
        includes = [
            "modules/hardcore/src/generated/OpTypedMessageBase.h",
        ]
        includes_set = set(includes)
        for message in self.messages:
            package = getPackage(message)
            for include in package.cpp.opMessageIncludes():
                if include not in includes_set:
                    includes_set.add(include)
                    includes.append(include)

        text = fileHeader()
        text += "\n" + render(
            """
            // Generated from proto files in the system

            #include "core/pch.h"
            
            %(defines)s

            %(includes)s

            """, {
                "defines": self.renderDefines(self.defines),
                "includes": self.renderIncludes(includes),
            }) + "\n"

        text += self.renderVerify(self.messages) + "\n"

        text += self.renderDeserialize(self.messages) + "\n"

        text += render("""

            %(endifs)s
            """, {
            "endifs": self.renderEndifs(self.defines),
        }) + "\n"

        return text
Exemple #18
0
    def generate(self):
        includes = ["modules/hardcore/src/generated/OpTypedMessageBase.h",
                    ]
        includes_set = set(includes)
        for message in self.messages:
            package = getPackage(message)
            for include in package.cpp.opMessageIncludes():
                if include not in includes_set:
                    includes_set.add(include)
                    includes.append(include)

        text = fileHeader()
        text += "\n" + render("""
            // Generated from proto files in the system

            #include "core/pch.h"
            
            %(defines)s

            %(includes)s

            """, {
                "defines": self.renderDefines(self.defines),
                "includes": self.renderIncludes(includes),
            }) + "\n"

        text += self.renderVerify(self.messages) + "\n"

        text += self.renderDeserialize(self.messages) + "\n"

        text += render("""

            %(endifs)s
            """, {
                "endifs": self.renderEndifs(self.defines),
            }) + "\n"

        return text
Exemple #19
0
    def generate(self):
        text = ""

        text += fileHeader()
        text += "\n" + render("""
#ifndef OP_SCOPE_MANAGER_G_H
#define OP_SCOPE_MANAGER_G_H

#ifdef SCOPE_SUPPORT

""") + "\n"

        gen = CppManagerGenerator(self.services)
        text += gen.getDeclaration()

        text += render("""

#endif // SCOPE_SUPPORT

#endif // OP_SCOPE_MANAGER_G_H
""") + "\n"

        return text
    def generate(self):
        text = ""

        text += fileHeader()
        text += "\n" + render("""
#ifndef OP_SCOPE_MANAGER_G_H
#define OP_SCOPE_MANAGER_G_H

#ifdef SCOPE_SUPPORT

""") + "\n"

        gen = CppManagerGenerator(self.services)
        text += gen.getDeclaration()

        text += render("""

#endif // SCOPE_SUPPORT

#endif // OP_SCOPE_MANAGER_G_H
""") + "\n"

        return text
Exemple #21
0
    def renderVerify(self, messages):
        text = "\n" + render("""
            /*static*/ BOOL
            %(class)s::VerifyType(int type)
            {
            \tswitch(type)
            \t{
            """, {
                "class": "OpTypedMessageBase",
            }) + "\n"
        for message in messages:
            message_defines = getPackage(message).cpp.defines() + message.cpp.defines()
            if message_defines:
                text += self.renderDefines(message_defines) + "\n"
            text += self.indent(render("""
                case %(class)s::Type:
                // %(file)s: %(messagePath)s
                """, {
                    "opMessageID": message.cpp.opMessageID,
                    "messagePath": ".".join(message.path()),
                    "file": os.path.normpath(getPackage(message).filename).replace("\\", "/"),
                    "class": message.cpp.opMessage().symbol(),
                }), 2) + "\n\n"
            if message_defines:
                text += self.renderEndifs(message_defines) + "\n"
        text += "\n\t\t\t" + render("""
            \t\t\treturn TRUE;

            \t\tdefault:
            \t\t\treturn FALSE;
            \t}
            }
            """, {
                "class": "OpTypedMessageBase",
            }) + "\n"
        return text
Exemple #22
0
    def renderDeserialize(self, messages):
        def code():
            text = ""
            for message in messages:
                message_defines = getPackage(message).cpp.defines() + message.cpp.defines()
                if message_defines:
                    text += self.renderDefines(message_defines) + "\n"
                text += self.indent(render("""
                    case %(class)s::Type:
                        // %(file)s: %(messagePath)s
                        return %(class)s::Deserialize(src, dst, delay, data);
                    """, {
                        "opMessageID": message.cpp.opMessageID,
                        "messagePath": ".".join(message.path()),
                        "file": os.path.normpath(getPackage(message).filename).replace("\\", "/"),
                        "class": message.cpp.opMessage().symbol(),
                    })) + "\n\n"
                if message_defines:
                    text += self.renderEndifs(message_defines) + "\n"
            return text

        text = "\n" + render("""
            /*static*/ OpTypedMessage*
            OpTypedMessageBase::DeserializeData(
                int type,
                const OpMessageAddress& src,
                const OpMessageAddress& dst,
                double delay,
                const OpData& data)
            {
            \t// Decode the serialized data by matching @a type against the Type in one of the sub-classes of OpTypedMessage
            \tswitch(type)
            \t{
            %(code)s
            
            \t\tdefault:
            \t\t\tOP_ASSERT(!"Unknown message type, cannot decode");
            \t\t\treturn NULL;
            \t}
            }
            """, {
                "code": self.indent(code()),
            }) + "\n"
        return text
Exemple #23
0
 def code():
     text = ""
     for message in messages:
         message_defines = getPackage(message).cpp.defines() + message.cpp.defines()
         if message_defines:
             text += self.renderDefines(message_defines) + "\n"
         text += self.indent(render("""
             case %(class)s::Type:
                 // %(file)s: %(messagePath)s
                 return %(class)s::Deserialize(src, dst, delay, data);
             """, {
                 "opMessageID": message.cpp.opMessageID,
                 "messagePath": ".".join(message.path()),
                 "file": os.path.normpath(getPackage(message).filename).replace("\\", "/"),
                 "class": message.cpp.opMessage().symbol(),
             })) + "\n\n"
         if message_defines:
             text += self.renderEndifs(message_defines) + "\n"
     return text
Exemple #24
0
    def renderInterfaceImplementation(self, service, includes, commands):
        messages = [
            msg for msg in self.sortedMessages() if msg != defaultMessage
        ]
        all_messages = [
            msg for msg in self.sortedMessages(with_inline=True)
            if msg != defaultMessage
        ]
        enums = self.enums()

        text = "\n"
        for include in includes:
            text += "#include %(include)s\n" % {"include": strQuote(include)}

        text += "\n" + render(
            """
            // BEGIN: %(class)s_SI::Descriptors

            %(class)s_SI::Descriptors::Descriptors()
            {
            """, {
                "class": service.options["cpp_class"].value,
            }) + "\n"

        text += render(
            """
            }

            %(class)s_SI::Descriptors::~Descriptors()
            {
            """, {
                "class": service.options["cpp_class"].value,
            }) + "\n"

        text += render(
            """
            }

            OP_STATUS
            %(class)s_SI::Descriptors::Construct()
            {
                RETURN_IF_ERROR(%(descriptorClass)s::Construct());
            """, {
                "class": service.options["cpp_class"].value,
                "descriptorClass": self.package.cpp.descriptorClass().symbol(),
            }) + "\n"

        text += "	// Initialize commands\n"

        for idx, command in enumerate(commands):
            text += self.indent(
                render(
                    """
                command_list[%(idx)s] = OpScopeCommand(%(command)s,
                					%(commandEnum)s
                """, {
                        "idx": idx,
                        "command": strQuote(command.name),
                        "commandEnum": enumName(command),
                    }))
            if isinstance(command, proto.Event):
                text += ",\n						OpScopeCommand::Type_Event"
            else:
                text += ",\n						OpScopeCommand::Type_Call"

            if isinstance(command, proto.Event):
                text += render(
                    """
                    ,
                    						_gen_void_MsgID,
                    						%(requestIdentifier)s
                    """, {
                        "requestIdentifier": self.renderMessageID(
                            command.message),
                    })
            else:
                text += render(
                    """
                    ,
                    						%(requestIdentifier)s,
                    						%(responseIdentifier)s
                    """, {
                        "requestIdentifier":
                        self.renderMessageID(command.message),
                        "responseIdentifier":
                        self.renderMessageID(command.response),
                    })
            text += "\n						);\n"
        text += "	" + render(
            """
            	return OpStatus::OK;
            }

            // END: %(class)s_SI::Descriptors
            """, {
                "class": service.options["cpp_class"].value,
            })

        return text
Exemple #25
0
    def renderServiceImplementation(self, service, requests, events,
                                    generate_instance):
        class_name = service.options["cpp_class"].value + "_SI"

        class_name_base = service.iparent.cpp.cppMessageSet().symbol()
        if class_name_base.find("_MessageSet"):
            cpp_descriptor_class_name = class_name_base.replace(
                "_MessageSet", "_Descriptors")
        else:
            cpp_descriptor_class_name = class_name_base + "_Descriptors"

        text = "\n"

        text += "\n" + render(
            """
            // Service implementation

            %(class)s::%(class)s(const uni_char* id, OpScopeServiceManager *manager, ControlType control)
            		: OpScopeService(id == NULL ? UNI_L(%(protocol_name_quoted)s) : id, manager, control)
            {
            }

            /*virtual*/
            %(class)s::~%(class)s()
            {
            }
            """, {
                "class":
                class_name,
                "protocol_name_quoted":
                strQuote(utils.join_dashed(utils.split_camelcase(
                    service.name))),
                "serviceVarName":
                self.varName(service.name),
            }) + "\n"
        if not generate_instance:
            return text

        text += "\n" + render(
            """
            /*virtual*/
            int
            %(class)s::GetCommandCount() const
            {
            	return Command_Count;
            }

            /*virtual*/
            OpScopeService::CommandRange
            %(class)s::GetCommands() const
            {
            	Descriptors *descriptors = g_scope_manager->GetDescriptorSet().%(serviceVarName)s;
            	OP_ASSERT(descriptors);
            	return CommandRange(descriptors ? descriptors->command_list : NULL, Command_Count);
            }

            /*virtual*/
            OP_STATUS
            %(class)s::DoReceive( OpScopeClient *client, const OpScopeTPMessage &msg )
            {
            	// Check for invalid request data
            	if (msg.Status() != OpScopeTPMessage::OK) // All calls must have status OK
            		return SetCommandError(OpScopeTPMessage::BadRequest, GetInvalidStatusFieldText());
            	if (msg.ServiceName().Compare(GetName()) != 0) // Make sure the service name matches the one in the message
            		return SetCommandError(OpScopeTPMessage::InternalError, GetIncorrectServiceText());
            """, {
                "class":
                class_name,
                "protocol_name_quoted":
                strQuote(utils.join_dashed(utils.split_camelcase(
                    service.name))),
                "serviceVarName":
                self.varName(service.name),
            }) + "\n\n"

        if requests:
            text += self.indent(
                render(
                    """
                if (msg.CommandID() == %(requestID)s) // %(requestName)s
                {
                """, {
                        "requestID": enumName(requests[0]),
                        "requestName": requests[0].name,
                    })) + self.renderRequestDecode(requests[0]) + "	}\n"

            for command in requests[1:]:
                text += self.indent(
                    render(
                        """
                    else if (msg.CommandID() == %(requestID)s) // %(requestName)s
                    {
                    """, {
                            "requestID": enumName(command),
                            "requestName": command.name,
                        })) + self.renderRequestDecode(command) + "	}\n"

            text += self.indent(
                render("""
                else
                {
                	SetCommandError(OpScopeTPMessage::CommandNotFound, GetCommandNotFoundText());
                	return OpStatus::ERR;
                }
                """)) + "\n"

        text += "	return OpStatus::OK;\n}\n\n"

        messages = [msg for msg in service.messages() if msg != defaultMessage]
        enums = self.enums()

        text += render(
            """
            /*virtual*/
            const OpProtobufMessage *
            %(class)s::GetMessage(unsigned message_id) const
            {
            	Descriptors *descriptors = GetDescriptors();
            	if (!descriptors)
            		return NULL;
            	return descriptors->Get(message_id);
            }

            %(class)s::Descriptors *
            %(class)s::GetDescriptors() const
            {
            	Descriptors *d = g_scope_manager->GetDescriptorSet().%(serviceVarName)s;
            	OP_ASSERT(d);
            	return d;
            }

            /*virtual*/
            unsigned
            %(class)s::GetMessageCount() const
            {
            	return %(descriptorClass)s::_gen_Message_Count;
            }

            /*virtual*/
            OpScopeService::MessageIDRange
            %(class)s::GetMessageIDs() const
            {
            	unsigned start = %(descriptorClass)s::_gen_Message_Count > 0 ? 1 : 0;
            	return MessageIDRange(start, start + %(descriptorClass)s::_gen_Message_Count);
            }

            /*virtual*/
            OpScopeService::MessageRange
            %(class)s::GetMessages() const
            {
            	unsigned start = %(descriptorClass)s::_gen_Message_Count > 0 ? 1 : 0;
            	return MessageRange(this, start, start + %(descriptorClass)s::_gen_Message_Count);
            }
            """, {
                "class": class_name,
                "serviceVarName": self.varName(service.name),
                "descriptorClass": cpp_descriptor_class_name,
            }) + "\n\n"

        text += render(
            """
            /* virtual */
            const char *
            %(class)s::GetVersionString() const
            {
            	return "%(version)s";
            }

            /* virtual */
            int
            %(class)s::GetMajorVersion() const
            {
            	return %(versionMajor)s;
            }

            /* virtual */
            int
            %(class)s::GetMinorVersion() const
            {
            	return %(versionMinor)s;
            }

            /* virtual */
            const char *
            %(class)s::GetPatchVersion() const
            {
            	return "%(versionPatch)s";
            }
            """, {
                "class": class_name,
                "version": service.options["version"].value,
                "versionMajor": service.version[0],
                "versionMinor": service.version[1],
                "versionPatch": service.version[2],
            }) + "\n"

        if events:
            for event in events:
                params = []
                if event.message.isNonEmpty():
                    params.append("const %s &msg" %
                                  message_className(event.message))
                if requiresAsyncResponse(event):
                    params.append("unsigned int tag")

                text += "\n" + render(
                    """
                    OP_STATUS
                    %(class)s::%(eventMethod)s(%(eventParams)s) // %(eventName)s
                    {
                    """, {
                        "class": class_name,
                        "eventMethod": event_functionName(event),
                        "eventParams": ", ".join(params),
                        "eventName": event.name,
                    }) + "\n"

                if event.message.isNonEmpty():
                    text += "	OpProtobufInstanceProxy proxy(%(messageClass)s::GetMessageDescriptor(GetDescriptors()), const_cast<%(messageClass)s *>(&msg));\n" % {
                        "messageClass": message_className(event.message),
                    }
                else:
                    text += "	OpProtobufInstanceProxy proxy(OpScopeDefaultMessage::GetMessageDescriptor(), &g_scope_manager->default_message_instance);\n"

                text += ("	if (proxy.GetProtoMessage() == NULL)\n" +
                         "		return OpStatus::ERR_NO_MEMORY;\n")

                if requiresAsyncResponse(event):
                    text += "	return SendAsyncResponse(tag, proxy, %(eventEnum)s);\n" % {
                        "eventEnum": enumName(event)
                    }
                else:
                    text += "	return SendEvent(proxy, %(eventEnum)s);\n" % {
                        "eventEnum": enumName(event)
                    }

                text += "}\n\n"

        if enums:
            text += render(
                """
                // Enum introspection: BEGIN

                /*virtual*/
                OpScopeService::EnumIDRange
                %(class)s::GetEnumIDs() const
                {
                	Descriptors *descriptors = GetDescriptors();
                	return EnumIDRange(descriptors ? descriptors->enum_id_list : NULL, %(descriptorClass)s::_gen_Enum_Count);
                }

                /*virtual*/
                unsigned
                %(class)s::GetEnumCount() const
                {
                	return %(descriptorClass)s::_gen_Enum_Count;
                }

                /*virtual*/
                BOOL
                %(class)s::HasEnum(unsigned enum_id) const
                {
                	switch (enum_id)
                	{
                """, {
                    "class": class_name,
                    "descriptorClass": cpp_descriptor_class_name,
                }) + "\n"
            for enum in enums:
                text += "		case %(descriptorClass)s::_gen_EnumID_%(enumPath)s:\n" % {
                    "enumPath": "_".join(enum.path()),
                    "descriptorClass": cpp_descriptor_class_name,
                }

            text += ("			return TRUE;\n" "	}\n" "	return FALSE;\n" "}\n" "\n")
            text += render(
                """
                /*virtual*/
                OP_STATUS
                %(class)s::GetEnum(unsigned enum_id, const uni_char *&name, unsigned &value_count) const
                {
                	switch (enum_id)
                	{
                """, {
                    "class": class_name,
                }) + "\n"

            for enum in enums:
                text += self.indent(
                    render(
                        """
                    // %(messageClassPath)s
                    case %(descriptorClass)s::_gen_EnumID_%(enumPath)s:
                    	name = UNI_L(%(enum)s);
                    	value_count = %(descriptorClass)s::_gen_EnumValueCount_%(enumPath)s;
                    	return OpStatus::OK;
                    """, {
                            "messageClassPath": messageClassPath(enum)[1],
                            "enumPath": "_".join(enum.path()),
                            "enum": strQuote(enum.name),
                            "descriptorClass": cpp_descriptor_class_name,
                        }), 2) + "\n"

            text += ("	}\n"
                     "	return OpStatus::ERR_NO_SUCH_RESOURCE;\n"
                     "}\n"
                     "\n")
            text += render(
                """
                /*virtual*/
                OP_STATUS
                %(class)s::GetEnumValue(unsigned enum_id, unsigned idx, const uni_char *&value_name, unsigned &value_number) const
                {
                	switch (enum_id)
                	{
                """, {
                    "class": class_name,
                }) + "\n"

            for enum in enums:
                text += self.indent(
                    render(
                        """
                    // %(messageClassPath)s
                    case %(descriptorClass)s::_gen_EnumID_%(enumPath)s:
                    {
                    """, {
                            "messageClassPath": messageClassPath(enum)[1],
                            "enumPath": "_".join(enum.path()),
                            "descriptorClass": cpp_descriptor_class_name,
                        }), 2) + "\n"
                if enum.values:
                    text += self.indent(
                        render(
                            """
                        if (idx > %(descriptorClass)s::_gen_EnumValueCount_%(enumPath)s)
                        	return OpStatus::ERR_OUT_OF_RANGE;
                        // Values for %(messageClassPath)s
                        const unsigned enum_numbers[] = {
                        	  %(enumValue)s
                        """, {
                                "enumPath": "_".join(enum.path()),
                                "messageClassPath": messageClassPath(enum)[1],
                                "enumValue": enum.values[0].value,
                                "descriptorClass": cpp_descriptor_class_name,
                            }), 3) + "\n"
                    for value in enum.values[1:]:
                        text += "				, %s\n" % value.value

                    text += self.indent(
                        render("""
                        }; // ARRAY OK 2010-04-14 jborsodi
                        const unsigned name_offsets[] = {
                        	  0
                        """), 3) + "\n"
                    for idx in range(1, len(enum.values)):
                        text += "				, %(offset)s\n" % {
                            "offset":
                            sum([
                                len(value.name) + 1
                                for value in enum.values[:idx]
                            ])
                        }

                    text += self.indent(
                        render(
                            """
                        }; // ARRAY OK 2010-04-14 jborsodi
                        const uni_char *names = UNI_L( %(enumStrings)s );
                        OP_ASSERT(idx < sizeof(name_offsets));
                        OP_ASSERT(idx < sizeof(enum_numbers));
                        value_name = names + name_offsets[idx];
                        value_number = enum_numbers[idx];
                        return OpStatus::OK;
                        """, {
                                "enumStrings":
                                strQuote("".join([
                                    value.name + "\0"
                                    for value in enum.values[:-1]
                                ] + [enum.values[-1].name]))
                            }), 3) + "\n"
                else:
                    text += "			return OpStatus::ERR; // No values so return error\n"

                text += "		}\n\n"

            text += ("	}\n"
                     "	return OpStatus::ERR_NO_SUCH_RESOURCE;\n"
                     "}\n"
                     "// Enum introspection: END\n")
        return text
Exemple #26
0
    def renderImplementation(self, services):
        text = ""

        fields = {}
        for service in services:
            fields[service] = {
                "name": service.name,
                "memberName": self.memberName(service.name),
                "varName": self.varName(service.name),
                "class": service.options["cpp_class"].value,
            }
            if "cpp_feature" in service.options:
                fields[service]["feature"] = service.options["cpp_feature"].value
            if "cpp_construct" in service.options:
                fields[service]["construct"] = service.options["cpp_construct"].value

        text += "\n\n" + render("""

            #include "modules/scope/src/generated/g_scope_manager.h"

            // Services we need to instantiate

            """) + "\n\n"

        for service in services:
            if "cpp_instance" not in service.options or service.options["cpp_instance"].value == "true":
                if "cpp_feature" in service.options:
                    text += "#ifdef %(feature)s\n" % {"feature": service.options["cpp_feature"].value}

                text += """# include "%(file)s"\n""" % {"file": service.cpp.files()["serviceDeclaration"]}

                if "cpp_feature" in service.options:
                    text += "#endif // %(feature)s\n" % {"feature": service.options["cpp_feature"].value}

        text += "\n" + render("""

            /* OpScopeServiceFactory */

            OpScopeServiceFactory::OpScopeServiceFactory()
            	: descriptors(NULL)
            """) + "\n"

        for service in services:
            if "cpp_instance" not in service.options or service.options["cpp_instance"].value == "true":
                if "cpp_feature" in service.options:
                    text += "#ifdef %(feature)s\n" % fields[service]

                text += "	, %(memberName)s(NULL)\n" % fields[service]
                if "cpp_feature" in service.options:
                    text += "#endif // %(feature)s\n" % fields[service]

        text += render("""
            {
            }

            OP_STATUS
            OpScopeServiceFactory::CreateServices(OpScopeServiceManager *manager)
            {
            	RETURN_IF_ERROR(InitializeShared());

            """) + "\n\n"

        for service in services:
            if "cpp_instance" not in service.options or service.options["cpp_instance"].value == "true":
                if "cpp_feature" in service.options:
                    text += "#ifdef %(feature)s\n" % fields[service]

                text += self.indent(render("""
                    {
                    	%(memberName)s = OP_NEW(%(class)s, ());
                    	RETURN_OOM_IF_NULL(%(memberName)s);
                    	%(memberName)s->SetManager(manager);
                    """, fields[service]) + "\n")
                if "cpp_construct" in service.options:
                    text += "		OP_STATUS status = %(memberName)s->Construct(%(construct)s);\n" % fields[service]
                else:
                    text += "		OP_STATUS status = %(memberName)s->Construct();\n" % fields[service]

                if "cpp_is_essential" in service.options and service.options["cpp_is_essential"].value == "true":
                    text += self.indent(render("""
                        // Ensure that service '%(name)s' is initialized, cannot work without it
                        if (OpStatus::IsError(status))
                        	return status;
                        manager->RegisterService(%(memberName)s);
                        """, fields[service]), 2)
                else:
                    text += self.indent(render("""
                        if (OpStatus::IsMemoryError(status))
                        	return status;
                        // Only register the service if there are no errors while constructing it
                        if (OpStatus::IsSuccess(status))
                        	manager->RegisterService(%(memberName)s);
                        """, fields[service]), 2)

                text += "\n	}\n"
                if "cpp_feature" in service.options:
                    text += "#endif // %(feature)s\n" % fields[service]


        text += "\n" + self.indent(render("""
            	// Add meta-services

            	for (MetaService *meta_service = meta_services.First(); meta_service; meta_service = meta_service->Suc())
            	{
            		meta_service->service = OP_NEW_L(OpScopeMetaService, (meta_service->name.CStr()));
            		RETURN_OOM_IF_NULL(meta_service->service);
            		meta_service->service->SetManager(manager);
            		OP_STATUS status = meta_service->service->Construct();
            		if (OpStatus::IsMemoryError(status))
            			return status;
            		// Only register the service if there are no errors while constructing it
            		if (OpStatus::IsSuccess(status))
            			manager->RegisterService(meta_service->service);
            	}

            	// All services has been initialized, now continue with the intra-service setup
            	OpScopeServiceManager::ServiceRange range = manager->GetServices();
            	for (; !range.IsEmpty(); range.PopFront())
            	{
            		OP_STATUS status = range.Front()->OnPostInitialization();
            		if (OpStatus::IsMemoryError(status))
            			return status;

            		// Any errors in post initialization makes the service unavailable
            		if (OpStatus::IsError(status))
            		{
            			manager->UnregisterService(range.Front());
            """) + "\n")

        for service in services:
            if "cpp_instance" not in service.options or service.options["cpp_instance"].value == "true":
                if "cpp_is_essential" in service.options and service.options["cpp_is_essential"].value == "true":

                    if "cpp_feature" in service.options:
                        text += "#ifdef %(feature)s\n" % fields[service]

                    text += self.indent(render("""
                        			// Ensure that post initialization of service '%(name)s' succeeds, cannot work without it
                        			if (range.Front() == %(memberName)s)
                        				return status;
                        """, fields[service]) + "\n", 3)

                    if "cpp_feature" in service.options:
                        text += "#endif // %(feature)s\n" % fields[service]

        text += "		" + render("""
            		}
            	}

            	return OpStatus::OK;
            }

            void
            OpScopeServiceFactory::DeleteServices()
            {
            	// Once we have starting shutting down services, we don't want any new
            	// events from Core. This protects against shutdown crashes.

            """) + "\n\n"

        for service in services:
            if "cpp_instance" not in service.options or service.options["cpp_instance"].value == "true":
                if "cpp_feature" in service.options:
                    text += "#ifdef %(feature)s\n" % fields[service]

                text += self.indent(render("""
                        %(class)s *tmp_%(memberName)s = %(memberName)s;
                        %(memberName)s = NULL;
                    """, fields[service]) + "\n")
                if "cpp_feature" in service.options:
                    text += "#endif // %(feature)s\n" % fields[service]

        text += "\n	// Now destroy all services.\n\n"

        for service in services:
            if "cpp_instance" not in service.options or service.options["cpp_instance"].value == "true":
                if "cpp_feature" in service.options:
                    text += "#ifdef %(feature)s\n" % fields[service]

                text += "	OP_DELETE(tmp_%(memberName)s);\n" % fields[service]
                if "cpp_feature" in service.options:
                    text += "#endif // %(feature)s\n" % fields[service]

        text += "\n	" + render("""

            	// Delete meta-services

            	meta_services.Clear();

            	// Cleanup any shared member variables

            	CleanupShared();
            }

            /* OpScopeDescriptorSet */

            OpScopeDescriptorSet::OpScopeDescriptorSet()
            	: dummy(0)
            """) + "\n"

        for service in services:
            if "cpp_feature" in service.options:
                text += "#ifdef %(feature)s\n" % fields[service]

            text += "	, %(varName)s(NULL)\n" % fields[service]
            if "cpp_feature" in service.options:
                text += "#endif // %(feature)s\n" % fields[service]

        text += render("""
            {
            	(void)dummy;
            }

            OpScopeDescriptorSet::~OpScopeDescriptorSet()
            {
            """) + "\n"

        for service in services:
            if "cpp_feature" in service.options:
                text += "#ifdef %(feature)s\n" % fields[service]

            text += "	OP_DELETE(%(varName)s);\n" % fields[service]
            if "cpp_feature" in service.options:
                text += "#endif // %(feature)s\n" % fields[service]

        text += render("""
            }

            OP_STATUS
            OpScopeDescriptorSet::Construct()
            {
            """) + "\n"

        for service in services:
            if "cpp_feature" in service.options:
                text += "#ifdef %(feature)s\n" % fields[service]

            text += self.indent(render("""
                %(varName)s = OP_NEW(%(class)s_SI::Descriptors, ());
                RETURN_OOM_IF_NULL(%(varName)s);
                RETURN_IF_ERROR(%(varName)s->Construct());
            """, fields[service]) + "\n")
            if "cpp_feature" in service.options:
                text += "#endif // %(feature)s\n" % fields[service]

        text += "	return OpStatus::OK;\n}\n"

        return text
Exemple #27
0
    def renderRequestDecode(self, command):
        text = "\n		OP_STATUS status = OpStatus::OK;\n"

        if requiresAsyncResponse(command):
            text += self.indent(
                render("""
                unsigned async_tag;
                status = InitAsyncCommand(msg, async_tag); // Needed for async requests, the response will use this info when request is done
                if (OpStatus::IsError(status))
                {
                	RETURN_IF_ERROR(SetCommandError(OpScopeTPHeader::InternalError, GetInitAsyncCommandFailedText()));
                	return status;
                }
                """), 2) + "\n"

        if command.message.isNonEmpty():
            text += "		%(requestMessage)s in;\n" % {
                "requestMessage": message_className(command.message)
            }

        if hasattr(command, 'response') and command.response.isNonEmpty():
            text += "		%(responseMessage)s out;\n" % {
                "responseMessage": message_className(command.response)
            }
        text += "\n"

        if command.message.isNonEmpty():
            text += self.indent(
                render(
                    """
                OpProtobufInstanceProxy in_proxy(%(requestMessage)s::GetMessageDescriptor(GetDescriptors()), &in);
                if (in_proxy.GetProtoMessage() == NULL)
                	return OpStatus::ERR_NO_MEMORY;
                status = ParseMessage(client, msg, in_proxy);
                if (OpStatus::IsError(status))
                {
                	if (GetCommandError().GetStatus() == OpScopeTPHeader::OK) // Set a generic error if none was set by a parser
                		RETURN_IF_ERROR(SetCommandError(OpScopeTPHeader::InternalError, GetParseCommandMessageFailedText()));
                	return status;
                }
                """, {
                        "requestMessage": message_className(command.message),
                    }), 2) + "\n\n"

        text += self.indent(
            render("""
            status = %(commandCall)s;
            if (OpStatus::IsError(status))
            {
            	if (GetCommandError().GetStatus() == OpScopeTPHeader::OK) // Set a generic error if none was set by command
            """) % {
                "commandCall": request_functionCall(command),
            }, 2) + "\n"

        if requiresAsyncResponse(command):
            text += self.indent(
                render("""
                {
                	OP_STATUS tmp_status = SetCommandError(OpScopeTPHeader::InternalError, GetCommandExecutionFailedText());
                	OpStatus::Ignore(tmp_status);
                }
                // Remove the async command since the command failed to send an async response
                CleanupAsyncCommand(async_tag);
            """), 3) + "\n"
        else:
            text += "			RETURN_IF_ERROR(SetCommandError(OpScopeTPHeader::InternalError, GetCommandExecutionFailedText()));\n"

        text += ("			return status;\n" + "		}\n")

        if hasattr(command, 'response') and command.response.isNonEmpty():
            text += "\n" + self.indent(
                render(
                    """
                OpProtobufInstanceProxy out_proxy(%(responseMessage)s::GetMessageDescriptor(GetDescriptors()), &out);
                if (out_proxy.GetProtoMessage() == NULL)
                	return OpStatus::ERR_NO_MEMORY;
                RETURN_IF_ERROR(SendResponse(client, msg, out_proxy));
            """, {
                        "responseMessage": message_className(command.response),
                    }), 2) + "\n"
        elif not requiresAsyncResponse(command):
            text += "\n" + self.indent(
                render(
                    """
                // The request does not define a response message so we send the default response which is an empty message
                OpProtobufInstanceProxy out_proxy(OpScopeDefaultMessage::GetMessageDescriptor(), &g_scope_manager->default_message_instance);
                if (out_proxy.GetProtoMessage() == NULL)
                	return OpStatus::ERR_NO_MEMORY;
                status = SendResponse(client, msg, out_proxy);
                if (OpStatus::IsError(status))
                {
                	if (!IsResponseSent() && GetCommandError().GetStatus() == OpScopeTPHeader::OK) // Set a generic error if response sending failed or no error was set by response code
                		RETURN_IF_ERROR(SetCommandError(OpScopeTPHeader::InternalError, GetCommandResponseFailedText()));
                	return status;
                }
            """, {}), 2) + "\n"
        return text
Exemple #28
0
    def generate(self):
        enums = self.enums
        guard = re.sub("_+", "_", re.sub("[^a-zA-Z0-9]+", "_", os.path.basename(self.filePath))).strip("_").upper()

        text = fileHeader()
        text += "\n" + render("""
            // Generated from proto files in the system

            #ifndef %(guard)s
            #define %(guard)s

            %(defines)s

            class OpTypedMessage;
            struct OpMessageAddress;
            class OpData;

            class OpTypedMessageBase
            {
            public:
            """, {
                "defines": self.renderDefines(self.defines),
                "guard": guard,
            }) + "\n"

        text += self.indent(self.renderVerify(enums)) + "\n"

        text += self.indent(render("""
            /**
             * Deserializes the message data in @p data based on the @p type.
             * It will call the Class::Deserialize() method on the class that
             * belongs to the type.
             *
             * @param type The type of message data to decode. This determines
             *        the class of the returned instance.
             * @param src Source address of the message. This will be placed in
             *        the returned object.
             * @param dst Destination address of the message. This will be
             *        placed in the returned object.
             * @param delay Number of milliseconds until this message should
             *        be processed. This will be recorded in the returned object.
             * @param data The data-stream from which to de-serialize the
             *        message object.
             * @return The deserialized message object or @c NULL on failure.
             */
            static OpTypedMessage*
            DeserializeData(
                int type,
                const OpMessageAddress& src,
                const OpMessageAddress& dst,
                double delay,
                const OpData& data);
            """))
        text += render("""
            };

            %(endifs)s

            #endif // %(guard)s
            """, {
                "endifs": self.renderEndifs(self.defines),
                "guard": guard,
            }) + "\n"

        return text
Exemple #29
0
    def renderMessageImplementation(self, message):
        klass = message.cpp.opMessage()
        protoKlass = message.cpp.klass()

        message_gen = CppMessageGenerator(
            message,
            self.package.cpp.cppMessageSet().symbol())
        message_gen.initMembers()
        message_gen.cpp_class_path = klass.symbol()

        members = ""
        for member in message_gen.redirect_members:
            if not member.is_inline:
                members += message_gen.renderFunctionImplementation(
                    member) + "\n\n"

        text = render(
            """
            %(classPath)s::~%(class)s()
            {
            }

            /* static */ %(classPath)s*
            %(classPath)s::Cast(const OpTypedMessage* msg)
            {
            	OP_ASSERT(msg && msg->GetType() == Type);
                return static_cast<%(classPath)s*>(const_cast<OpTypedMessage*>(msg));
            }

            /* static */ %(classPath)s*
            %(classPath)s::Deserialize(
            		const OpMessageAddress& src,
            		const OpMessageAddress& dst,
            		double delay,
            		const OpData& data)
            {
            	OpProtobufInputStream stream;
            	RETURN_VALUE_IF_ERROR(stream.Construct(data), NULL);
            	%(classPathRelative)s *msg = %(classPathRelative)s::Create(src, dst, delay);
            	if (!msg)
            		return NULL;
            	OpProtobufInstanceProxy instance(%(protoClassPath)s::GetMessageDescriptor(PROTOBUF_DESCRIPTOR(%(descriptorID)s)), &msg->protobuf_data);
            	if (OpStatus::IsError(stream.Read(instance)))
            	{
            		OP_DELETE(msg);
            		return NULL;
            	}
            	return msg;
            }

            OP_STATUS
            %(classPath)s::Serialize(OpData& data) const
            {
            	OpProtobufOpDataOutputRange range(data);
            	OpProtobufOutputStream stream(&range);
            	%(protoClassPath)s *proto = const_cast<%(protoClassPath)s *>(&protobuf_data);
            	void *proto_ptr = proto;
            	OpProtobufInstanceProxy instance(%(protoClassPath)s::GetMessageDescriptor(PROTOBUF_DESCRIPTOR(%(descriptorID)s)), proto_ptr);
            	return stream.Write(instance);
            }

            const char *
            %(classPath)s::GetTypeString() const
            {
            	const OpProtobufMessage *d = %(protoClassPath)s::GetMessageDescriptor(PROTOBUF_DESCRIPTOR(%(descriptorID)s));
            	return d ? d->GetName() : NULL;
            }
            """, {
                "classPath": klass.symbol(),
                "classPathRelative": klass.symbol(relative=klass),
                "class": klass.name,
                "protoClassPath": protoKlass.symbol(),
                "globalModule": "g_%s" % self.options.module,
                "descriptorID": self.package.cpp.descriptorIdentifier(),
            })

        text += members

        return text
Exemple #30
0
    def renderServiceInterface(self, service, commands, generate_instance):
        text = "\n" + render(
            """
            class %(class)s_SI
            	: public OpScopeService
            	, public %(class)s_MessageSet
            {
            public:
            	%(class)s_SI(const uni_char* id = NULL, OpScopeServiceManager *manager = NULL, ControlType control = CONTROL_MANUAL);
            	virtual ~%(class)s_SI();

            	enum CommandEnum
            	{
            """,
            {
                "class": service.options["cpp_class"].
                value,  # TODO: Store fully generated class name on service object
            }) + "\n"

        for command in commands[:1]:
            text += "		  %(enumName)s = %(enumValue)s\n" % {
                "enumName": command.options["cpp_enum_name"].value,
                "enumValue": command.id,
            }

        for command in commands[1:]:
            text += "		, %(enumName)s = %(enumValue)s\n" % {
                "enumName": command.options["cpp_enum_name"].value,
                "enumValue": command.id,
            }

        text += "\n		, Command_Count = %(commandCount)s // Number of commands in this service\n" % {
            "commandCount": len(commands),
        }

        text += self.indent(render("""
            };
            """))

        text += "\n" + self.indent(
            render(
                """
            // This class contains the descriptors or all commands of this service
            class Descriptors
                : public %(descriptorClass)s
            {
            public:
            \tDescriptors();
            \t~Descriptors();

            \tOP_STATUS Construct();
                """, {
                    "class": service.options["cpp_class"].value,
                    "descriptorClass":
                    self.package.cpp.descriptorClass().symbol(),
                })) + "\n\n"

        text += "\n"

        text += ("		// List of commands\n" +
                 "		OpScopeCommand command_list[Command_Count];\n" + "	};\n\n")

        if generate_instance:
            text += "\n// Service API implementation: BEGIN\n\n"
            text += self.renderServiceDeclaration(self.service, self.requests,
                                                  self.events) + "\n\n"
            text += "\n// Service API implementation: END\n"

        text += "\n};\n\n"

        text += "\n"
        return text
    def renderImplementation(self, services):
        text = ""

        fields = {}
        for service in services:
            fields[service] = {
                "name": service.name,
                "memberName": self.memberName(service.name),
                "varName": self.varName(service.name),
                "class": service.options["cpp_class"].value,
            }
            if "cpp_feature" in service.options:
                fields[service]["feature"] = service.options[
                    "cpp_feature"].value
            if "cpp_construct" in service.options:
                fields[service]["construct"] = service.options[
                    "cpp_construct"].value

        text += "\n\n" + render("""

            #include "modules/scope/src/generated/g_scope_manager.h"

            // Services we need to instantiate

            """) + "\n\n"

        for service in services:
            if "cpp_instance" not in service.options or service.options[
                    "cpp_instance"].value == "true":
                if "cpp_feature" in service.options:
                    text += "#ifdef %(feature)s\n" % {
                        "feature": service.options["cpp_feature"].value
                    }

                text += """# include "%(file)s"\n""" % {
                    "file": service.cpp.files()["serviceDeclaration"]
                }

                if "cpp_feature" in service.options:
                    text += "#endif // %(feature)s\n" % {
                        "feature": service.options["cpp_feature"].value
                    }

        text += "\n" + render("""

            /* OpScopeServiceFactory */

            OpScopeServiceFactory::OpScopeServiceFactory()
            	: descriptors(NULL)
            """) + "\n"

        for service in services:
            if "cpp_instance" not in service.options or service.options[
                    "cpp_instance"].value == "true":
                if "cpp_feature" in service.options:
                    text += "#ifdef %(feature)s\n" % fields[service]

                text += "	, %(memberName)s(NULL)\n" % fields[service]
                if "cpp_feature" in service.options:
                    text += "#endif // %(feature)s\n" % fields[service]

        text += render("""
            {
            }

            OP_STATUS
            OpScopeServiceFactory::CreateServices(OpScopeServiceManager *manager)
            {
            	RETURN_IF_ERROR(InitializeShared());

            """) + "\n\n"

        for service in services:
            if "cpp_instance" not in service.options or service.options[
                    "cpp_instance"].value == "true":
                if "cpp_feature" in service.options:
                    text += "#ifdef %(feature)s\n" % fields[service]

                text += self.indent(
                    render(
                        """
                    {
                    	%(memberName)s = OP_NEW(%(class)s, ());
                    	RETURN_OOM_IF_NULL(%(memberName)s);
                    	%(memberName)s->SetManager(manager);
                    """, fields[service]) + "\n")
                if "cpp_construct" in service.options:
                    text += "		OP_STATUS status = %(memberName)s->Construct(%(construct)s);\n" % fields[
                        service]
                else:
                    text += "		OP_STATUS status = %(memberName)s->Construct();\n" % fields[
                        service]

                if "cpp_is_essential" in service.options and service.options[
                        "cpp_is_essential"].value == "true":
                    text += self.indent(
                        render(
                            """
                        // Ensure that service '%(name)s' is initialized, cannot work without it
                        if (OpStatus::IsError(status))
                        	return status;
                        manager->RegisterService(%(memberName)s);
                        """, fields[service]), 2)
                else:
                    text += self.indent(
                        render(
                            """
                        if (OpStatus::IsMemoryError(status))
                        	return status;
                        // Only register the service if there are no errors while constructing it
                        if (OpStatus::IsSuccess(status))
                        	manager->RegisterService(%(memberName)s);
                        """, fields[service]), 2)

                text += "\n	}\n"
                if "cpp_feature" in service.options:
                    text += "#endif // %(feature)s\n" % fields[service]

        text += "\n" + self.indent(
            render("""
            	// Add meta-services

            	for (MetaService *meta_service = meta_services.First(); meta_service; meta_service = meta_service->Suc())
            	{
            		meta_service->service = OP_NEW_L(OpScopeMetaService, (meta_service->name.CStr()));
            		RETURN_OOM_IF_NULL(meta_service->service);
            		meta_service->service->SetManager(manager);
            		OP_STATUS status = meta_service->service->Construct();
            		if (OpStatus::IsMemoryError(status))
            			return status;
            		// Only register the service if there are no errors while constructing it
            		if (OpStatus::IsSuccess(status))
            			manager->RegisterService(meta_service->service);
            	}

            	// All services has been initialized, now continue with the intra-service setup
            	OpScopeServiceManager::ServiceRange range = manager->GetServices();
            	for (; !range.IsEmpty(); range.PopFront())
            	{
            		OP_STATUS status = range.Front()->OnPostInitialization();
            		if (OpStatus::IsMemoryError(status))
            			return status;

            		// Any errors in post initialization makes the service unavailable
            		if (OpStatus::IsError(status))
            		{
            			manager->UnregisterService(range.Front());
            """) + "\n")

        for service in services:
            if "cpp_instance" not in service.options or service.options[
                    "cpp_instance"].value == "true":
                if "cpp_is_essential" in service.options and service.options[
                        "cpp_is_essential"].value == "true":

                    if "cpp_feature" in service.options:
                        text += "#ifdef %(feature)s\n" % fields[service]

                    text += self.indent(
                        render(
                            """
                        			// Ensure that post initialization of service '%(name)s' succeeds, cannot work without it
                        			if (range.Front() == %(memberName)s)
                        				return status;
                        """, fields[service]) + "\n", 3)

                    if "cpp_feature" in service.options:
                        text += "#endif // %(feature)s\n" % fields[service]

        text += "		" + render("""
            		}
            	}

            	return OpStatus::OK;
            }

            void
            OpScopeServiceFactory::DeleteServices()
            {
            	// Once we have starting shutting down services, we don't want any new
            	// events from Core. This protects against shutdown crashes.

            """) + "\n\n"

        for service in services:
            if "cpp_instance" not in service.options or service.options[
                    "cpp_instance"].value == "true":
                if "cpp_feature" in service.options:
                    text += "#ifdef %(feature)s\n" % fields[service]

                text += self.indent(
                    render(
                        """
                        %(class)s *tmp_%(memberName)s = %(memberName)s;
                        %(memberName)s = NULL;
                    """, fields[service]) + "\n")
                if "cpp_feature" in service.options:
                    text += "#endif // %(feature)s\n" % fields[service]

        text += "\n	// Now destroy all services.\n\n"

        for service in services:
            if "cpp_instance" not in service.options or service.options[
                    "cpp_instance"].value == "true":
                if "cpp_feature" in service.options:
                    text += "#ifdef %(feature)s\n" % fields[service]

                text += "	OP_DELETE(tmp_%(memberName)s);\n" % fields[service]
                if "cpp_feature" in service.options:
                    text += "#endif // %(feature)s\n" % fields[service]

        text += "\n	" + render("""

            	// Delete meta-services

            	meta_services.Clear();

            	// Cleanup any shared member variables

            	CleanupShared();
            }

            /* OpScopeDescriptorSet */

            OpScopeDescriptorSet::OpScopeDescriptorSet()
            	: dummy(0)
            """) + "\n"

        for service in services:
            if "cpp_feature" in service.options:
                text += "#ifdef %(feature)s\n" % fields[service]

            text += "	, %(varName)s(NULL)\n" % fields[service]
            if "cpp_feature" in service.options:
                text += "#endif // %(feature)s\n" % fields[service]

        text += render("""
            {
            	(void)dummy;
            }

            OpScopeDescriptorSet::~OpScopeDescriptorSet()
            {
            """) + "\n"

        for service in services:
            if "cpp_feature" in service.options:
                text += "#ifdef %(feature)s\n" % fields[service]

            text += "	OP_DELETE(%(varName)s);\n" % fields[service]
            if "cpp_feature" in service.options:
                text += "#endif // %(feature)s\n" % fields[service]

        text += render("""
            }

            OP_STATUS
            OpScopeDescriptorSet::Construct()
            {
            """) + "\n"

        for service in services:
            if "cpp_feature" in service.options:
                text += "#ifdef %(feature)s\n" % fields[service]

            text += self.indent(
                render(
                    """
                %(varName)s = OP_NEW(%(class)s_SI::Descriptors, ());
                RETURN_OOM_IF_NULL(%(varName)s);
                RETURN_IF_ERROR(%(varName)s->Construct());
            """, fields[service]) + "\n")
            if "cpp_feature" in service.options:
                text += "#endif // %(feature)s\n" % fields[service]

        text += "	return OpStatus::OK;\n}\n"

        return text
    def renderDeclaration(self, services):
        text = ""

        text += "\n" + render("""

            // Includes

            #include "modules/scope/src/scope_service.h"

            // Includes for shared variables

            """) + "\n\n"

        for include in self.manager_options.includes:
            text += """#include "%s"\n""" % include

        text += "\n" + render("""

            // Forward declarations

            """) + "\n\n"

        for service in services:
            if "cpp_instance" not in service.options or service.options[
                    "cpp_instance"].value == "true":
                if "cpp_feature" in service.options:
                    text += "#ifdef %(feature)s\n" % {
                        "feature": service.options["cpp_feature"].value
                    }

                text += "class %(class)s;\n" % {
                    "class": service.options["cpp_class"].value
                }

                if "cpp_feature" in service.options:
                    text += "#endif // %(feature)s\n" % {
                        "feature": service.options["cpp_feature"].value
                    }

        text += "\n" + render("""

            // Interface definitions

            """) + "\n\n"

        for service in services:
            if "cpp_feature" in service.options:
                text += "#ifdef %(feature)s\n" % {
                    "feature": service.options["cpp_feature"].value
                }

            prefix = "g_scope_"
            basename = utils.join_underscore(
                utils.split_camelcase(service.name))
            if "cpp_file" in service.options:
                basename = service.options["cpp_file"].value
                prefix = "g_"
            text += """# include "%(cpp_gen_base)s/%(file)s_interface.h"\n""" % {
                "file": prefix + basename,
                "cpp_gen_base": service.options["cpp_gen_base"].value,
            }

            if "cpp_feature" in service.options:
                text += "#endif // %(feature)s\n" % {
                    "feature": service.options["cpp_feature"].value
                }

        text += "\n" + render("""

class OpScopeDescriptorSet;
class OpScopeManager;
class OpScopeServiceManager;

/**
 * This is a generated class which defines all services which are use in scope.
 * It provides methods for registering meta-services as well as creating all
 * service objects.
 * In addition it keeps an instance of the OpScopeDescriptorSet class, this is
 * used to provide descriptor objects for messages in each service.
 *
 * This class is meant to be sub-classed into a real scope manager. The sub-class
 * must call RegisterMetaService() to register meta-services, and then call
 * CreateServices() and CreateServiceDescriptors() at a convenient time to
 * initialize the class properly.
 *
 * @note This class is generated.
 */
class OpScopeServiceFactory
{
public:
	/**
	 * Initializes the generated manager with all service pointers set to NULL.
	 */
	OpScopeServiceFactory();
	/**
	 * Deletes all active services and the descriptor set.
	 */
	virtual ~OpScopeServiceFactory();

	/**
	 * Get a reference to the descriptor set. Can only be used
	 * after a successful call to CreateServiceDescriptors.
	 */
	OpScopeDescriptorSet &GetDescriptorSet();

	/**
	 * Add a new meta-service named @a name. Meta-services are services
	 * which have no functionality, no version and cannot be introspected.
	 *
	 * The actual service will be created when CreateServices() is called
	 * by a sub-class. Adding a meta-service after that point will have no
	 * effect.
	 *
	 * If the meta-service has already been registered it will return OpStatus::ERR.
	 *
	 * @param name The name of the meta-service.
	 * @return OpStatus::OK, OpStatus::ERR or OpStatus::ERR_NO_MEMORY
	 *
	 */
	OP_STATUS RegisterMetaService(const uni_char *name);
	/**
	 * @see RegisterMetaService(const uni_char *name);
	 */
	OP_STATUS RegisterMetaService(const OpString &name) { return RegisterMetaService(name.CStr()); }

protected:

	/**
	 * Creates all services.
	 *
	 * @param manager The manager that owns the services.
	 * @return OpStatus::OK on success, OpStatus::ERR_NO_MEMORY otherwise.
	 */
	OP_STATUS CreateServices(OpScopeServiceManager *manager);

	/**
	 * Deletes all services. No more events will be accepted from Core
	 * after this method is called, even events triggered by service
	 * destruction.
	 */
	void DeleteServices();

	/**
	 * Create service descriptions.
	 *
	 * @return OpStatus::OK on success, OpStatus::ERR_NO_MEMORY otherwise.
	 */
	 OP_STATUS CreateServiceDescriptors();

public:

	OpScopeDescriptorSet *descriptors;

	// Services:

""") + "\n\n"

        for service in services:
            if "cpp_instance" not in service.options or service.options[
                    "cpp_instance"].value == "true":
                if "cpp_feature" in service.options:
                    text += "#ifdef %(feature)s\n" % {
                        "feature": service.options["cpp_feature"].value
                    }

                text += "	%(class)s *%(name)s;\n" % {
                    "class": service.options["cpp_class"].value,
                    "name": self.memberName(service.name),
                }

                if "cpp_feature" in service.options:
                    text += "#endif // %(feature)s\n" % {
                        "feature": service.options["cpp_feature"].value
                    }

        text += "\n" + render("""

            private:
            	/**
            	 * Defines the name of a meta-service and manages the service object.
            	 * The meta-service is first initailized with a name and later on in the
            	 * CreateServices() a service object is created and placed in service.
            	 * When the MetaService is destructed it will delete the service object.
            	 */
            	struct MetaService : public ListElement<MetaService>
            	{
            		MetaService() : service(NULL) {}
            		~MetaService() { OP_DELETE(service); }
            		OpString name;
            		OpScopeService *service;
            	};
            	/**
            	 * List of meta-services currently registered.
            	 */
            	List<MetaService> meta_services;

            	// NOTE: These two methods are meant to be manually created outside of these classes
            	//       See modules/scope/src/scope_manager.cpp for the implementation
            	/**
            	 * Initializes any shared member variables, called before the services are created.
            	 */
            	OP_STATUS InitializeShared();
            	/**
            	 * Cleans up the shared member variables, called after the services has been deleted.
            	 */
            	void CleanupShared();

            	// Shared member variables. See cpp.conf for more information.
            """) + "\n"

        for field in self.manager_options.shared_fields:
            text += "	%s;\n" % field

        text += render("""
            }; // OpScopeServiceFactory

            /**
             * Contains the descriptors of all services in use by scope.
             *
             * @note This class is generated.
             */
            class OpScopeDescriptorSet
            {
            public:
            	OpScopeDescriptorSet();
            	~OpScopeDescriptorSet();

            	OP_STATUS Construct();

            private:
            	// Not really used for anything, except to prevent errors on certain
            	// compile configurations.
            	int dummy;

            public:
            """) + "\n"

        for service in services:
            if "cpp_feature" in service.options:
                text += "#ifdef %(feature)s\n" % {
                    "feature": service.options["cpp_feature"].value
                }

            text += "	%(class)s_SI::Descriptors *%(name)s;\n" % {
                "class": service.options["cpp_class"].value,
                "name": self.varName(service.name),
            }

            if "cpp_feature" in service.options:
                text += "#endif // %(feature)s\n" % {
                    "feature": service.options["cpp_feature"].value
                }

        text += "\n" + render("""
            }; // OpScopeDescriptorSet
            """) + "\n"

        return text
Exemple #33
0
    def renderDeclaration(self, services):
        text = ""

        text += "\n" + render("""

            // Includes

            #include "modules/scope/src/scope_service.h"

            // Includes for shared variables

            """) + "\n\n"

        for include in self.manager_options.includes:
            text += """#include "%s"\n""" % include

        text += "\n" + render("""

            // Forward declarations

            """) + "\n\n"

        for service in services:
            if "cpp_instance" not in service.options or service.options["cpp_instance"].value == "true":
                if "cpp_feature" in service.options:
                    text += "#ifdef %(feature)s\n" % {"feature": service.options["cpp_feature"].value}

                text += "class %(class)s;\n" % {"class": service.options["cpp_class"].value}

                if "cpp_feature" in service.options:
                    text += "#endif // %(feature)s\n" % {"feature": service.options["cpp_feature"].value}

        text += "\n" + render("""

            // Interface definitions

            """) + "\n\n"

        for service in services:
            if "cpp_feature" in service.options:
                text += "#ifdef %(feature)s\n" % {"feature": service.options["cpp_feature"].value}

            prefix = "g_scope_"
            basename = utils.join_underscore(utils.split_camelcase(service.name))
            if "cpp_file" in service.options:
                basename = service.options["cpp_file"].value
                prefix = "g_"
            text += """# include "%(cpp_gen_base)s/%(file)s_interface.h"\n""" % {
                "file": prefix + basename,
                "cpp_gen_base": service.options["cpp_gen_base"].value,
                }

            if "cpp_feature" in service.options:
                text += "#endif // %(feature)s\n" % {"feature": service.options["cpp_feature"].value}

        text += "\n" + render("""

class OpScopeDescriptorSet;
class OpScopeManager;
class OpScopeServiceManager;

/**
 * This is a generated class which defines all services which are use in scope.
 * It provides methods for registering meta-services as well as creating all
 * service objects.
 * In addition it keeps an instance of the OpScopeDescriptorSet class, this is
 * used to provide descriptor objects for messages in each service.
 *
 * This class is meant to be sub-classed into a real scope manager. The sub-class
 * must call RegisterMetaService() to register meta-services, and then call
 * CreateServices() and CreateServiceDescriptors() at a convenient time to
 * initialize the class properly.
 *
 * @note This class is generated.
 */
class OpScopeServiceFactory
{
public:
	/**
	 * Initializes the generated manager with all service pointers set to NULL.
	 */
	OpScopeServiceFactory();
	/**
	 * Deletes all active services and the descriptor set.
	 */
	virtual ~OpScopeServiceFactory();

	/**
	 * Get a reference to the descriptor set. Can only be used
	 * after a successful call to CreateServiceDescriptors.
	 */
	OpScopeDescriptorSet &GetDescriptorSet();

	/**
	 * Add a new meta-service named @a name. Meta-services are services
	 * which have no functionality, no version and cannot be introspected.
	 *
	 * The actual service will be created when CreateServices() is called
	 * by a sub-class. Adding a meta-service after that point will have no
	 * effect.
	 *
	 * If the meta-service has already been registered it will return OpStatus::ERR.
	 *
	 * @param name The name of the meta-service.
	 * @return OpStatus::OK, OpStatus::ERR or OpStatus::ERR_NO_MEMORY
	 *
	 */
	OP_STATUS RegisterMetaService(const uni_char *name);
	/**
	 * @see RegisterMetaService(const uni_char *name);
	 */
	OP_STATUS RegisterMetaService(const OpString &name) { return RegisterMetaService(name.CStr()); }

protected:

	/**
	 * Creates all services.
	 *
	 * @param manager The manager that owns the services.
	 * @return OpStatus::OK on success, OpStatus::ERR_NO_MEMORY otherwise.
	 */
	OP_STATUS CreateServices(OpScopeServiceManager *manager);

	/**
	 * Deletes all services. No more events will be accepted from Core
	 * after this method is called, even events triggered by service
	 * destruction.
	 */
	void DeleteServices();

	/**
	 * Create service descriptions.
	 *
	 * @return OpStatus::OK on success, OpStatus::ERR_NO_MEMORY otherwise.
	 */
	 OP_STATUS CreateServiceDescriptors();

public:

	OpScopeDescriptorSet *descriptors;

	// Services:

""") + "\n\n"

        for service in services:
            if "cpp_instance" not in service.options or service.options["cpp_instance"].value == "true":
                if "cpp_feature" in service.options:
                    text += "#ifdef %(feature)s\n" % {"feature": service.options["cpp_feature"].value}

                text += "	%(class)s *%(name)s;\n" % {
                    "class": service.options["cpp_class"].value,
                    "name": self.memberName(service.name),
                    }

                if "cpp_feature" in service.options:
                    text += "#endif // %(feature)s\n" % {"feature": service.options["cpp_feature"].value}

        text += "\n" + render("""

            private:
            	/**
            	 * Defines the name of a meta-service and manages the service object.
            	 * The meta-service is first initailized with a name and later on in the
            	 * CreateServices() a service object is created and placed in service.
            	 * When the MetaService is destructed it will delete the service object.
            	 */
            	struct MetaService : public ListElement<MetaService>
            	{
            		MetaService() : service(NULL) {}
            		~MetaService() { OP_DELETE(service); }
            		OpString name;
            		OpScopeService *service;
            	};
            	/**
            	 * List of meta-services currently registered.
            	 */
            	List<MetaService> meta_services;

            	// NOTE: These two methods are meant to be manually created outside of these classes
            	//       See modules/scope/src/scope_manager.cpp for the implementation
            	/**
            	 * Initializes any shared member variables, called before the services are created.
            	 */
            	OP_STATUS InitializeShared();
            	/**
            	 * Cleans up the shared member variables, called after the services has been deleted.
            	 */
            	void CleanupShared();

            	// Shared member variables. See cpp.conf for more information.
            """) + "\n"

        for field in self.manager_options.shared_fields:
            text += "	%s;\n" % field

        text += render("""
            }; // OpScopeServiceFactory

            /**
             * Contains the descriptors of all services in use by scope.
             *
             * @note This class is generated.
             */
            class OpScopeDescriptorSet
            {
            public:
            	OpScopeDescriptorSet();
            	~OpScopeDescriptorSet();

            	OP_STATUS Construct();

            private:
            	// Not really used for anything, except to prevent errors on certain
            	// compile configurations.
            	int dummy;

            public:
            """) + "\n"

        for service in services:
            if "cpp_feature" in service.options:
                text += "#ifdef %(feature)s\n" % {"feature": service.options["cpp_feature"].value}

            text += "	%(class)s_SI::Descriptors *%(name)s;\n" % {
                "class": service.options["cpp_class"].value,
                "name": self.varName(service.name),
                }

            if "cpp_feature" in service.options:
                text += "#endif // %(feature)s\n" % {"feature": service.options["cpp_feature"].value}

        text += "\n" + render("""
            }; // OpScopeDescriptorSet
            """) + "\n"

        return text
Exemple #34
0
    def renderServiceDeclaration(self, service, requests, events):
        enums = self.enums()

        text = (
            "\n"
            + self.indent(
                render(
                    """
            	virtual OP_STATUS             DoReceive( OpScopeClient *client, const OpScopeTPMessage &msg );
            	virtual int                   GetCommandCount() const;
            	virtual CommandRange          GetCommands() const;

            	virtual const OpProtobufMessage *GetMessage(unsigned int message_id) const;
            	virtual unsigned                 GetMessageCount() const;
            	virtual MessageIDRange           GetMessageIDs() const;
            	virtual MessageRange             GetMessages() const;
            """
                )
            )
            + "\n\n"
        )

        if enums:
            text += (
                self.indent(
                    render(
                        """
                // Introspection of enums
                virtual EnumIDRange GetEnumIDs() const;
                virtual unsigned  GetEnumCount() const;
                virtual BOOL      HasEnum(unsigned enum_id) const;
                virtual OP_STATUS GetEnum(unsigned enum_id, const uni_char *&name, unsigned &value_count) const;
                virtual OP_STATUS GetEnumValue(unsigned enum_id, unsigned idx, const uni_char *&value_name, unsigned &value_number) const;
                """
                    )
                )
                + "\n\n"
            )

        text += (
            self.indent(
                render(
                    """
            virtual const char *GetVersionString() const;
            virtual int         GetMajorVersion() const;
            virtual int         GetMinorVersion() const;
            virtual const char *GetPatchVersion() const;
            """
                )
            )
            + "\n\n"
        )

        if requests:
            text += "	// Request/Response functions\n"
            for command in requests:
                text += "	%(function)s\n" % {"function": request_functionSignature(command)}
            text += "\n"

        if events:
            text += "	// Event functions\n"
            for command in events:
                text += "	%(function)s\n" % {"function": event_functionSignature(command)}
            text += "\n"

        text += "\n	Descriptors *GetDescriptors() const;\n"
        return text
Exemple #35
0
    def renderMessage(self, message):
        klass = message.cpp.opMessage()
        protobuf_klass = message.cpp.klass()

        message_gen = CppMessageGenerator(
            message,
            self.package.cpp.cppMessageSet().symbol())
        message_gen.initMembers()

        members = ""
        for member in message_gen.redirect_members:
            members += self.indent(
                message_gen.renderFunctionDefinition(
                    member, use_rtype_outer=True)) + "\n\n"

        all_args = message_gen.construct + message_gen.constructor
        all_args.sort(key=lambda i: i[0].default != None)
        args = "\n	".join(
            [arg.declaration(relative=klass) + "," for arg, idx in all_args])
        constructor_args = "\n			".join([
            ", " + arg.declaration(relative=klass)
            for arg, idx in sorted(message_gen.constructor,
                                   key=lambda i: i[0].default != None)
        ])
        construct_args = "\n		".join([
            arg[0].declaration(relative=klass) + comma
            for arg, comma in commaList(
                sorted(message_gen.construct,
                       key=lambda i: i[0].default != None))
        ])
        arg_call = ", ".join([
            arg.symbol(relative=klass)
            for arg, idx in sorted(message_gen.constructor,
                                   key=lambda i: i[0].default != None)
        ])
        arg_call_comma = arg_call and ", " + arg_call
        arg_call2 = ", ".join([
            arg.symbol(relative=klass)
            for arg, idx in sorted(message_gen.construct,
                                   key=lambda i: i[0].default != None)
        ])

        allocateDefs = ""
        if message.cpp.opMessageAlloc == AllocationStrategy.ALLOCATE_OPMEMORYPOOL:
            allocateDefs = render(
                """
                /** Use OpMemoryPool allocation with OP_NEW */
                OP_USE_MEMORY_POOL_DECL;
                """, {"class": klass.name}) + "\n"

        custom_create = ""
        default_create = ""
        need_default_create = not all_args
        if all_args:
            # See if we need a default Create() method with no args, if all args
            # to the custom Create() method have default values then it is not
            # needed
            for arg in all_args:
                if not arg[0].default:
                    need_default_create = True
                    break

            custom_create = self.indent(
                render(
                    """
                	static %(class)s* Create(
                		%(args)s
                		const OpMessageAddress& src = OpMessageAddress(),
                		const OpMessageAddress& dst = OpMessageAddress(),
                		double delay = 0)
                	{
                		%(class)s *obj = OP_NEW(%(class)s, (src, dst, delay%(arg_call_comma)s));
                		if (obj)
                		{
                			if (OpStatus::IsSuccess(obj->Construct(%(arg_call2)s)))
                				return obj;

                			OP_DELETE(obj);
                		}
                		return NULL;
                	}
                """, {
                        "class": klass.name,
                        "args": args,
                        "arg_call2": arg_call2,
                        "arg_call_comma": arg_call_comma,
                    }))
        if need_default_create:
            makeCode = "OP_NEW(%(class)s, (src, dst, delay))" % {
                "class": klass.name,
            }
            default_create = self.indent(
                render(
                    """
                static %(class)s* Create()
                {
                    OpMessageAddress src;
                    OpMessageAddress dst;
                    double delay = 0;
                    return %(makeCode)s;
                }
                """, {
                        "class": klass.name,
                        "makeCode": makeCode,
                    }))

        defaultConstructor = ""
        for arg in message_gen.constructor:
            if not arg[0].default:
                defaultConstructor = self.indent(
                    render(
                        """
                	%(class)s(
                			const OpMessageAddress& src,
                			const OpMessageAddress& dst,
                			double delay
                			)
                		: OpTypedMessage(Type, src, dst, delay)
                		, protobuf_data()
                	{
                	}
                """, {
                            "class": klass.name,
                        }))
                break

        doc = ""
        if klass.doc:
            doc = klass.doc.toComment() + "\n"

        text = ""
        message_defines = message.cpp.defines()
        if message_defines:
            text += self.renderDefines(message_defines) + "\n"

        text = render(
            """
            %(doc)sclass %(class)s
            	: public OpTypedMessage
            {
            public:
            \t/**
            \t * The type for this message class.
            \t *
            \t * @note The reason this contains a integer value and not an enum
            \t *       is to avoid uneccesary dependencies and helps avoid
            \t *       re-compiles whenever a message is added, removed or renamed.
            \t */
            \tstatic const unsigned Type = %(messageIdentifier)du;

            	virtual ~%(class)s();

            %(default_create)s

            	static %(class)s* Create(
            		const OpMessageAddress& src,
            		const OpMessageAddress& dst = OpMessageAddress(),
            		double delay = 0)
            	{
            		return OP_NEW(%(class)s, (src, dst, delay));
            	}

            %(custom_create)s

            	static %(class)s* Cast(const OpTypedMessage* msg);

            	static %(class)s* Deserialize(
            		const OpMessageAddress& src,
            		const OpMessageAddress& dst,
            		double delay,
            		const OpData& data);

            	virtual OP_STATUS Serialize(OpData& data) const;

            	virtual const char *GetTypeString() const;

            	// Accessors/modifiers comes here
            %(members)s

            protected:
            %(allocateDefs)s
            	%(class)s(
            			const OpMessageAddress& src,
            			const OpMessageAddress& dst,
            			double delay
            			%(constructor_args)s
            			)
            		: OpTypedMessage(Type, src, dst, delay)
            		, protobuf_data(%(arg_call)s)
            	{
            	}

            %(defaultConstructor)s

            	OP_STATUS Construct(
            		%(construct_args)s
            	)
            	{
            		return protobuf_data.Construct(%(arg_call2)s);
            	}

            private:
            	%(protobuf_class)s protobuf_data;
            };

            """, {
                "class": klass.name,
                "protobuf_class": protobuf_klass.symbol(),
                "messageIdentifier": message.cpp.opMessageID,
                "doc": doc,
                "protobuf_message": "TODO: Fill in protobuf message here",
                "members": members,
                "args": args,
                "arg_call": arg_call,
                "arg_call_comma": arg_call_comma,
                "arg_call2": arg_call2,
                "constructor_args": constructor_args,
                "construct_args": construct_args,
                "default_create": default_create,
                "custom_create": custom_create,
                "defaultConstructor": defaultConstructor,
                "allocateDefs": self.indent(allocateDefs),
            }) + "\n"

        if message_defines:
            text += self.renderEndifs(message_defines) + "\n"

        return text
Exemple #36
0
    def renderInterfaceImplementation(self, service, includes, commands):
        messages = [msg for msg in self.sortedMessages() if msg != defaultMessage]
        all_messages = [msg for msg in self.sortedMessages(with_inline=True) if msg != defaultMessage]
        enums = self.enums()

        text = "\n"
        for include in includes:
            text += "#include %(include)s\n" % {"include": strQuote(include)}

        text += (
            "\n"
            + render(
                """
            // BEGIN: %(class)s_SI::Descriptors

            %(class)s_SI::Descriptors::Descriptors()
            {
            """,
                {"class": service.options["cpp_class"].value},
            )
            + "\n"
        )

        text += (
            render(
                """
            }

            %(class)s_SI::Descriptors::~Descriptors()
            {
            """,
                {"class": service.options["cpp_class"].value},
            )
            + "\n"
        )

        text += (
            render(
                """
            }

            OP_STATUS
            %(class)s_SI::Descriptors::Construct()
            {
                RETURN_IF_ERROR(%(descriptorClass)s::Construct());
            """,
                {
                    "class": service.options["cpp_class"].value,
                    "descriptorClass": self.package.cpp.descriptorClass().symbol(),
                },
            )
            + "\n"
        )

        text += "	// Initialize commands\n"

        for idx, command in enumerate(commands):
            text += self.indent(
                render(
                    """
                command_list[%(idx)s] = OpScopeCommand(%(command)s,
                					%(commandEnum)s
                """,
                    {"idx": idx, "command": strQuote(command.name), "commandEnum": enumName(command)},
                )
            )
            if isinstance(command, proto.Event):
                text += ",\n						OpScopeCommand::Type_Event"
            else:
                text += ",\n						OpScopeCommand::Type_Call"

            if isinstance(command, proto.Event):
                text += render(
                    """
                    ,
                    						_gen_void_MsgID,
                    						%(requestIdentifier)s
                    """,
                    {"requestIdentifier": self.renderMessageID(command.message)},
                )
            else:
                text += render(
                    """
                    ,
                    						%(requestIdentifier)s,
                    						%(responseIdentifier)s
                    """,
                    {
                        "requestIdentifier": self.renderMessageID(command.message),
                        "responseIdentifier": self.renderMessageID(command.response),
                    },
                )
            text += "\n						);\n"
        text += "	" + render(
            """
            	return OpStatus::OK;
            }

            // END: %(class)s_SI::Descriptors
            """,
            {"class": service.options["cpp_class"].value},
        )

        return text
Exemple #37
0
    def renderServiceInterface(self, service, commands, generate_instance):
        text = (
            "\n"
            + render(
                """
            class %(class)s_SI
            	: public OpScopeService
            	, public %(class)s_MessageSet
            {
            public:
            	%(class)s_SI(const uni_char* id = NULL, OpScopeServiceManager *manager = NULL, ControlType control = CONTROL_MANUAL);
            	virtual ~%(class)s_SI();

            	enum CommandEnum
            	{
            """,
                {
                    "class": service.options[
                        "cpp_class"
                    ].value  # TODO: Store fully generated class name on service object
                },
            )
            + "\n"
        )

        for command in commands[:1]:
            text += "		  %(enumName)s = %(enumValue)s\n" % {
                "enumName": command.options["cpp_enum_name"].value,
                "enumValue": command.id,
            }

        for command in commands[1:]:
            text += "		, %(enumName)s = %(enumValue)s\n" % {
                "enumName": command.options["cpp_enum_name"].value,
                "enumValue": command.id,
            }

        text += "\n		, Command_Count = %(commandCount)s // Number of commands in this service\n" % {
            "commandCount": len(commands)
        }

        text += self.indent(
            render(
                """
            };
            """
            )
        )

        text += (
            "\n"
            + self.indent(
                render(
                    """
            // This class contains the descriptors or all commands of this service
            class Descriptors
                : public %(descriptorClass)s
            {
            public:
            \tDescriptors();
            \t~Descriptors();

            \tOP_STATUS Construct();
                """,
                    {
                        "class": service.options["cpp_class"].value,
                        "descriptorClass": self.package.cpp.descriptorClass().symbol(),
                    },
                )
            )
            + "\n\n"
        )

        text += "\n"

        text += "		// List of commands\n" + "		OpScopeCommand command_list[Command_Count];\n" + "	};\n\n"

        if generate_instance:
            text += "\n// Service API implementation: BEGIN\n\n"
            text += self.renderServiceDeclaration(self.service, self.requests, self.events) + "\n\n"
            text += "\n// Service API implementation: END\n"

        text += "\n};\n\n"

        text += "\n"
        return text
Exemple #38
0
    def generate(self):
        enums = self.enums
        guard = re.sub(
            "_+", "_",
            re.sub("[^a-zA-Z0-9]+", "_",
                   os.path.basename(self.filePath))).strip("_").upper()

        text = fileHeader()
        text += "\n" + render(
            """
            // Generated from proto files in the system

            #ifndef %(guard)s
            #define %(guard)s

            %(defines)s

            class OpTypedMessage;
            struct OpMessageAddress;
            class OpData;

            class OpTypedMessageBase
            {
            public:
            """, {
                "defines": self.renderDefines(self.defines),
                "guard": guard,
            }) + "\n"

        text += self.indent(self.renderVerify(enums)) + "\n"

        text += self.indent(
            render("""
            /**
             * Deserializes the message data in @p data based on the @p type.
             * It will call the Class::Deserialize() method on the class that
             * belongs to the type.
             *
             * @param type The type of message data to decode. This determines
             *        the class of the returned instance.
             * @param src Source address of the message. This will be placed in
             *        the returned object.
             * @param dst Destination address of the message. This will be
             *        placed in the returned object.
             * @param delay Number of milliseconds until this message should
             *        be processed. This will be recorded in the returned object.
             * @param data The data-stream from which to de-serialize the
             *        message object.
             * @return The deserialized message object or @c NULL on failure.
             */
            static OpTypedMessage*
            DeserializeData(
                int type,
                const OpMessageAddress& src,
                const OpMessageAddress& dst,
                double delay,
                const OpData& data);
            """))
        text += render(
            """
            };

            %(endifs)s

            #endif // %(guard)s
            """, {
                "endifs": self.renderEndifs(self.defines),
                "guard": guard,
            }) + "\n"

        return text
Exemple #39
0
    def renderRequestDecode(self, command):
        text = "\n		OP_STATUS status = OpStatus::OK;\n"

        if requiresAsyncResponse(command):
            text += (
                self.indent(
                    render(
                        """
                unsigned async_tag;
                status = InitAsyncCommand(msg, async_tag); // Needed for async requests, the response will use this info when request is done
                if (OpStatus::IsError(status))
                {
                	RETURN_IF_ERROR(SetCommandError(OpScopeTPHeader::InternalError, GetInitAsyncCommandFailedText()));
                	return status;
                }
                """
                    ),
                    2,
                )
                + "\n"
            )

        if command.message.isNonEmpty():
            text += "		%(requestMessage)s in;\n" % {"requestMessage": message_className(command.message)}

        if hasattr(command, "response") and command.response.isNonEmpty():
            text += "		%(responseMessage)s out;\n" % {"responseMessage": message_className(command.response)}
        text += "\n"

        if command.message.isNonEmpty():
            text += (
                self.indent(
                    render(
                        """
                OpProtobufInstanceProxy in_proxy(%(requestMessage)s::GetMessageDescriptor(GetDescriptors()), &in);
                if (in_proxy.GetProtoMessage() == NULL)
                	return OpStatus::ERR_NO_MEMORY;
                status = ParseMessage(client, msg, in_proxy);
                if (OpStatus::IsError(status))
                {
                	if (GetCommandError().GetStatus() == OpScopeTPHeader::OK) // Set a generic error if none was set by a parser
                		RETURN_IF_ERROR(SetCommandError(OpScopeTPHeader::InternalError, GetParseCommandMessageFailedText()));
                	return status;
                }
                """,
                        {"requestMessage": message_className(command.message)},
                    ),
                    2,
                )
                + "\n\n"
            )

        text += (
            self.indent(
                render(
                    """
            status = %(commandCall)s;
            if (OpStatus::IsError(status))
            {
            	if (GetCommandError().GetStatus() == OpScopeTPHeader::OK) // Set a generic error if none was set by command
            """
                )
                % {"commandCall": request_functionCall(command)},
                2,
            )
            + "\n"
        )

        if requiresAsyncResponse(command):
            text += (
                self.indent(
                    render(
                        """
                {
                	OP_STATUS tmp_status = SetCommandError(OpScopeTPHeader::InternalError, GetCommandExecutionFailedText());
                	OpStatus::Ignore(tmp_status);
                }
                // Remove the async command since the command failed to send an async response
                CleanupAsyncCommand(async_tag);
            """
                    ),
                    3,
                )
                + "\n"
            )
        else:
            text += "			RETURN_IF_ERROR(SetCommandError(OpScopeTPHeader::InternalError, GetCommandExecutionFailedText()));\n"

        text += "			return status;\n" + "		}\n"

        if hasattr(command, "response") and command.response.isNonEmpty():
            text += (
                "\n"
                + self.indent(
                    render(
                        """
                OpProtobufInstanceProxy out_proxy(%(responseMessage)s::GetMessageDescriptor(GetDescriptors()), &out);
                if (out_proxy.GetProtoMessage() == NULL)
                	return OpStatus::ERR_NO_MEMORY;
                RETURN_IF_ERROR(SendResponse(client, msg, out_proxy));
            """,
                        {"responseMessage": message_className(command.response)},
                    ),
                    2,
                )
                + "\n"
            )
        elif not requiresAsyncResponse(command):
            text += (
                "\n"
                + self.indent(
                    render(
                        """
                // The request does not define a response message so we send the default response which is an empty message
                OpProtobufInstanceProxy out_proxy(OpScopeDefaultMessage::GetMessageDescriptor(), &g_scope_manager->default_message_instance);
                if (out_proxy.GetProtoMessage() == NULL)
                	return OpStatus::ERR_NO_MEMORY;
                status = SendResponse(client, msg, out_proxy);
                if (OpStatus::IsError(status))
                {
                	if (!IsResponseSent() && GetCommandError().GetStatus() == OpScopeTPHeader::OK) // Set a generic error if response sending failed or no error was set by response code
                		RETURN_IF_ERROR(SetCommandError(OpScopeTPHeader::InternalError, GetCommandResponseFailedText()));
                	return status;
                }
            """,
                        {},
                    ),
                    2,
                )
                + "\n"
            )
        return text
Exemple #40
0
    def renderMessageImplementation(self, message):
        klass = message.cpp.opMessage()
        protoKlass = message.cpp.klass()

        message_gen = CppMessageGenerator(message, self.package.cpp.cppMessageSet().symbol())
        message_gen.initMembers()
        message_gen.cpp_class_path = klass.symbol()

        members = ""
        for member in message_gen.redirect_members:
            if not member.is_inline:
                members += message_gen.renderFunctionImplementation(member) + "\n\n"

        text = render("""
            %(classPath)s::~%(class)s()
            {
            }

            /* static */ %(classPath)s*
            %(classPath)s::Cast(const OpTypedMessage* msg)
            {
            	OP_ASSERT(msg && msg->GetType() == Type);
                return static_cast<%(classPath)s*>(const_cast<OpTypedMessage*>(msg));
            }

            /* static */ %(classPath)s*
            %(classPath)s::Deserialize(
            		const OpMessageAddress& src,
            		const OpMessageAddress& dst,
            		double delay,
            		const OpData& data)
            {
            	OpProtobufInputStream stream;
            	RETURN_VALUE_IF_ERROR(stream.Construct(data), NULL);
            	%(classPathRelative)s *msg = %(classPathRelative)s::Create(src, dst, delay);
            	if (!msg)
            		return NULL;
            	OpProtobufInstanceProxy instance(%(protoClassPath)s::GetMessageDescriptor(PROTOBUF_DESCRIPTOR(%(descriptorID)s)), &msg->protobuf_data);
            	if (OpStatus::IsError(stream.Read(instance)))
            	{
            		OP_DELETE(msg);
            		return NULL;
            	}
            	return msg;
            }

            OP_STATUS
            %(classPath)s::Serialize(OpData& data) const
            {
            	OpProtobufOpDataOutputRange range(data);
            	OpProtobufOutputStream stream(&range);
            	%(protoClassPath)s *proto = const_cast<%(protoClassPath)s *>(&protobuf_data);
            	void *proto_ptr = proto;
            	OpProtobufInstanceProxy instance(%(protoClassPath)s::GetMessageDescriptor(PROTOBUF_DESCRIPTOR(%(descriptorID)s)), proto_ptr);
            	return stream.Write(instance);
            }

            const char *
            %(classPath)s::GetTypeString() const
            {
            	const OpProtobufMessage *d = %(protoClassPath)s::GetMessageDescriptor(PROTOBUF_DESCRIPTOR(%(descriptorID)s));
            	return d ? d->GetName() : NULL;
            }
            """, {
                "classPath": klass.symbol(),
                "classPathRelative": klass.symbol(relative=klass),
                "class": klass.name,
                "protoClassPath": protoKlass.symbol(),
                "globalModule": "g_%s" % self.options.module,
                "descriptorID": self.package.cpp.descriptorIdentifier(),
            })

        text += members

        return text
Exemple #41
0
    def renderServiceImplementation(self, service, requests, events, generate_instance):
        class_name = service.options["cpp_class"].value + "_SI"

        class_name_base = service.iparent.cpp.cppMessageSet().symbol()
        if class_name_base.find("_MessageSet"):
            cpp_descriptor_class_name = class_name_base.replace("_MessageSet", "_Descriptors")
        else:
            cpp_descriptor_class_name = class_name_base + "_Descriptors"

        text = "\n"

        text += (
            "\n"
            + render(
                """
            // Service implementation

            %(class)s::%(class)s(const uni_char* id, OpScopeServiceManager *manager, ControlType control)
            		: OpScopeService(id == NULL ? UNI_L(%(protocol_name_quoted)s) : id, manager, control)
            {
            }

            /*virtual*/
            %(class)s::~%(class)s()
            {
            }
            """,
                {
                    "class": class_name,
                    "protocol_name_quoted": strQuote(utils.join_dashed(utils.split_camelcase(service.name))),
                    "serviceVarName": self.varName(service.name),
                },
            )
            + "\n"
        )
        if not generate_instance:
            return text

        text += (
            "\n"
            + render(
                """
            /*virtual*/
            int
            %(class)s::GetCommandCount() const
            {
            	return Command_Count;
            }

            /*virtual*/
            OpScopeService::CommandRange
            %(class)s::GetCommands() const
            {
            	Descriptors *descriptors = g_scope_manager->GetDescriptorSet().%(serviceVarName)s;
            	OP_ASSERT(descriptors);
            	return CommandRange(descriptors ? descriptors->command_list : NULL, Command_Count);
            }

            /*virtual*/
            OP_STATUS
            %(class)s::DoReceive( OpScopeClient *client, const OpScopeTPMessage &msg )
            {
            	// Check for invalid request data
            	if (msg.Status() != OpScopeTPMessage::OK) // All calls must have status OK
            		return SetCommandError(OpScopeTPMessage::BadRequest, GetInvalidStatusFieldText());
            	if (msg.ServiceName().Compare(GetName()) != 0) // Make sure the service name matches the one in the message
            		return SetCommandError(OpScopeTPMessage::InternalError, GetIncorrectServiceText());
            """,
                {
                    "class": class_name,
                    "protocol_name_quoted": strQuote(utils.join_dashed(utils.split_camelcase(service.name))),
                    "serviceVarName": self.varName(service.name),
                },
            )
            + "\n\n"
        )

        if requests:
            text += (
                self.indent(
                    render(
                        """
                if (msg.CommandID() == %(requestID)s) // %(requestName)s
                {
                """,
                        {"requestID": enumName(requests[0]), "requestName": requests[0].name},
                    )
                )
                + self.renderRequestDecode(requests[0])
                + "	}\n"
            )

            for command in requests[1:]:
                text += (
                    self.indent(
                        render(
                            """
                    else if (msg.CommandID() == %(requestID)s) // %(requestName)s
                    {
                    """,
                            {"requestID": enumName(command), "requestName": command.name},
                        )
                    )
                    + self.renderRequestDecode(command)
                    + "	}\n"
                )

            text += (
                self.indent(
                    render(
                        """
                else
                {
                	SetCommandError(OpScopeTPMessage::CommandNotFound, GetCommandNotFoundText());
                	return OpStatus::ERR;
                }
                """
                    )
                )
                + "\n"
            )

        text += "	return OpStatus::OK;\n}\n\n"

        messages = [msg for msg in service.messages() if msg != defaultMessage]
        enums = self.enums()

        text += (
            render(
                """
            /*virtual*/
            const OpProtobufMessage *
            %(class)s::GetMessage(unsigned message_id) const
            {
            	Descriptors *descriptors = GetDescriptors();
            	if (!descriptors)
            		return NULL;
            	return descriptors->Get(message_id);
            }

            %(class)s::Descriptors *
            %(class)s::GetDescriptors() const
            {
            	Descriptors *d = g_scope_manager->GetDescriptorSet().%(serviceVarName)s;
            	OP_ASSERT(d);
            	return d;
            }

            /*virtual*/
            unsigned
            %(class)s::GetMessageCount() const
            {
            	return %(descriptorClass)s::_gen_Message_Count;
            }

            /*virtual*/
            OpScopeService::MessageIDRange
            %(class)s::GetMessageIDs() const
            {
            	unsigned start = %(descriptorClass)s::_gen_Message_Count > 0 ? 1 : 0;
            	return MessageIDRange(start, start + %(descriptorClass)s::_gen_Message_Count);
            }

            /*virtual*/
            OpScopeService::MessageRange
            %(class)s::GetMessages() const
            {
            	unsigned start = %(descriptorClass)s::_gen_Message_Count > 0 ? 1 : 0;
            	return MessageRange(this, start, start + %(descriptorClass)s::_gen_Message_Count);
            }
            """,
                {
                    "class": class_name,
                    "serviceVarName": self.varName(service.name),
                    "descriptorClass": cpp_descriptor_class_name,
                },
            )
            + "\n\n"
        )

        text += (
            render(
                """
            /* virtual */
            const char *
            %(class)s::GetVersionString() const
            {
            	return "%(version)s";
            }

            /* virtual */
            int
            %(class)s::GetMajorVersion() const
            {
            	return %(versionMajor)s;
            }

            /* virtual */
            int
            %(class)s::GetMinorVersion() const
            {
            	return %(versionMinor)s;
            }

            /* virtual */
            const char *
            %(class)s::GetPatchVersion() const
            {
            	return "%(versionPatch)s";
            }
            """,
                {
                    "class": class_name,
                    "version": service.options["version"].value,
                    "versionMajor": service.version[0],
                    "versionMinor": service.version[1],
                    "versionPatch": service.version[2],
                },
            )
            + "\n"
        )

        if events:
            for event in events:
                params = []
                if event.message.isNonEmpty():
                    params.append("const %s &msg" % message_className(event.message))
                if requiresAsyncResponse(event):
                    params.append("unsigned int tag")

                text += (
                    "\n"
                    + render(
                        """
                    OP_STATUS
                    %(class)s::%(eventMethod)s(%(eventParams)s) // %(eventName)s
                    {
                    """,
                        {
                            "class": class_name,
                            "eventMethod": event_functionName(event),
                            "eventParams": ", ".join(params),
                            "eventName": event.name,
                        },
                    )
                    + "\n"
                )

                if event.message.isNonEmpty():
                    text += (
                        "	OpProtobufInstanceProxy proxy(%(messageClass)s::GetMessageDescriptor(GetDescriptors()), const_cast<%(messageClass)s *>(&msg));\n"
                        % {"messageClass": message_className(event.message)}
                    )
                else:
                    text += "	OpProtobufInstanceProxy proxy(OpScopeDefaultMessage::GetMessageDescriptor(), &g_scope_manager->default_message_instance);\n"

                text += "	if (proxy.GetProtoMessage() == NULL)\n" + "		return OpStatus::ERR_NO_MEMORY;\n"

                if requiresAsyncResponse(event):
                    text += "	return SendAsyncResponse(tag, proxy, %(eventEnum)s);\n" % {"eventEnum": enumName(event)}
                else:
                    text += "	return SendEvent(proxy, %(eventEnum)s);\n" % {"eventEnum": enumName(event)}

                text += "}\n\n"

        if enums:
            text += (
                render(
                    """
                // Enum introspection: BEGIN

                /*virtual*/
                OpScopeService::EnumIDRange
                %(class)s::GetEnumIDs() const
                {
                	Descriptors *descriptors = GetDescriptors();
                	return EnumIDRange(descriptors ? descriptors->enum_id_list : NULL, %(descriptorClass)s::_gen_Enum_Count);
                }

                /*virtual*/
                unsigned
                %(class)s::GetEnumCount() const
                {
                	return %(descriptorClass)s::_gen_Enum_Count;
                }

                /*virtual*/
                BOOL
                %(class)s::HasEnum(unsigned enum_id) const
                {
                	switch (enum_id)
                	{
                """,
                    {"class": class_name, "descriptorClass": cpp_descriptor_class_name},
                )
                + "\n"
            )
            for enum in enums:
                text += "		case %(descriptorClass)s::_gen_EnumID_%(enumPath)s:\n" % {
                    "enumPath": "_".join(enum.path()),
                    "descriptorClass": cpp_descriptor_class_name,
                }

            text += "			return TRUE;\n" "	}\n" "	return FALSE;\n" "}\n" "\n"
            text += (
                render(
                    """
                /*virtual*/
                OP_STATUS
                %(class)s::GetEnum(unsigned enum_id, const uni_char *&name, unsigned &value_count) const
                {
                	switch (enum_id)
                	{
                """,
                    {"class": class_name},
                )
                + "\n"
            )

            for enum in enums:
                text += (
                    self.indent(
                        render(
                            """
                    // %(messageClassPath)s
                    case %(descriptorClass)s::_gen_EnumID_%(enumPath)s:
                    	name = UNI_L(%(enum)s);
                    	value_count = %(descriptorClass)s::_gen_EnumValueCount_%(enumPath)s;
                    	return OpStatus::OK;
                    """,
                            {
                                "messageClassPath": messageClassPath(enum)[1],
                                "enumPath": "_".join(enum.path()),
                                "enum": strQuote(enum.name),
                                "descriptorClass": cpp_descriptor_class_name,
                            },
                        ),
                        2,
                    )
                    + "\n"
                )

            text += "	}\n" "	return OpStatus::ERR_NO_SUCH_RESOURCE;\n" "}\n" "\n"
            text += (
                render(
                    """
                /*virtual*/
                OP_STATUS
                %(class)s::GetEnumValue(unsigned enum_id, unsigned idx, const uni_char *&value_name, unsigned &value_number) const
                {
                	switch (enum_id)
                	{
                """,
                    {"class": class_name},
                )
                + "\n"
            )

            for enum in enums:
                text += (
                    self.indent(
                        render(
                            """
                    // %(messageClassPath)s
                    case %(descriptorClass)s::_gen_EnumID_%(enumPath)s:
                    {
                    """,
                            {
                                "messageClassPath": messageClassPath(enum)[1],
                                "enumPath": "_".join(enum.path()),
                                "descriptorClass": cpp_descriptor_class_name,
                            },
                        ),
                        2,
                    )
                    + "\n"
                )
                if enum.values:
                    text += (
                        self.indent(
                            render(
                                """
                        if (idx > %(descriptorClass)s::_gen_EnumValueCount_%(enumPath)s)
                        	return OpStatus::ERR_OUT_OF_RANGE;
                        // Values for %(messageClassPath)s
                        const unsigned enum_numbers[] = {
                        	  %(enumValue)s
                        """,
                                {
                                    "enumPath": "_".join(enum.path()),
                                    "messageClassPath": messageClassPath(enum)[1],
                                    "enumValue": enum.values[0].value,
                                    "descriptorClass": cpp_descriptor_class_name,
                                },
                            ),
                            3,
                        )
                        + "\n"
                    )
                    for value in enum.values[1:]:
                        text += "				, %s\n" % value.value

                    text += (
                        self.indent(
                            render(
                                """
                        }; // ARRAY OK 2010-04-14 jborsodi
                        const unsigned name_offsets[] = {
                        	  0
                        """
                            ),
                            3,
                        )
                        + "\n"
                    )
                    for idx in range(1, len(enum.values)):
                        text += "				, %(offset)s\n" % {
                            "offset": sum([len(value.name) + 1 for value in enum.values[:idx]])
                        }

                    text += (
                        self.indent(
                            render(
                                """
                        }; // ARRAY OK 2010-04-14 jborsodi
                        const uni_char *names = UNI_L( %(enumStrings)s );
                        OP_ASSERT(idx < sizeof(name_offsets));
                        OP_ASSERT(idx < sizeof(enum_numbers));
                        value_name = names + name_offsets[idx];
                        value_number = enum_numbers[idx];
                        return OpStatus::OK;
                        """,
                                {
                                    "enumStrings": strQuote(
                                        "".join(
                                            [value.name + "\0" for value in enum.values[:-1]] + [enum.values[-1].name]
                                        )
                                    )
                                },
                            ),
                            3,
                        )
                        + "\n"
                    )
                else:
                    text += "			return OpStatus::ERR; // No values so return error\n"

                text += "		}\n\n"

            text += "	}\n" "	return OpStatus::ERR_NO_SUCH_RESOURCE;\n" "}\n" "// Enum introspection: END\n"
        return text
Exemple #42
0
    def renderMessage(self, message):
        klass = message.cpp.opMessage()
        protobuf_klass = message.cpp.klass()

        message_gen = CppMessageGenerator(message, self.package.cpp.cppMessageSet().symbol())
        message_gen.initMembers()

        members = ""
        for member in message_gen.redirect_members:
            members += self.indent(message_gen.renderFunctionDefinition(member, use_rtype_outer=True)) + "\n\n"

        all_args = message_gen.construct + message_gen.constructor
        all_args.sort(key=lambda i: i[0].default != None)
        args = "\n	".join([arg.declaration(relative=klass) + "," for arg, idx in all_args])
        constructor_args = "\n			".join([", " + arg.declaration(relative=klass) for arg, idx in sorted(message_gen.constructor, key=lambda i: i[0].default != None)])
        construct_args = "\n		".join([arg[0].declaration(relative=klass) + comma for arg, comma in commaList(sorted(message_gen.construct, key=lambda i: i[0].default != None))])
        arg_call = ", ".join([arg.symbol(relative=klass) for arg, idx in sorted(message_gen.constructor, key=lambda i: i[0].default != None)])
        arg_call_comma = arg_call and ", " + arg_call
        arg_call2 = ", ".join([arg.symbol(relative=klass) for arg, idx in sorted(message_gen.construct, key=lambda i: i[0].default != None)])

        allocateDefs = ""
        if message.cpp.opMessageAlloc == AllocationStrategy.ALLOCATE_OPMEMORYPOOL:
            allocateDefs = render("""
                /** Use OpMemoryPool allocation with OP_NEW */
                OP_USE_MEMORY_POOL_DECL;
                """, { "class": klass.name }) + "\n"

        custom_create = ""
        default_create = ""
        need_default_create = not all_args
        if all_args:
            # See if we need a default Create() method with no args, if all args
            # to the custom Create() method have default values then it is not
            # needed
            for arg in all_args:
                if not arg[0].default:
                    need_default_create = True
                    break

            custom_create = self.indent(render("""
                	static %(class)s* Create(
                		%(args)s
                		const OpMessageAddress& src = OpMessageAddress(),
                		const OpMessageAddress& dst = OpMessageAddress(),
                		double delay = 0)
                	{
                		%(class)s *obj = OP_NEW(%(class)s, (src, dst, delay%(arg_call_comma)s));
                		if (obj)
                		{
                			if (OpStatus::IsSuccess(obj->Construct(%(arg_call2)s)))
                				return obj;

                			OP_DELETE(obj);
                		}
                		return NULL;
                	}
                """, {
                    "class": klass.name,
                    "args": args,
                    "arg_call2": arg_call2,
                    "arg_call_comma": arg_call_comma,
                }))
        if need_default_create:
            makeCode = "OP_NEW(%(class)s, (src, dst, delay))" % {
                    "class": klass.name,
                    }
            default_create = self.indent(render("""
                static %(class)s* Create()
                {
                    OpMessageAddress src;
                    OpMessageAddress dst;
                    double delay = 0;
                    return %(makeCode)s;
                }
                """, {
                    "class": klass.name,
                    "makeCode": makeCode,
                }))

        defaultConstructor = ""
        for arg in message_gen.constructor:
            if not arg[0].default:
                defaultConstructor = self.indent(render("""
                	%(class)s(
                			const OpMessageAddress& src,
                			const OpMessageAddress& dst,
                			double delay
                			)
                		: OpTypedMessage(Type, src, dst, delay)
                		, protobuf_data()
                	{
                	}
                """, {
                    "class": klass.name,
                }))
                break

        doc = ""
        if klass.doc:
            doc = klass.doc.toComment() + "\n"

        text = ""
        message_defines = message.cpp.defines()
        if message_defines:
            text += self.renderDefines(message_defines) + "\n"

        text = render("""
            %(doc)sclass %(class)s
            	: public OpTypedMessage
            {
            public:
            \t/**
            \t * The type for this message class.
            \t *
            \t * @note The reason this contains a integer value and not an enum
            \t *       is to avoid uneccesary dependencies and helps avoid
            \t *       re-compiles whenever a message is added, removed or renamed.
            \t */
            \tstatic const unsigned Type = %(messageIdentifier)du;

            	virtual ~%(class)s();

            %(default_create)s

            	static %(class)s* Create(
            		const OpMessageAddress& src,
            		const OpMessageAddress& dst = OpMessageAddress(),
            		double delay = 0)
            	{
            		return OP_NEW(%(class)s, (src, dst, delay));
            	}

            %(custom_create)s

            	static %(class)s* Cast(const OpTypedMessage* msg);

            	static %(class)s* Deserialize(
            		const OpMessageAddress& src,
            		const OpMessageAddress& dst,
            		double delay,
            		const OpData& data);

            	virtual OP_STATUS Serialize(OpData& data) const;

            	virtual const char *GetTypeString() const;

            	// Accessors/modifiers comes here
            %(members)s

            protected:
            %(allocateDefs)s
            	%(class)s(
            			const OpMessageAddress& src,
            			const OpMessageAddress& dst,
            			double delay
            			%(constructor_args)s
            			)
            		: OpTypedMessage(Type, src, dst, delay)
            		, protobuf_data(%(arg_call)s)
            	{
            	}

            %(defaultConstructor)s

            	OP_STATUS Construct(
            		%(construct_args)s
            	)
            	{
            		return protobuf_data.Construct(%(arg_call2)s);
            	}

            private:
            	%(protobuf_class)s protobuf_data;
            };

            """, {
                "class": klass.name,
                "protobuf_class": protobuf_klass.symbol(),
                "messageIdentifier": message.cpp.opMessageID,
                "doc": doc,
                "protobuf_message": "TODO: Fill in protobuf message here",
                "members": members,
                "args": args,
                "arg_call": arg_call,
                "arg_call_comma": arg_call_comma,
                "arg_call2": arg_call2,
                "constructor_args": constructor_args,
                "construct_args": construct_args,
                "default_create": default_create,
                "custom_create": custom_create,
                "defaultConstructor": defaultConstructor,
                "allocateDefs": self.indent(allocateDefs),
            }) + "\n"

        if message_defines:
            text += self.renderEndifs(message_defines) + "\n"

        return text