root/OpenSceneGraph/trunk/src/osgPlugins/RestHttpDevice/RestHttpDevice.hpp @ 13429

Revision 13429, 7.9 kB (checked in by robert, 9 hours ago)

Fixed rendering of Popups

  • Property svn:executable set to *
Line 
1/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
2 *
3 * This library is open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 * OpenSceneGraph Public License for more details.
12*/
13
14
15#pragma once
16
17#include <osg/Referenced>
18#include <OpenThreads/Thread>
19#include <osgGA/Device>
20#include "server.hpp"
21
22class RestHttpDevice : public osgGA::Device, OpenThreads::Thread {
23
24public:
25   
26    class RequestHandler : public osg::Referenced {
27    public:
28        typedef std::map<std::string, std::string> Arguments;
29        RequestHandler(const std::string& request_path)
30            : osg::Referenced()
31            , _requestPath(request_path)
32            , _device(NULL)
33        {
34        }
35       
36        virtual bool operator()(const std::string& request_path, const std::string& full_request_path, const Arguments& arguments, http::server::reply& reply) = 0;
37       
38        const std::string& getRequestPath() const { return _requestPath; }
39       
40        virtual void describeTo(std::ostream& out) const
41        {
42            out << getRequestPath() << ": no description available";
43        }
44       
45    protected:
46        void setDevice(RestHttpDevice* device) { _device = device; }
47        RestHttpDevice* getDevice() { return _device; }
48       
49        void reportMissingArgument(const std::string& argument, http::server::reply& reply) const
50        {
51            OSG_WARN << "RequestHandler :: missing argument '" << argument << "' for " << getRequestPath() << std::endl;
52            reply.content = "{ \"result\": 0, \"error\": \"missing argument '"+argument+"'\"}";
53            reply.status = http::server::reply::ok;
54        }
55       
56        bool sendOkReply(http::server::reply& reply)
57        {
58            if (reply.content.empty())
59            {
60                reply.status = http::server::reply::no_content;
61            }
62            return true;
63        }
64       
65        bool getStringArgument(const Arguments& arguments, const std::string& argument, http::server::reply& reply, std::string& result) const
66        {
67            Arguments::const_iterator itr = arguments.find(argument);
68            if (itr == arguments.end()) {
69                reportMissingArgument(argument, reply);
70                return false;
71            }
72            result = itr->second;
73            return true;
74        }
75       
76        bool getHexArgument(const Arguments& arguments, const std::string& argument, http::server::reply& reply, int& value) const
77        {
78            std::string hex_str;
79            if (!getStringArgument(arguments, argument, reply, hex_str))
80                return false;
81            value = strtoul(hex_str.c_str(), NULL, 16);
82            return true;
83        }
84       
85        bool getIntArgument(const Arguments& arguments, const std::string& argument, http::server::reply& reply, int& value) const
86        {
87            std::string str;
88            if (!getStringArgument(arguments, argument, reply, str))
89                return false;
90            value = strtol(str.c_str(), NULL, 10);
91            return true;
92        }
93       
94        bool getDoubleArgument(const Arguments& arguments, const std::string& argument, http::server::reply& reply, double& value) const
95        {
96            std::string str;
97            if (!getStringArgument(arguments, argument, reply, str))
98                return false;
99            value = strtod(str.c_str(), NULL);
100            return true;
101        }
102       
103        /// set the request-path, works only from the constructor
104        void setRequestPath(const std::string& request_path) { _requestPath = request_path; }
105    protected:
106       
107        double getTimeStamp(const Arguments& arguments, http::server::reply& reply)
108        {
109            double time_stamp(0.0);
110            getDoubleArgument(arguments, "time", reply, time_stamp);
111            return time_stamp;
112        }
113       
114        double getLocalTime(const Arguments& arguments, http::server::reply& reply)
115        {
116            return getLocalTime(getTimeStamp(arguments, reply));
117        }
118       
119        double getLocalTime(double time_stamp)
120        {
121            return getDevice()->getLocalTime(time_stamp);
122        }
123       
124    private:
125        std::string _requestPath;
126        RestHttpDevice* _device;
127    friend class RestHttpDevice;
128    };
129   
130   
131    typedef std::multimap<std::string, osg::ref_ptr<RequestHandler> > RequestHandlerMap;
132   
133    RestHttpDevice(const std::string& listening_address, const std::string& listening_port, const std::string& doc_path);
134    ~RestHttpDevice();
135   
136    void addRequestHandler(RequestHandler* handler);
137   
138    bool handleRequest(const std::string& request_path,  http::server::reply& reply);
139   
140    virtual void run();
141   
142    void describeTo(std::ostream& out) const;
143   
144    friend std::ostream& operator<<(std::ostream& out, const RestHttpDevice& device)
145    {
146        device.describeTo(out);
147        return out;
148    }
149   
150    double getLocalTime(double time_stamp)
151    {
152        if (_firstEventRemoteTimeStamp < 0)
153        {
154            _firstEventLocalTimeStamp = getEventQueue()->getTime();
155            _firstEventRemoteTimeStamp = time_stamp;
156        }
157        double local_time = _firstEventLocalTimeStamp + (time_stamp - _firstEventRemoteTimeStamp);
158        // std::cout << "ts: "<< time_stamp << " -> " << local_time << std::endl;
159        return  local_time;
160    }
161   
162    bool isNewer(double time_stamp)
163    {
164        bool is_newer(time_stamp > _lastEventRemoteTimeStamp);
165        if (is_newer)
166            _lastEventRemoteTimeStamp = time_stamp;
167        return is_newer;
168    }
169   
170
171   
172    virtual bool checkEvents()
173    {
174        if ((fabs(_currentMouseX - _targetMouseY) > 0.1f) || (fabs(_currentMouseY - _targetMouseY) > 0.1))
175        {
176            static const float scalar = 0.2f;
177            _currentMouseX = (1.0f - scalar) * _currentMouseX + scalar * _targetMouseX;
178            _currentMouseY = (1.0f - scalar) * _currentMouseY + scalar * _targetMouseY;
179            getEventQueue()->mouseMotion(_currentMouseX, _currentMouseY, getEventQueue()->getTime());
180        }
181        return !(getEventQueue()->empty());
182    }
183   
184    void setTargetMousePosition(float x, float y, bool force = false)
185    {
186        _targetMouseX = x; _targetMouseY = y;
187        if (force) {
188            _currentMouseX = x; _currentMouseY = y;
189        }
190    }
191   
192   
193   
194private:
195    void parseArguments(const std::string request_path, RequestHandler::Arguments& arguments);
196    http::server::server _server;
197    RequestHandlerMap _map;
198    std::string _serverAddress, _serverPort, _documentRoot;
199    double _firstEventLocalTimeStamp;
200    double _firstEventRemoteTimeStamp;
201    double _lastEventRemoteTimeStamp;
202    float _currentMouseX, _currentMouseY, _targetMouseX, _targetMouseY;
203   
204};
205
206
207
208class SendKeystrokeRequestHandler : public RestHttpDevice::RequestHandler {
209public:
210    SendKeystrokeRequestHandler(const std::string& request_path, int key) : RestHttpDevice::RequestHandler(request_path), _key(key) {}
211   
212    virtual bool operator()(const std::string& request_path, const std::string& full_request_path, const Arguments& arguments, http::server::reply& reply)
213    {
214        double local_time = getLocalTime(arguments, reply);
215       
216        getDevice()->getEventQueue()->keyPress(_key, local_time);
217        getDevice()->getEventQueue()->keyRelease(_key, local_time);
218       
219        return sendOkReply(reply);
220    }
221   
222    virtual void describeTo(std::ostream& out) const
223    {
224        out << getRequestPath() << ": send KEY_DOWN + KEY_UP, code: 0x" << std::hex << _key << std::dec;
225    }
226private:
227    int _key;
228};
Note: See TracBrowser for help on using the browser.