You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
309 lines
9.5 KiB
309 lines
9.5 KiB
@############################################### |
|
@# |
|
@# ROS message source code generation for C++ |
|
@# |
|
@# EmPy template for generating <msg>.h files |
|
@# |
|
@############################################### |
|
@# Start of Template |
|
@# |
|
@# Context: |
|
@# - file_name_in (String) Source file |
|
@# - spec (msggen.MsgSpec) Parsed specification of the .msg file |
|
@# - md5sum (String) MD5Sum of the .msg specification |
|
@############################################### |
|
/* Software License Agreement (BSD License) |
|
* |
|
* Copyright (c) 2011, Willow Garage, Inc. |
|
* All rights reserved. |
|
* |
|
* Redistribution and use in source and binary forms, with or without |
|
* modification, are permitted provided that the following conditions |
|
* are met: |
|
* |
|
* * Redistributions of source code must retain the above copyright |
|
* notice, this list of conditions and the following disclaimer. |
|
* * Redistributions in binary form must reproduce the above |
|
* copyright notice, this list of conditions and the following |
|
* disclaimer in the documentation and/or other materials provided |
|
* with the distribution. |
|
* * Neither the name of Willow Garage, Inc. nor the names of its |
|
* contributors may be used to endorse or promote products derived |
|
* from this software without specific prior written permission. |
|
* |
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
|
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
|
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
* POSSIBILITY OF SUCH DAMAGE. |
|
* |
|
* Auto-generated by genmsg_cpp from file @file_name_in |
|
* |
|
*/ |
|
|
|
@{ |
|
import genmsg.msgs |
|
import gencpp |
|
|
|
cpp_namespace = '::%s::'%(spec.package) # TODO handle nested namespace |
|
cpp_class = '%s_'%spec.short_name |
|
cpp_full_name = '%s%s'%(cpp_namespace,cpp_class) |
|
cpp_full_name_with_alloc = '%s<ContainerAllocator>'%(cpp_full_name) |
|
cpp_msg_definition = gencpp.escape_message_definition(msg_definition) |
|
}@ |
|
|
|
#ifndef @(spec.package.upper())_MESSAGE_@(spec.short_name.upper())_H |
|
#define @(spec.package.upper())_MESSAGE_@(spec.short_name.upper())_H |
|
|
|
@############################## |
|
@# Generic Includes |
|
@############################## |
|
|
|
#include <string> |
|
#include <vector> |
|
#include <map> |
|
|
|
#include <ros/types.h> |
|
#include <ros/serialization.h> |
|
#include <ros/builtin_message_traits.h> |
|
#include <ros/message_operations.h> |
|
|
|
@############################## |
|
@# Includes for dependencies |
|
@############################## |
|
@{ |
|
for field in spec.parsed_fields(): |
|
if (not field.is_builtin): |
|
if (field.is_header): |
|
print('#include <std_msgs/Header.h>') |
|
else: |
|
(package, name) = genmsg.names.package_resource_name(field.base_type) |
|
package = package or spec.package # convert '' to package |
|
print('#include <%s/%s.h>'%(package, name)) |
|
}@ |
|
|
|
namespace @(spec.package) |
|
{ |
|
template <class ContainerAllocator> |
|
struct @(spec.short_name)_ |
|
{ |
|
typedef @(spec.short_name)_<ContainerAllocator> Type; |
|
|
|
@# constructors (with and without allocator) |
|
@[for (alloc_type,alloc_name) in [['',''],['const ContainerAllocator& ','_alloc']]]@ |
|
@(spec.short_name)_(@(alloc_type+alloc_name)) |
|
@# Write initializer list |
|
@('\n '.join(gencpp.generate_initializer_list(spec, alloc_name != '' )))@ |
|
{ |
|
@# Fixed length arrays |
|
@('\n '.join(gencpp.generate_fixed_length_assigns(spec, alloc_name != '', '%s::'%(spec.package))))@ |
|
} |
|
@[end for] |
|
|
|
@[for field in spec.parsed_fields()] |
|
@{cpp_type = gencpp.msg_type_to_cpp(field.type)}@ |
|
typedef @(cpp_type) _@(field.name)_type; |
|
_@(field.name)_type @(field.name); |
|
@[end for] |
|
|
|
@# Constants |
|
@[for constant in spec.constants]@ |
|
@[if (constant.type in ['byte', 'int8', 'int16', 'int32', 'int64', 'char'])]@ |
|
enum { @(constant.name) = @(int(constant.val)) }; |
|
@[elif (constant.type in ['uint8', 'uint16', 'uint32', 'uint64'])]@ |
|
enum { @(constant.name) = @(int(constant.val))u }; |
|
@[else]@ |
|
static const @(gencpp.msg_type_to_cpp(constant.type)) @(constant.name); |
|
@[end if]@ |
|
@[end for] |
|
|
|
@# Shared pointer typedefs |
|
typedef boost::shared_ptr< @(cpp_full_name)<ContainerAllocator> > Ptr; |
|
typedef boost::shared_ptr< @(cpp_full_name)<ContainerAllocator> const> ConstPtr; |
|
|
|
}; // struct @(cpp_class) |
|
|
|
@# Typedef of template instance using std::allocator |
|
typedef @(cpp_full_name)<std::allocator<void> > @(spec.short_name); |
|
|
|
@# Shared pointer typedefs |
|
typedef boost::shared_ptr< @(cpp_namespace+spec.short_name) > @(spec.short_name)Ptr; |
|
typedef boost::shared_ptr< @(cpp_namespace+spec.short_name) const> @(spec.short_name)ConstPtr; |
|
|
|
// constants requiring out of line definition |
|
@[for c in spec.constants] |
|
@[if c.type not in ['byte', 'int8', 'int16', 'int32', 'int64', 'char', 'uint8', 'uint16', 'uint32', 'uint64']] |
|
template<typename ContainerAllocator> const @(gencpp.msg_type_to_cpp(c.type)) |
|
@(spec.short_name)_<ContainerAllocator>::@(c.name) = |
|
@[if c.type == 'string'] |
|
"@(gencpp.escape_string(c.val))" |
|
@[elif c.type == 'bool'] |
|
@(int(c.val)) |
|
@[else] |
|
@c.val |
|
@[end if] |
|
; |
|
@[end if] |
|
@[end for] |
|
|
|
|
|
@# Printer |
|
template<typename ContainerAllocator> |
|
std::ostream& operator<<(std::ostream& s, const @(cpp_full_name_with_alloc) & v) |
|
{ |
|
ros::message_operations::Printer< @(cpp_full_name_with_alloc) >::stream(s, "", v); |
|
return s; |
|
} |
|
|
|
@# End of namespace |
|
} // namespace @(spec.package) |
|
|
|
@# Message Traits |
|
namespace ros |
|
{ |
|
namespace message_traits |
|
{ |
|
|
|
@{ |
|
bool_traits = dict(IsMessage=True, |
|
IsFixedSize=gencpp.is_fixed_length(spec, msg_context, search_path), |
|
HasHeader=spec.has_header(), |
|
) |
|
def booltotype(b): |
|
return "TrueType" if b else "FalseType" |
|
} |
|
|
|
// BOOLTRAITS @bool_traits |
|
// @search_path |
|
|
|
@# TODO |
|
// !!!!!!!!!!! @(dir(spec)) |
|
@#if spec.is_fixed_length(): |
|
@# traits = traits.append('IsFixedSize') |
|
|
|
@#template <class ContainerAllocator> |
|
@#struct IsFixedSize<@(cpp_full_name_with_alloc) >:: @(dir(spec)) ? "TrueType" ! "FalseType") { }; |
|
@#template <class ContainerAllocator> |
|
@#struct IsFixedSize<@(cpp_full_name_with_alloc) const >:: @(dir(spec)) ? "TrueType" ! "FalseType") { }; |
|
|
|
@# Binary traits |
|
|
|
@[for k, v in bool_traits.items()]@ |
|
|
|
template <class ContainerAllocator> |
|
struct @(k)< @(cpp_full_name_with_alloc) > |
|
: @(booltotype(v)) |
|
{ }; |
|
|
|
template <class ContainerAllocator> |
|
struct @(k)< @(cpp_full_name_with_alloc) const> |
|
: @(booltotype(v)) |
|
{ }; |
|
@[end for]@ |
|
|
|
@# String traits |
|
@[for trait_class,trait_value in [['MD5Sum', md5sum], ['DataType', spec.full_name], ['Definition', cpp_msg_definition]]]@ |
|
|
|
template<class ContainerAllocator> |
|
struct @(trait_class)< @(cpp_full_name_with_alloc) > |
|
{ |
|
static const char* value() |
|
{ |
|
return "@(trait_value)"; |
|
} |
|
|
|
static const char* value(const @(cpp_full_name_with_alloc)&) { return value(); } |
|
@{ |
|
if trait_class == 'MD5Sum': |
|
iter_count = int(len(trait_value) / 16) |
|
for i in range(0, iter_count): |
|
start = i*16 |
|
print(' static const uint64_t static_value%s = 0x%sULL;'%((i+1), trait_value[start:start+16])) |
|
}@ |
|
}; |
|
@[end for]@ |
|
|
|
@# End of traits |
|
} // namespace message_traits |
|
} // namespace ros |
|
|
|
@# Serialization |
|
namespace ros |
|
{ |
|
namespace serialization |
|
{ |
|
|
|
template<class ContainerAllocator> struct Serializer< @(cpp_full_name_with_alloc) > |
|
{ |
|
@[if spec.parsed_fields()]@ |
|
template<typename Stream, typename T> inline static void allInOne(Stream& stream, T m) |
|
{ |
|
@[for field in spec.parsed_fields()]@ |
|
stream.next(m.@(field.name)); |
|
@[end for]@ |
|
} |
|
@[else]@ |
|
template<typename Stream, typename T> inline static void allInOne(Stream&, T) |
|
{} |
|
@[end if]@ |
|
|
|
ROS_DECLARE_ALLINONE_SERIALIZER; |
|
}; // struct @(cpp_class) |
|
|
|
} // namespace serialization |
|
} // namespace ros |
|
|
|
@# Message Operations |
|
namespace ros |
|
{ |
|
namespace message_operations |
|
{ |
|
|
|
@# Printer operation |
|
template<class ContainerAllocator> |
|
struct Printer< @(cpp_full_name_with_alloc) > |
|
{ |
|
@[if spec.parsed_fields()]@ |
|
template<typename Stream> static void stream(Stream& s, const std::string& indent, const @(cpp_full_name_with_alloc)& v) |
|
{ |
|
@# todo, change this stuff below into proper EmPy syntax |
|
@{ |
|
for field in spec.parsed_fields(): |
|
cpp_type = gencpp.msg_type_to_cpp(field.base_type) |
|
if (field.is_array): |
|
print(' s << indent << "%s[]" << std::endl;'%(field.name)) |
|
print(' for (size_t i = 0; i < v.%s.size(); ++i)'%(field.name)) |
|
print(' {') |
|
print(' s << indent << " %s[" << i << "]: ";'%(field.name)) |
|
indent_increment = ' ' |
|
if (not field.is_builtin): |
|
print(' s << std::endl;') |
|
print(' s << indent;') |
|
indent_increment = ' '; |
|
print(' Printer<%s>::stream(s, indent + "%s", v.%s[i]);'%(cpp_type, indent_increment, field.name)) |
|
print(' }') |
|
else: |
|
print(' s << indent << "%s: ";'%(field.name)) |
|
indent_increment = ' ' |
|
if (not field.is_builtin or field.is_array): |
|
print(' s << std::endl;') |
|
print(' Printer<%s>::stream(s, indent + "%s", v.%s);'%(cpp_type, indent_increment, field.name)) |
|
}@ |
|
} |
|
@[else]@ |
|
template<typename Stream> static void stream(Stream&, const std::string&, const @(cpp_full_name_with_alloc)&) |
|
{} |
|
@[end if]@ |
|
}; |
|
|
|
} // namespace message_operations |
|
} // namespace ros |
|
|
|
#endif // @(spec.package.upper())_MESSAGE_@(spec.short_name.upper())_H
|
|
|