#include <simgear/scene/util/OsgMath.hxx>
#include <simgear/scene/util/parse_color.hxx>
#include <simgear/misc/sg_path.hxx>
+#include <simgear/io/HTTPClient.hxx>
#include <osg/Array>
#include <osg/Geometry>
#include <osg/PrimitiveSet>
-
-#include <boost/algorithm/string/predicate.hpp>
+#include <osgDB/Registry>
namespace simgear
{
}
else if( name == "file" )
{
- static const std::string CANVAS_PROTOCOL = "canvas://";
- const std::string& path = child->getStringValue();
+ static const std::string PROTOCOL_SEP = "://";
+
+ std::string url = child->getStringValue(),
+ protocol, path;
- CanvasPtr canvas = _canvas.lock();
- if( !canvas )
+ size_t sep_pos = url.find(PROTOCOL_SEP);
+ if( sep_pos != std::string::npos )
{
- SG_LOG(SG_GL, SG_ALERT, "canvas::Image: No canvas available");
- return;
+ protocol = url.substr(0, sep_pos);
+ path = url.substr(sep_pos + PROTOCOL_SEP.length());
}
+ else
+ path = url;
- if( boost::starts_with(path, CANVAS_PROTOCOL) )
+ if( protocol == "canvas" )
{
+ CanvasPtr canvas = _canvas.lock();
+ if( !canvas )
+ {
+ SG_LOG(SG_GL, SG_ALERT, "canvas::Image: No canvas available");
+ return;
+ }
+
CanvasMgr* canvas_mgr = canvas->getCanvasMgr();
if( !canvas_mgr )
{
const SGPropertyNode* canvas_node =
canvas_mgr->getPropertyRoot()
->getParent()
- ->getNode( path.substr(CANVAS_PROTOCOL.size()) );
+ ->getNode( path );
if( !canvas_node )
{
SG_LOG(SG_GL, SG_ALERT, "canvas::Image: No such canvas: " << path);
setSrcCanvas(src_canvas);
}
+ else if( protocol == "http" || protocol == "https" )
+ // TODO check https
+ {
+ Canvas::getSystemAdapter()
+ ->getHTTPClient()
+ ->load(url)
+ ->done(this, &Image::handleImageLoadDone);
+ }
else
{
setImage( Canvas::getSystemAdapter()->getImage(path) );
(*_texCoords)[i + 3].set(tl.x(), br.y());
}
+ //----------------------------------------------------------------------------
+ void Image::handleImageLoadDone(HTTP::Request* req)
+ {
+ if( req->responseCode() != 200 )
+ {
+ SG_LOG( SG_GL,
+ SG_WARN,
+ "canvas::Image: failed to download '" << req->url() << "': "
+ << req->responseReason() );
+ return;
+ }
+
+ std::string ext = SGPath(req->path()).extension();
+ SG_LOG(SG_GL, SG_INFO, "canvas::Image: received " << req->url());
+
+ osgDB::ReaderWriter* rw =
+ osgDB::Registry::instance()->getReaderWriterForExtension(ext);
+
+ std::istringstream img_data(
+ static_cast<HTTP::MemoryRequest*>(req)->responseBody()
+ );
+
+ osgDB::ReaderWriter::ReadResult result = rw->readImage(img_data);
+ if( result.success() )
+ setImage( result.takeImage() );
+ else
+ SG_LOG( SG_GL,
+ SG_WARN,
+ "canvas::Image: failed to read image '" << req->url() << "': "
+ << result.message() );
+ }
+
} // namespace canvas
} // namespace simgear
#include <simgear/structure/SGSharedPtr.hxx>
#include <simgear/math/sg_types.hxx>
+#include <boost/bind.hpp>
#include <boost/function.hpp>
class SGPropertyNode;
*/
Request* done(const Callback& cb);
+ template<class C>
+ Request* done(C* instance, void (C::*mem_func)(Request*))
+ {
+ return done(boost::bind(mem_func, instance, _1));
+ }
+
/**
* Set the handler to be called when the request completes or aborts with an
* error.
*/
Request* fail(const Callback& cb);
+ template<class C>
+ Request* fail(C* instance, void (C::*mem_func)(Request*))
+ {
+ return fail(boost::bind(mem_func, instance, _1));
+ }
+
/**
* Set the handler to be called when the request either successfully
* completes or fails.
*/
Request* always(const Callback& cb);
+ template<class C>
+ Request* always(C* instance, void (C::*mem_func)(Request*))
+ {
+ return always(boost::bind(mem_func, instance, _1));
+ }
+
/**
* Set the data for the body of the request. The request is automatically
* send using the POST method.