JsonFactory.h 8.28 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 7
#include "utilities.h"

8
#include "ros_bridge/include/MessageTraits.h"
9
#include "ros_bridge/include/MessageGroups.h"
10
#include "ros_bridge/include/GenericMessages.h"
11 12 13 14

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

15 16
namespace ROSBridge {

17 18 19
class StdHeaderPolicy;

//!
20
//! \brief The JsonFactory class is used to create ROS messages.
21
//!
22 23 24
//! 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.
25
template <class HeaderPolicy = StdHeaderPolicy>
Valentin Platzgummer's avatar
Valentin Platzgummer committed
26
class GenericJsonFactory : public HeaderPolicy
27
{
28
    typedef MessageBaseClass ROSMsg;
29 30
public:

Valentin Platzgummer's avatar
Valentin Platzgummer committed
31
    GenericJsonFactory() : HeaderPolicy() {}
32 33 34 35 36 37

    //!
    //! \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
38 39
    //! not derived from \class MessageBaseClass.
    //! \param msg Instance of a \class MessageBaseClass subclass belonging to a ROSMessageGroup.
40 41 42
    //! \return rapidjson::Document document containing a ROS message.
    template <class T>
    rapidjson::Document *create(const T &msg){
43 44
        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,
45
                "msg belongs to group EmptyGroup (not allowed). Please specify Group (typedef MessageGroup Group)");
46
        //cout << T::Group::label() << endl;
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
        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>
65 66
    rapidjson::Document *_create(const U &msg, Type2Type<MessageGroups::Point32Group>){
        using namespace ROSBridge;
67
        rapidjson::Document *doc = new rapidjson::Document(rapidjson::kObjectType);
68
        bool ret = JsonMethodes::GeometryMsgs::Point32::toJson<_Float32>(msg, *doc, doc->GetAllocator());
69 70 71 72 73 74 75 76 77 78
        assert(ret);
        (void)ret;

        return doc;
    }

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

        return doc;
    }

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

        return doc;
    }

    // ===========================================================================
    // PolygonStampedGroup
    // ===========================================================================
    template<class U>
107 108 109
    rapidjson::Document *_create(const U &msg, Type2Type<MessageGroups::PolygonStampedGroup>){
        using namespace ROSBridge;
        using namespace ROSBridge::traits;
110 111 112 113 114 115 116
        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.
117
        using namespace ROSBridge;
118
        rapidjson::Document *doc = new rapidjson::Document(rapidjson::kObjectType);
119
        bool ret = JsonMethodes::GeometryMsgs::PolygonStamped::toJson(msg, *doc, doc->GetAllocator());
120 121 122 123 124 125 126 127 128
        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.
129
        using namespace ROSBridge;
Valentin Platzgummer's avatar
Valentin Platzgummer committed
130
        GenericMessages::StdMsgs::Header header(HeaderPolicy::header(msg));
131
        rapidjson::Document *doc = new rapidjson::Document(rapidjson::kObjectType);
132
        bool ret = JsonMethodes::GeometryMsgs::PolygonStamped::toJson(msg.polygon(), header, *doc, doc->GetAllocator());
133 134 135 136 137 138 139 140 141 142
        assert(ret);
        (void)ret;

        return doc;
    }

    // ===========================================================================
    // PolygonArrayGroup
    // ===========================================================================
    template<class U>
143 144 145
    rapidjson::Document *_create(const U &msg, Type2Type<MessageGroups::PolygonArrayGroup>){
        using namespace ROSBridge;
        using namespace ROSBridge::traits;
146 147 148 149 150 151 152
        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.
153
        using namespace ROSBridge;
154
        rapidjson::Document *doc = new rapidjson::Document(rapidjson::kObjectType);
Valentin Platzgummer's avatar
Valentin Platzgummer committed
155
        bool ret = JsonMethodes::JSKRecognitionMsgs::PolygonArray::toJson(msg, *doc, doc->GetAllocator());
156 157 158 159 160 161 162 163 164
        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.
165
        using namespace ROSBridge;
Valentin Platzgummer's avatar
Valentin Platzgummer committed
166
       GenericMessages::StdMsgs::Header header(HeaderPolicy::header(msg));
167
        rapidjson::Document *doc = new rapidjson::Document(rapidjson::kObjectType);
Valentin Platzgummer's avatar
Valentin Platzgummer committed
168
        bool ret = JsonMethodes::JSKRecognitionMsgs::PolygonArray::toJson(msg, header, *doc, doc->GetAllocator());
169 170 171 172 173 174
        assert(ret);
        (void)ret;

        return doc;
    }

175 176 177 178 179 180 181 182 183 184
    // ===========================================================================
    // ProgressGroup
    // ===========================================================================
    template<class U>
    rapidjson::Document *_create(const U &msg, Type2Type<MessageGroups::ProgressGroup>){
        using namespace ROSBridge;
        rapidjson::Document *doc = new rapidjson::Document(rapidjson::kObjectType);
        bool ret = JsonMethodes::NemoMsgs::Progress::toJson(msg, *doc, doc->GetAllocator());
        assert(ret);
        (void)ret;
185

186 187
        return doc;
    }
188 189
};

Valentin Platzgummer's avatar
Valentin Platzgummer committed
190 191 192 193
class StdHeaderPolicy
{
    typedef ROSBridge::GenericMessages::StdMsgs::Header Header;
    typedef ROSBridge::GenericMessages::StdMsgs::Time Time;
194 195 196 197 198 199 200
public:
    StdHeaderPolicy():_seq(-1){};

    //!
    //! \brief header Returns the header belonging to msg.
    //! \return Returns the header belonging to msg.
    //!
Valentin Platzgummer's avatar
Valentin Platzgummer committed
201 202
    Header header(const ROSBridge::MessageBaseClass &msg) {
        return Header(++_seq, time(msg), "/map");
203 204 205 206 207 208
    }


    //!
    //! \brief time Returns the current time.
    //! \return Returns the current time.
Valentin Platzgummer's avatar
Valentin Platzgummer committed
209
    Time time(const ROSBridge::MessageBaseClass &msg) {
210
        (void)msg;
Valentin Platzgummer's avatar
Valentin Platzgummer committed
211
        return Time(0,0);
212
    }
Valentin Platzgummer's avatar
Valentin Platzgummer committed
213

214 215 216 217
private:
    long _seq;
};

Valentin Platzgummer's avatar
Valentin Platzgummer committed
218 219
typedef GenericJsonFactory<> JsonFactory;

220 221 222
} // end namespace ros_bridge