JsonFactory.h 7.51 KB
Newer Older
1
#pragma once
2 3

#include "ros_bridge/rapidjson/include/rapidjson/document.h"
4 5
#include "ros_bridge/include/JsonMethodes.h"
#include "MessageBaseClass.h"
6
#include "utilities.h"
7
#include "ros_bridge/include/MessageTraits.h"
8

9
#include "ros_bridge/include/MessageGroups.h"
10 11 12 13

#include "boost/type_traits.hpp"
#include "boost/type_traits/is_base_of.hpp"

14 15
namespace ROSBridge {

16 17 18
class StdHeaderPolicy;

//!
19
//! \brief The JsonFactory class is used to create ROS messages.
20
//!
21 22 23 24 25
//! The JsonFactory class is used to create \class rapidjson::Document documents containing ROS messages
//! from classes derived from \class MessageBaseClass. Each class has a group mark (typedef ... Group) which allows the
//! JsonFactory to determine the ROS message type it will create.
template <class StringType = std::string, class HeaderPolicy = StdHeaderPolicy>
class JsonFactory : public HeaderPolicy
26
{
27
    typedef MessageBaseClass<StringType> ROSMsg;
28 29
public:

30
    JsonFactory(){}
31 32 33 34 35 36

    //!
    //! \brief Creates a \class rapidjson::Document document containing a ROS mesage from \p msg.
    //!
    //! Creates a \class rapidjson::Document document containing a ROS message from \p msg.
    //! A compile-time error will occur, if \p msg belongs to the \struct EmptyGroup or is
37 38
    //! not derived from \class MessageBaseClass.
    //! \param msg Instance of a \class MessageBaseClass subclass belonging to a ROSMessageGroup.
39 40 41
    //! \return rapidjson::Document document containing a ROS message.
    template <class T>
    rapidjson::Document *create(const T &msg){
42 43
        static_assert(boost::is_base_of<ROSMsg, T>::value, "Type of msg must be derived from MessageBaseClass.");
        static_assert(!::boost::is_same<typename T::Group, MessageGroups::EmptyGroup>::value,
44
                "msg belongs to group EmptyGroup (not allowed). Please specify Group (typedef MessageGroup Group)");
45
        //cout << T::Group::label() << endl;
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
        return _create(msg, Type2Type<typename T::Group>());
    }

private:

    // ===========================================================================
    // EmptyGroup and not implemented Groups
    // ===========================================================================
    template<class U, class V>
    rapidjson::Document *_create(const U &msg, Type2Type<V>){
        (void)msg;
        assert(false); // Implementation missing for group U::Group!
    }

    // ===========================================================================
    // Point32Group
    // ===========================================================================
    template<class U>
64 65
    rapidjson::Document *_create(const U &msg, Type2Type<MessageGroups::Point32Group>){
        using namespace ROSBridge;
66
        rapidjson::Document *doc = new rapidjson::Document(rapidjson::kObjectType);
67
        bool ret = JsonMethodes::Point32::toJson<_Float32>(msg, *doc, doc->GetAllocator());
68 69 70 71 72 73 74 75 76 77
        assert(ret);
        (void)ret;

        return doc;
    }

    // ===========================================================================
    // GeoPointGroup
    // ===========================================================================
    template<class U>
78 79
    rapidjson::Document *_create(const U &msg, Type2Type<MessageGroups::GeoPointGroup>){
        using namespace ROSBridge;
80
        rapidjson::Document *doc = new rapidjson::Document(rapidjson::kObjectType);
81
        bool ret = JsonMethodes::GeoPoint::toJson(msg, *doc, doc->GetAllocator());
82 83 84 85 86 87 88 89 90 91
        assert(ret);
        (void)ret;

        return doc;
    }

    // ===========================================================================
    // PolygonGroup
    // ===========================================================================
    template<class U>
92 93
    rapidjson::Document *_create(const U &msg, Type2Type<MessageGroups::PolygonGroup>){
        using namespace ROSBridge;
94
        rapidjson::Document *doc = new rapidjson::Document(rapidjson::kObjectType);
95
        bool ret = JsonMethodes::Polygon::toJson(msg, *doc, doc->GetAllocator());
96 97 98 99 100 101 102 103 104 105
        assert(ret);
        (void)ret;

        return doc;
    }

    // ===========================================================================
    // PolygonStampedGroup
    // ===========================================================================
    template<class U>
106 107 108
    rapidjson::Document *_create(const U &msg, Type2Type<MessageGroups::PolygonStampedGroup>){
        using namespace ROSBridge;
        using namespace ROSBridge::traits;
109 110 111 112 113 114 115
        typedef HasMemberHeader<U> HasHeader;

        return _createPolygonStamped(msg, Int2Type<HasHeader::value>());
    }

    template<class U, int k>
    rapidjson::Document *_createPolygonStamped(const U &msg, Int2Type<k>){ // U has member header(), use integraded header.
116
        using namespace ROSBridge;
117
        rapidjson::Document *doc = new rapidjson::Document(rapidjson::kObjectType);
118
        bool ret = JsonMethodes::PolygonStamped::toJson(msg, *doc, doc->GetAllocator());
119 120 121 122 123 124 125 126 127
        assert(ret);
        (void)ret;

        return doc;

    }

    template<class U>
    rapidjson::Document *_createPolygonStamped(const U &msg, Int2Type<0>){// U has no member header(), generate one on the fly.
128 129
        using namespace ROSBridge;
        JsonMethodes::Header::Header header(HeaderPolicy::header(msg));
130
        rapidjson::Document *doc = new rapidjson::Document(rapidjson::kObjectType);
131
        bool ret = JsonMethodes::PolygonStamped::toJson(msg, header, *doc, doc->GetAllocator());
132 133 134 135 136 137 138 139 140 141
        assert(ret);
        (void)ret;

        return doc;
    }

    // ===========================================================================
    // PolygonArrayGroup
    // ===========================================================================
    template<class U>
142 143 144
    rapidjson::Document *_create(const U &msg, Type2Type<MessageGroups::PolygonArrayGroup>){
        using namespace ROSBridge;
        using namespace ROSBridge::traits;
145 146 147 148 149 150 151
        typedef HasMemberHeader<U> HasHeader;

        return _createPolygonArray(msg, Int2Type<HasHeader::value>());
    }

    template<class U, int k>
    rapidjson::Document *_createPolygonArray(const U &msg, Int2Type<k>){ // U has member header(), use integraded header.
152
        using namespace ROSBridge;
153
        rapidjson::Document *doc = new rapidjson::Document(rapidjson::kObjectType);
154
        bool ret = JsonMethodes::PolygonArray::toJson(msg, *doc, doc->GetAllocator());
155 156 157 158 159 160 161 162 163
        assert(ret);
        (void)ret;

        return doc;

    }

    template<class U>
    rapidjson::Document *_createPolygonArray(const U &msg, Int2Type<0>){// U has no member header(), generate one on the fly.
164 165
        using namespace ROSBridge;
        JsonMethodes::Header::Header header(HeaderPolicy::header(msg));
166
        rapidjson::Document *doc = new rapidjson::Document(rapidjson::kObjectType);
167
        bool ret = JsonMethodes::PolygonArray::toJson(msg, header, *doc, doc->GetAllocator());
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
        assert(ret);
        (void)ret;

        return doc;
    }


};

class StdHeaderPolicy{
public:
    StdHeaderPolicy():_seq(-1){};

    //!
    //! \brief header Returns the header belonging to msg.
    //! \return Returns the header belonging to msg.
    //!
    template<typename T>
186 187
        ROSBridge::JsonMethodes::Header::Header header(const T&msg) {
        return ROSBridge::JsonMethodes::Header::Header(++_seq, time(msg), "/map");
188 189 190 191 192 193 194
    }


    //!
    //! \brief time Returns the current time.
    //! \return Returns the current time.
    template<typename T>
195
    ROSBridge::JsonMethodes::Time::Time time(const T&msg) {
196
        (void)msg;
197
        return ROSBridge::JsonMethodes::Time::Time(0,0);
198 199 200 201 202
    }
private:
    long _seq;
};

203 204 205
} // end namespace ros_bridge