Exemplo n.º 1
0
 def messageGenerators(self, with_inline=False):
     messages = self.sortedMessages(with_inline=with_inline)
     if "cpp_class" not in self.service.options:
         raise CppError("Missing 'cpp_class' option in service definition")
     cpp_class = self.service.options["cpp_class"].value
     for msg in messages:
         if msg.isNonEmpty():
             gen = generatorManager.getMessage(msg)
             if not gen:
                 gen = generatorManager.setMessage(
                     msg, CppMessageGenerator(msg, cpp_class + "_SI"))
             yield gen
Exemplo n.º 2
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
Exemplo n.º 3
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
Exemplo n.º 4
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
Exemplo n.º 5
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