|
From: <br...@us...> - 2009-03-19 04:19:33
|
Revision: 3846
http://openvrml.svn.sourceforge.net/openvrml/?rev=3846&view=rev
Author: braden
Date: 2009-03-19 04:19:27 +0000 (Thu, 19 Mar 2009)
Log Message:
-----------
Created a convenience library libopenvrml-control to hold the platform-independent parts of the OpenVRML control (which is currently called openvrml-xembed).
Modified Paths:
--------------
trunk/ChangeLog
trunk/src/Makefile.am
trunk/src/openvrml-xembed/browser.cpp
trunk/src/openvrml-xembed/plugin_streambuf.h
Added Paths:
-----------
trunk/src/libopenvrml-control/
trunk/src/libopenvrml-control/openvrml_control/
trunk/src/libopenvrml-control/openvrml_control/browser.cpp
trunk/src/libopenvrml-control/openvrml_control/browser.h
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2009-03-19 04:07:16 UTC (rev 3845)
+++ trunk/ChangeLog 2009-03-19 04:19:27 UTC (rev 3846)
@@ -1,3 +1,73 @@
+2009-03-19 Braden McDaniel <br...@en...>
+
+ Created a convenience library libopenvrml-control to hold the
+ platform-independent parts of the OpenVRML control (which is
+ currently called openvrml-xembed).
+
+ * src/Makefile.am
+ (noinst_LTLIBRARIES): Added convenience library
+ libopenvrml-control.
+ (libopenvrml_control_libopenvrml_control_la_SOURCES):
+ libopenvrml-control sources.
+ (libopenvrml_control_libopenvrml_control_la_CPPFLAGS):
+ libopenvrml-control CPPFLAGS.
+ (libopenvrml_control_libopenvrml_control_la_LIBADD): Depends on
+ libopenvrml.
+ (openvrml_xembed_openvrml_xembed_CPPFLAGS): Added
+ libopenvrml-control to include path.
+ (openvrml_xembed_openvrml_xembed_LDADD): Depends on
+ libopenvrml-control.
+ * src/libopenvrml-control/openvrml_control/browser.cpp: Added
+ file. openvrml_control::browser encapsulates a browser "control".
+ * src/libopenvrml-control/openvrml_control/browser.h: Added
+ file. openvrml_control::browser encapsulates a browser "control".
+ * src/openvrml-xembed/browser.cpp
+ (resource_fetcher): Moved to
+ src/libopenvrml-control/openvrml_control/browser.cpp.
+ (browser_host_proxy): Added; implements
+ openvrml_control::browser_host.
+ (OpenvrmlXembedBrowserPrivate_): Added browser_control_host_proxy
+ and browser_control; removed resource_fetcher, browser,
+ browser_initialized_mutex, uninitialized_streambuf_map,
+ streambuf_map, initial_stream_reader_thread, got_initial_stream,
+ and browser_initialized. The removed members have been moved
+ to (or have equivalents in) openvrml_control::browser.
+ (initial_stream_reader): Moved to
+ src/libopenvrml-control/openvrml_control/browser.cpp.
+ (openvrml_xembed_browser_constructor(GType, guint,
+ GObjectConstructParam *)): Initialize the browser_control and
+ browser_control_host_proxy members; removed initialization of
+ removed members.
+ (openvrml_xembed_browser_finalize(GObject *)): Removed cleanup of
+ removed members; delete browser_control and
+ browser_control_host_proxy.
+ (openvrml_xembed_browser_new_stream(OpenvrmlXembedStreamClient *,
+ guint64, const char *, const char *, GError **)): Delegate to
+ openvrml_control::browser::new_stream.
+ (openvrml_xembed_browser_destroy_stream(OpenvrmlXembedStreamClient *,
+ guint64, GError **)): Delegate to
+ openvrml_control::browser::destroy_stream.
+ (openvrml_xembed_browser_write(OpenvrmlXembedStreamClient *,
+ guint64, const GArray *, GError **)): Delegate to
+ openvrml_control::browser::write.
+ (load_url): Moved to
+ src/libopenvrml-control/openvrml_control/browser.cpp.
+ (openvrml_xembed_browser_load_url(OpenvrmlXembedBrowser *, const
+ gchar **, const gchar **, GError **)): Delegate to
+ openvrml_control::browser::load_uri.
+ (openvrml_xembed_browser_get_world_url(OpenvrmlXembedBrowser *,
+ GError **)): Delegate to openvrml_control::browser::world_url.
+ (openvrml_xembed_browser_initialized(OpenvrmlXembedBrowser *)):
+ Delegate to openvrml_control::browser::initialized.
+ (browser_listener::do_browser_changed(const
+ openvrml::browser_event &)): Don't set browser_initialized; this
+ is now taken care of inside openvrml_control::browser.
+ (GtkGLViewer::GtkGLViewer(OpenvrmlXembedBrowserPlug &)): Call
+ openvrml_control::browser::viewer.
+ * src/openvrml-xembed/plugin_streambuf.h
+ (openvrml_xembed::plugin_streambuf): Grant friendship to
+ openvrml_control::browser.
+
2009-03-18 Braden McDaniel <br...@en...>
Newer jni.h is more const-correct; play along.
Modified: trunk/src/Makefile.am
===================================================================
--- trunk/src/Makefile.am 2009-03-19 04:07:16 UTC (rev 3845)
+++ trunk/src/Makefile.am 2009-03-19 04:19:27 UTC (rev 3846)
@@ -721,6 +721,7 @@
libopenvrml_gl_libopenvrml_gl_la_LIBADD = libopenvrml/libopenvrml.la
if ENABLE_XEMBED
+noinst_LTLIBRARIES = libopenvrml-control/libopenvrml-control.la
libexec_PROGRAMS = openvrml-xembed/openvrml-xembed
session_bus_servicesdir = $(datadir)/dbus-1/services
session_bus_services_DATA = openvrml-xembed/org.openvrml.BrowserControl.service
@@ -729,8 +730,20 @@
openvrml-xembed/browser-factory-server-glue.h \
openvrml-xembed/browser-host-client-glue.h
endif
+libopenvrml_control_libopenvrml_control_la_SOURCES = \
+ libopenvrml-control/openvrml_control/browser.cpp \
+ libopenvrml-control/openvrml_control/browser.h
+libopenvrml_control_libopenvrml_control_la_CPPFLAGS = \
+ -I$(top_srcdir)/src/openvrml-xembed \
+ -I$(top_builddir)/src/libopenvrml \
+ -I$(top_srcdir)/src/libopenvrml
+libopenvrml_control_libopenvrml_control_la_LIBADD = \
+ libopenvrml/libopenvrml.la
+
openvrml_xembed_openvrml_xembed_CPPFLAGS = \
-I$(top_builddir)/src/openvrml-xembed \
+ -I$(top_srcdir)/src/openvrml-xembed \
+ -I$(top_srcdir)/src/libopenvrml-control \
-I$(top_builddir)/src/libopenvrml \
-I$(top_srcdir)/src/libopenvrml \
-I$(top_builddir)/src/libopenvrml-gl \
@@ -753,6 +766,7 @@
$(DBUS_G_LIBS) \
$(GTKGL_LIBS)
openvrml_xembed_openvrml_xembed_LDADD = \
+ libopenvrml-control/libopenvrml-control.la \
libopenvrml-gl/libopenvrml-gl.la
openvrml_xembed_datadir = $(datadir)/openvrml-xembed
Added: trunk/src/libopenvrml-control/openvrml_control/browser.cpp
===================================================================
--- trunk/src/libopenvrml-control/openvrml_control/browser.cpp (rev 0)
+++ trunk/src/libopenvrml-control/openvrml_control/browser.cpp 2009-03-19 04:19:27 UTC (rev 3846)
@@ -0,0 +1,366 @@
+// -*- mode: c++; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 78 -*-
+//
+// OpenVRML Control
+//
+// Copyright 2009 Braden N. McDaniel
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3 of the License, or (at your option)
+// any later version.
+//
+// This program is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+// more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; if not, see <http://www.gnu.org/licenses/>.
+//
+
+# include "browser.h"
+# include <openvrml/browser.h>
+# include <boost/lexical_cast.hpp>
+# include <iostream>
+
+openvrml_control::unknown_stream::unknown_stream(const std::string & uri):
+ std::logic_error("no stream corresponding to URI: " + uri)
+{}
+
+openvrml_control::unknown_stream::unknown_stream(const uint64_t stream_id):
+ std::logic_error("no stream corresponding to stream ID: "
+ + boost::lexical_cast<std::string>(stream_id))
+{}
+
+openvrml_control::unknown_stream::~unknown_stream() throw ()
+{}
+
+openvrml_control::browser::resource_fetcher::
+resource_fetcher(browser_host & control_host,
+ openvrml_xembed::uninitialized_plugin_streambuf_map &
+ uninitialized_plugin_streambuf_map,
+ openvrml_xembed::plugin_streambuf_map & plugin_streambuf_map):
+ control_host_(control_host),
+ uninitialized_plugin_streambuf_map_(uninitialized_plugin_streambuf_map),
+ plugin_streambuf_map_(plugin_streambuf_map)
+{}
+
+openvrml_control::browser::resource_fetcher::~resource_fetcher()
+ OPENVRML_NOTHROW
+{
+ this->thread_group_.join_all();
+}
+
+void
+openvrml_control::browser::resource_fetcher::
+create_thread(const boost::function0<void> & threadfunc)
+{
+ this->thread_group_.create_thread(threadfunc);
+}
+
+std::auto_ptr<openvrml::resource_istream>
+openvrml_control::browser::resource_fetcher::
+do_get_resource(const std::string & uri)
+{
+ using openvrml_xembed::plugin_streambuf;
+
+ class plugin_resource_istream : public openvrml::resource_istream {
+ const boost::shared_ptr<plugin_streambuf> streambuf_;
+ resource_fetcher & resource_fetcher_;
+
+ public:
+ plugin_resource_istream(const std::string & uri,
+ resource_fetcher & fetcher):
+ openvrml::resource_istream(0),
+ streambuf_(
+ new plugin_streambuf(
+ uri,
+ fetcher.uninitialized_plugin_streambuf_map_,
+ fetcher.plugin_streambuf_map_)),
+ resource_fetcher_(fetcher)
+ {
+ this->rdbuf(this->streambuf_.get());
+ fetcher.uninitialized_plugin_streambuf_map_.insert(
+ uri, this->streambuf_);
+
+ //
+ // browser_host::get_url could throw; let it.
+ //
+ const int get_url_result = fetcher.control_host_.get_url(uri);
+
+ if (get_url_result != 0) {
+ this->setstate(ios_base::badbit);
+ }
+ this->streambuf_->set_get_url_result(get_url_result);
+ }
+
+ private:
+ virtual const std::string do_url() const OPENVRML_NOTHROW
+ {
+ return this->streambuf_->url();
+ }
+
+ virtual const std::string do_type() const OPENVRML_NOTHROW
+ {
+ return this->streambuf_->type();
+ }
+
+ virtual bool do_data_available() const OPENVRML_NOTHROW
+ {
+ return this->streambuf_->data_available();
+ }
+ };
+ return std::auto_ptr<openvrml::resource_istream>(
+ new plugin_resource_istream(uri, *this));
+}
+
+openvrml_control::browser::browser_listener::browser_listener(browser & b):
+ browser_(b)
+{}
+
+void
+openvrml_control::browser::browser_listener::
+do_browser_changed(const openvrml::browser_event & event)
+{
+ switch (event.id()) {
+ case openvrml::browser_event::initialized:
+ {
+ boost::mutex::scoped_lock lock(this->browser_.initialized_mutex_);
+ this->browser_.initialized_ = true;
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+namespace {
+ //
+ // We don't already know what the URI of the initial stream is until we
+ // start getting that data from the browser. This is a placeholder that
+ // is used to identify the plugin_streambuf that will be used to receive
+ // the initial stream data.
+ //
+ const char initial_stream_uri[] = "x-openvrml-initial:";
+
+ struct OPENVRML_LOCAL initial_stream_reader {
+ initial_stream_reader(
+ const boost::shared_ptr<openvrml_xembed::plugin_streambuf> &
+ streambuf,
+ openvrml::browser & browser):
+ streambuf_(streambuf),
+ browser_(browser)
+ {}
+
+ void operator()() const throw ()
+ {
+ using openvrml_xembed::plugin_streambuf;
+
+ class plugin_istream : public openvrml::resource_istream {
+ boost::shared_ptr<plugin_streambuf> streambuf_;
+
+ public:
+ explicit plugin_istream(
+ const boost::shared_ptr<plugin_streambuf> & streambuf):
+ openvrml::resource_istream(streambuf.get()),
+ streambuf_(streambuf)
+ {}
+
+ virtual ~plugin_istream() throw ()
+ {}
+
+ private:
+ virtual const std::string do_url() const throw (std::bad_alloc)
+ {
+ return this->streambuf_->url();
+ }
+
+ virtual const std::string do_type() const
+ throw (std::bad_alloc)
+ {
+ return this->streambuf_->type();
+ }
+
+ virtual bool do_data_available() const throw ()
+ {
+ return this->streambuf_->data_available();
+ }
+ } in(this->streambuf_);
+
+ this->browser_.set_world(in);
+ }
+
+ private:
+ boost::shared_ptr<openvrml_xembed::plugin_streambuf> streambuf_;
+ openvrml::browser & browser_;
+ };
+}
+
+openvrml_control::browser::browser(browser_host & host,
+ const bool expect_initial_stream):
+ fetcher_(host,
+ this->uninitialized_streambuf_map_,
+ this->streambuf_map_),
+ listener_(*this),
+ browser_(this->fetcher_, std::cout, std::cerr),
+ host_(host),
+ expect_initial_stream_(expect_initial_stream),
+ got_initial_stream_(false)
+{
+ this->browser_.add_listener(this->listener_);
+
+ //
+ // If necessary, create the initial stream.
+ //
+ if (expect_initial_stream) {
+ using boost::function0;
+ using boost::shared_ptr;
+ using openvrml_xembed::plugin_streambuf;
+
+ const shared_ptr<plugin_streambuf> initial_stream(
+ new plugin_streambuf(::initial_stream_uri,
+ this->uninitialized_streambuf_map_,
+ this->streambuf_map_));
+ initial_stream->state_ = plugin_streambuf::uninitialized;
+ this->uninitialized_streambuf_map_.insert(::initial_stream_uri,
+ initial_stream);
+
+ const function0<void> initial_stream_reader_func =
+ initial_stream_reader(initial_stream, this->browser_);
+
+ this->initial_stream_reader_thread_.reset(
+ new boost::thread(initial_stream_reader_func));
+ }
+}
+
+openvrml_control::browser::~browser() OPENVRML_NOTHROW
+{
+ if (this->expect_initial_stream_) {
+ this->initial_stream_reader_thread_->join();
+ }
+ this->browser_.remove_listener(this->listener_);
+}
+
+bool openvrml_control::browser::initialized() const
+{
+ boost::mutex::scoped_lock lock(this->initialized_mutex_);
+ return this->initialized_;
+}
+
+void openvrml_control::browser::new_stream(const uint64_t stream_id,
+ const std::string & type,
+ const std::string & uri)
+ OPENVRML_THROW1(unknown_stream)
+{
+ using namespace openvrml_xembed;
+ using boost::shared_ptr;
+
+ shared_ptr<plugin_streambuf> streambuf =
+ this->uninitialized_streambuf_map_.find(uri);
+
+ if (!streambuf) {
+ if (!this->got_initial_stream_) {
+ assert(this->uninitialized_streambuf_map_.size() == 1);
+ streambuf = this->uninitialized_streambuf_map_.front();
+ this->got_initial_stream_ = true;
+ } else {
+ throw unknown_stream(uri);
+ }
+ }
+ assert(streambuf->state() != plugin_streambuf::initialized);
+ streambuf->init(stream_id, uri, type);
+}
+
+void openvrml_control::browser::destroy_stream(const uint64_t stream_id)
+ OPENVRML_THROW1(unknown_stream)
+{
+ using namespace openvrml_xembed;
+ using boost::shared_ptr;
+
+ const shared_ptr<plugin_streambuf> streambuf =
+ this->streambuf_map_.find(stream_id);
+ if (!streambuf) { throw unknown_stream(stream_id); }
+ streambuf->buf_.set_eof();
+ this->streambuf_map_.erase(stream_id);
+}
+
+void openvrml_control::browser::write(const uint64_t stream_id,
+ const unsigned char * const data,
+ const size_t size)
+ OPENVRML_THROW1(unknown_stream)
+{
+ using namespace openvrml_xembed;
+ using boost::shared_ptr;
+
+ const shared_ptr<plugin_streambuf> streambuf =
+ this->streambuf_map_.find(stream_id);
+ if (!streambuf) { throw unknown_stream(stream_id); }
+ for (size_t i = 0; i < size; ++i) { streambuf->buf_.put(data[i]); }
+}
+
+struct OPENVRML_LOCAL openvrml_control::browser::load_url {
+ load_url(browser & b,
+ const std::vector<std::string> & url,
+ const std::vector<std::string> & parameter):
+ browser_(b),
+ url_(url),
+ parameter_(parameter)
+ {}
+
+ void operator()() const OPENVRML_NOTHROW
+ {
+ try {
+ {
+ boost::mutex::scoped_lock
+ lock(this->browser_.initialized_mutex_);
+ this->browser_.initialized_ = false;
+ }
+ this->browser_.browser_.load_url(this->url_, this->parameter_);
+ } catch (std::exception & ex) {
+ this->browser_.browser_.err(ex.what());
+ }
+ }
+
+ private:
+ browser & browser_;
+ const std::vector<std::string> url_, parameter_;
+};
+
+void
+openvrml_control::browser::load_uri(const std::vector<std::string> & uri,
+ const std::vector<std::string> & parameter)
+ OPENVRML_THROW2(boost::thread_resource_error, std::bad_alloc)
+{
+ this->fetcher_.create_thread(load_url(*this, uri, parameter));
+}
+
+const std::string openvrml_control::browser::world_url()
+{
+ return this->browser_.world_url();
+}
+
+bool
+openvrml_control::browser::add_listener(openvrml::browser_listener & listener)
+{
+ return this->browser_.add_listener(listener);
+}
+
+bool
+openvrml_control::browser::
+remove_listener(openvrml::browser_listener & listener)
+{
+ return this->browser_.remove_listener(listener);
+}
+
+void openvrml_control::browser::viewer(openvrml::viewer * v)
+{
+ this->browser_.viewer(v);
+}
+
+openvrml_control::browser_host::~browser_host()
+{}
+
+int openvrml_control::browser_host::get_url(const std::string & url)
+{
+ this->do_get_url(url);
+}
Property changes on: trunk/src/libopenvrml-control/openvrml_control/browser.cpp
___________________________________________________________________
Added: svn:eol-style
+ native
Added: trunk/src/libopenvrml-control/openvrml_control/browser.h
===================================================================
--- trunk/src/libopenvrml-control/openvrml_control/browser.h (rev 0)
+++ trunk/src/libopenvrml-control/openvrml_control/browser.h 2009-03-19 04:19:27 UTC (rev 3846)
@@ -0,0 +1,123 @@
+// -*- mode: c++; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 78 -*-
+//
+// OpenVRML Control
+//
+// Copyright 2009 Braden N. McDaniel
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3 of the License, or (at your option)
+// any later version.
+//
+// This program is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+// more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; if not, see <http://www.gnu.org/licenses/>.
+//
+
+# ifndef OPENVRML_CONTROL_BROWSER_H
+# define OPENVRML_CONTROL_BROWSER_H
+
+# include "plugin_streambuf.h"
+# include <openvrml/browser.h>
+
+namespace openvrml_control {
+
+ class unknown_stream : public std::logic_error {
+ public:
+ explicit unknown_stream(const std::string & uri);
+ explicit unknown_stream(uint64_t stream_id);
+ virtual ~unknown_stream() throw ();
+ };
+
+ class browser_host;
+
+ class browser {
+ struct load_url;
+
+ class resource_fetcher : public openvrml::resource_fetcher {
+ browser_host & control_host_;
+ openvrml_xembed::uninitialized_plugin_streambuf_map &
+ uninitialized_plugin_streambuf_map_;
+ openvrml_xembed::plugin_streambuf_map & plugin_streambuf_map_;
+ boost::thread_group thread_group_;
+
+ public:
+ resource_fetcher(
+ browser_host & control_host,
+ openvrml_xembed::uninitialized_plugin_streambuf_map &
+ uninitialized_plugin_streambuf_map,
+ openvrml_xembed::plugin_streambuf_map & plugin_streambuf_map);
+ virtual ~resource_fetcher() OPENVRML_NOTHROW;
+
+ void create_thread(const boost::function0<void> & threadfunc);
+
+ private:
+ virtual std::auto_ptr<openvrml::resource_istream>
+ do_get_resource(const std::string & uri);
+ };
+
+ class browser_listener : public openvrml::browser_listener {
+ browser & browser_;
+
+ public:
+ explicit browser_listener(browser & b);
+
+ private:
+ virtual void
+ do_browser_changed(const openvrml::browser_event & event);
+ };
+
+ openvrml_xembed::uninitialized_plugin_streambuf_map
+ uninitialized_streambuf_map_;
+ openvrml_xembed::plugin_streambuf_map streambuf_map_;
+ resource_fetcher fetcher_;
+ browser_listener listener_;
+ openvrml::browser browser_;
+ browser_host & host_;
+ boost::scoped_ptr<boost::thread> initial_stream_reader_thread_;
+ bool expect_initial_stream_, got_initial_stream_;
+ mutable boost::mutex initialized_mutex_;
+ bool initialized_;
+
+ public:
+ browser(browser_host & host, bool expect_initial_stream);
+ ~browser() OPENVRML_NOTHROW;
+
+ bool initialized() const;
+
+ void new_stream(uint64_t stream_id,
+ const std::string & type, const std::string & uri)
+ OPENVRML_THROW1(unknown_stream);
+ void destroy_stream(uint64_t stream_id)
+ OPENVRML_THROW1(unknown_stream);
+ void write(uint64_t stream_id, const unsigned char * data, size_t size)
+ OPENVRML_THROW1(unknown_stream);
+
+ void load_uri(const std::vector<std::string> & uri,
+ const std::vector<std::string> & parameter)
+ OPENVRML_THROW2(boost::thread_resource_error, std::bad_alloc);
+ const std::string world_url();
+
+ bool add_listener(openvrml::browser_listener & listener);
+ bool remove_listener(openvrml::browser_listener & listener);
+
+ void viewer(openvrml::viewer * v);
+ };
+
+
+ class browser_host {
+ public:
+ virtual ~browser_host() = 0;
+
+ int get_url(const std::string & url);
+
+ private:
+ virtual int do_get_url(const std::string & url) = 0;
+ };
+}
+
+# endif // ifndef OPENVRML_CONTROL_BROWSER_H
Property changes on: trunk/src/libopenvrml-control/openvrml_control/browser.h
___________________________________________________________________
Added: svn:eol-style
+ native
Modified: trunk/src/openvrml-xembed/browser.cpp
===================================================================
--- trunk/src/openvrml-xembed/browser.cpp 2009-03-19 04:07:16 UTC (rev 3845)
+++ trunk/src/openvrml-xembed/browser.cpp 2009-03-19 04:19:27 UTC (rev 3846)
@@ -18,21 +18,17 @@
// with this library; if not, see <http://www.gnu.org/licenses/>.
//
-# include <iostream>
-# include <sstream>
# include <boost/multi_index/detail/scope_guard.hpp>
// Must include before X11 headers.
# include <boost/numeric/conversion/converter.hpp>
-# include <boost/ptr_container/ptr_map.hpp>
# include <X11/keysym.h>
# include <dbus/dbus-glib.h>
# include <gdk/gdkx.h>
-# include <openvrml/browser.h>
+# include <openvrml_control/browser.h>
# include <openvrml/gl/viewer.h>
# include "browser.h"
# include "browser-server-glue.h"
# include "browser-host-client-glue.h"
-# include "plugin_streambuf.h"
# include <gtk/gtkgl.h>
# include <gtk/gtkdrawingarea.h>
@@ -73,54 +69,59 @@
openvrml_xembed_browser_stream_client_interface_init))
namespace {
- class G_GNUC_INTERNAL resource_fetcher : public openvrml::resource_fetcher {
- DBusGProxy & control_host_;
- openvrml_xembed::uninitialized_plugin_streambuf_map &
- uninitialized_plugin_streambuf_map_;
- openvrml_xembed::plugin_streambuf_map & plugin_streambuf_map_;
- boost::thread_group thread_group_;
+ class G_GNUC_INTERNAL browser_listener : public openvrml::browser_listener {
+ OpenvrmlXembedBrowser & browser_;
+
public:
- resource_fetcher(
- DBusGProxy & control_host,
- openvrml_xembed::uninitialized_plugin_streambuf_map &
- uninitialized_plugin_streambuf_map,
- openvrml_xembed::plugin_streambuf_map & plugin_streambuf_map);
- virtual ~resource_fetcher() OPENVRML_NOTHROW;
+ explicit browser_listener(OpenvrmlXembedBrowser & browser);
- void create_thread(const boost::function0<void> & threadfunc);
-
private:
- virtual std::auto_ptr<openvrml::resource_istream>
- do_get_resource(const std::string & uri);
+ virtual void do_browser_changed(const openvrml::browser_event & event);
};
- class G_GNUC_INTERNAL browser_listener : public openvrml::browser_listener {
- OpenvrmlXembedBrowser & browser_;
+ class G_GNUC_INTERNAL browser_host_proxy :
+ public openvrml_control::browser_host {
+
+ DBusGProxy & host_;
+
public:
- explicit browser_listener(OpenvrmlXembedBrowser & browser);
+ explicit browser_host_proxy(DBusGProxy & host):
+ host_(host)
+ {}
private:
- virtual void do_browser_changed(const openvrml::browser_event & event);
+ virtual int do_get_url(const std::string & url)
+ {
+ GError * error = 0;
+ scope_guard error_guard = make_guard(g_error_free, boost::ref(error));
+ gint result = -1;
+ gboolean succeeded =
+ org_openvrml_BrowserHost_get_url(&this->host_,
+ url.c_str(),
+ &result,
+ &error);
+ if (!succeeded) {
+ throw std::invalid_argument(error->message);
+ }
+
+ error_guard.dismiss();
+
+ return result;
+ }
};
}
struct OpenvrmlXembedBrowserPrivate_ {
DBusGProxy * control_host;
- ::resource_fetcher * resource_fetcher;
- openvrml::browser * browser;
+ browser_host_proxy * browser_control_host_proxy;
+ openvrml_control::browser * browser_control;
browser_listener * listener;
OpenvrmlXembedBrowserPlug * browser_plug;
GMutex * browser_plug_mutex;
GCond * browser_plug_set_cond;
- GMutex * browser_initialized_mutex;
- openvrml_xembed::uninitialized_plugin_streambuf_map * uninitialized_streambuf_map;
- openvrml_xembed::plugin_streambuf_map * streambuf_map;
- boost::thread * initial_stream_reader_thread;
bool expect_initial_stream;
- bool got_initial_stream;
- bool browser_initialized;
};
# define OPENVRML_XEMBED_BROWSER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), OPENVRML_XEMBED_TYPE_BROWSER, OpenvrmlXembedBrowserPrivate))
@@ -207,68 +208,6 @@
&dbus_glib_openvrml_xembed_browser_object_info);
}
-namespace {
- //
- // We don't already know what the URI of the initial stream is until we
- // start getting that data from the browser. This is a placeholder that
- // is used to identify the plugin_streambuf that will be used to receive
- // the initial stream data.
- //
- const char initial_stream_uri[] = "x-openvrml-initial:";
-
- struct OPENVRML_LOCAL initial_stream_reader {
- initial_stream_reader(
- const boost::shared_ptr<openvrml_xembed::plugin_streambuf> &
- streambuf,
- openvrml::browser & browser):
- streambuf_(streambuf),
- browser_(browser)
- {}
-
- void operator()() const throw ()
- {
- using openvrml_xembed::plugin_streambuf;
-
- class plugin_istream : public openvrml::resource_istream {
- boost::shared_ptr<plugin_streambuf> streambuf_;
-
- public:
- explicit plugin_istream(
- const boost::shared_ptr<plugin_streambuf> & streambuf):
- openvrml::resource_istream(streambuf.get()),
- streambuf_(streambuf)
- {}
-
- virtual ~plugin_istream() throw ()
- {}
-
- private:
- virtual const std::string do_url() const throw (std::bad_alloc)
- {
- return this->streambuf_->url();
- }
-
- virtual const std::string do_type() const
- throw (std::bad_alloc)
- {
- return this->streambuf_->type();
- }
-
- virtual bool do_data_available() const throw ()
- {
- return this->streambuf_->data_available();
- }
- } in(this->streambuf_);
-
- this->browser_.set_world(in);
- }
-
- private:
- boost::shared_ptr<openvrml_xembed::plugin_streambuf> streambuf_;
- openvrml::browser & browser_;
- };
-}
-
GObject *
openvrml_xembed_browser_constructor(
GType type,
@@ -289,54 +228,21 @@
try {
OpenvrmlXembedBrowser * const browser = OPENVRML_XEMBED_BROWSER(obj);
- browser->priv->uninitialized_streambuf_map =
- new openvrml_xembed::uninitialized_plugin_streambuf_map;
- browser->priv->streambuf_map =
- new openvrml_xembed::plugin_streambuf_map;
- browser->priv->resource_fetcher =
- new resource_fetcher(*browser->priv->control_host,
- *browser->priv->uninitialized_streambuf_map,
- *browser->priv->streambuf_map);
- browser->priv->browser =
- new openvrml::browser(*browser->priv->resource_fetcher,
- std::cout,
- std::cerr);
+ browser->priv->browser_control_host_proxy =
+ new browser_host_proxy(*browser->priv->control_host);
+ browser->priv->browser_control =
+ new openvrml_control::browser(
+ *browser->priv->browser_control_host_proxy,
+ browser->priv->expect_initial_stream);
browser->priv->listener = new browser_listener(*browser);
- browser->priv->browser->add_listener(*browser->priv->listener);
+ browser->priv->browser_control->add_listener(*browser->priv->listener);
browser->priv->browser_plug = 0;
browser->priv->browser_plug_mutex = g_mutex_new();
browser->priv->browser_plug_set_cond = g_cond_new();
-
- browser->priv->browser_initialized = false;
- browser->priv->browser_initialized_mutex = g_mutex_new();
-
- //
- // If necessary, create the initial stream.
- //
- if (browser->priv->expect_initial_stream) {
- using boost::function0;
- using boost::shared_ptr;
- using openvrml_xembed::plugin_streambuf;
-
- const shared_ptr<plugin_streambuf> initial_stream(
- new plugin_streambuf(
- ::initial_stream_uri,
- *browser->priv->uninitialized_streambuf_map,
- *browser->priv->streambuf_map));
- initial_stream->state_ = plugin_streambuf::uninitialized;
- browser->priv->uninitialized_streambuf_map
- ->insert(::initial_stream_uri, initial_stream);
-
- const function0<void> initial_stream_reader_func =
- initial_stream_reader(initial_stream, *browser->priv->browser);
-
- browser->priv->initial_stream_reader_thread =
- new boost::thread(initial_stream_reader_func);
- }
} catch (std::exception & ex) {
//
- // ex is most likely std::bad_alloc or boost::thread_resource_error.
+ // ex is most likely std::bad_alloc.
//
g_critical("%s", ex.what());
return 0;
@@ -347,21 +253,12 @@
void openvrml_xembed_browser_finalize(GObject * const obj)
{
OpenvrmlXembedBrowser * const browser = OPENVRML_XEMBED_BROWSER(obj);
-
- if (browser->priv->expect_initial_stream) {
- browser->priv->initial_stream_reader_thread->join();
- delete browser->priv->initial_stream_reader_thread;
- }
-
- g_mutex_free(browser->priv->browser_initialized_mutex);
g_cond_free(browser->priv->browser_plug_set_cond);
g_mutex_free(browser->priv->browser_plug_mutex);
- browser->priv->browser->remove_listener(*browser->priv->listener);
+ browser->priv->browser_control->remove_listener(*browser->priv->listener);
delete browser->priv->listener;
- delete browser->priv->browser;
- delete browser->priv->resource_fetcher;
- delete browser->priv->streambuf_map;
- delete browser->priv->uninitialized_streambuf_map;
+ delete browser->priv->browser_control;
+ delete browser->priv->browser_control_host_proxy;
}
void openvrml_xembed_browser_set_property(GObject * const obj,
@@ -458,28 +355,15 @@
OpenvrmlXembedBrowser * const browser =
OPENVRML_XEMBED_BROWSER(stream_client);
- shared_ptr<plugin_streambuf> streambuf =
- browser->priv->uninitialized_streambuf_map->find(url);
-
- if (!streambuf) {
- if (!browser->priv->got_initial_stream) {
- g_assert(
- browser->priv->uninitialized_streambuf_map->size() == 1);
- streambuf =
- browser->priv->uninitialized_streambuf_map->front();
- browser->priv->got_initial_stream = true;
- } else {
- g_set_error(
- error,
- OPENVRML_XEMBED_ERROR,
- OPENVRML_XEMBED_ERROR_UNKNOWN_STREAM,
- "Attempt to create a stream that has not been requested: %s",
- url);
- return false;
- }
+ try {
+ browser->priv->browser_control->new_stream(stream_id, type, url);
+ } catch (const openvrml_control::unknown_stream & ex) {
+ g_set_error(error,
+ OPENVRML_XEMBED_ERROR,
+ OPENVRML_XEMBED_ERROR_UNKNOWN_STREAM,
+ ex.what());
+ return false;
}
- g_assert(streambuf->state() != plugin_streambuf::initialized);
- streambuf->init(stream_id, url, type);
return true;
}
@@ -495,19 +379,15 @@
OpenvrmlXembedBrowser * const browser =
OPENVRML_XEMBED_BROWSER(stream_client);
- const shared_ptr<plugin_streambuf> streambuf =
- browser->priv->streambuf_map->find(stream_id);
- if (!streambuf) {
- g_set_error(
- error,
- OPENVRML_XEMBED_ERROR,
- OPENVRML_XEMBED_ERROR_UNKNOWN_STREAM,
- "Attempt to destroy a nonexistent stream: %lu",
- stream_id);
+ try {
+ browser->priv->browser_control->destroy_stream(stream_id);
+ } catch (const openvrml_control::unknown_stream & ex) {
+ g_set_error(error,
+ OPENVRML_XEMBED_ERROR,
+ OPENVRML_XEMBED_ERROR_UNKNOWN_STREAM,
+ ex.what());
return false;
}
- streambuf->buf_.set_eof();
- browser->priv->streambuf_map->erase(stream_id);
return true;
}
@@ -523,52 +403,20 @@
OpenvrmlXembedBrowser * const browser =
OPENVRML_XEMBED_BROWSER(stream_client);
- const shared_ptr<plugin_streambuf> streambuf =
- browser->priv->streambuf_map->find(stream_id);
- if (!streambuf) {
- g_set_error(
- error,
- OPENVRML_XEMBED_ERROR,
- OPENVRML_XEMBED_ERROR_UNKNOWN_STREAM,
- "Attempt to write to a nonexistent stream: %lu",
- stream_id);
- return false;
+ try {
+ browser->priv->browser_control->write(
+ stream_id,
+ reinterpret_cast<unsigned char *>(data->data),
+ data->len);
+ } catch (const openvrml_control::unknown_stream & ex) {
+ g_set_error(error,
+ OPENVRML_XEMBED_ERROR,
+ OPENVRML_XEMBED_ERROR_UNKNOWN_STREAM,
+ ex.what());
}
- for (size_t i = 0; i < data->len; ++i) {
- streambuf->buf_.put(g_array_index(data, unsigned char, i));
- }
return true;
}
-namespace {
- struct G_GNUC_INTERNAL load_url {
- load_url(OpenvrmlXembedBrowser & browser,
- const std::vector<std::string> & url,
- const std::vector<std::string> & parameter):
- browser_(browser),
- url_(url),
- parameter_(parameter)
- {}
-
- void operator()() const OPENVRML_NOTHROW
- {
- try {
- g_mutex_lock(this->browser_.priv->browser_initialized_mutex);
- this->browser_.priv->browser_initialized = false;
- g_mutex_unlock(this->browser_.priv->browser_initialized_mutex);
- this->browser_.priv->browser->load_url(this->url_,
- this->parameter_);
- } catch (std::exception & ex) {
- this->browser_.priv->browser->err(ex.what());
- }
- }
-
- private:
- OpenvrmlXembedBrowser & browser_;
- const std::vector<std::string> url_, parameter_;
- };
-}
-
gboolean
openvrml_xembed_browser_load_url(OpenvrmlXembedBrowser * const vrml_browser,
const gchar ** url,
@@ -583,8 +431,7 @@
while (url && *url) { url_vec.push_back(*(url++)); }
while (parameter && *parameter) { param_vec.push_back(*(parameter++)); }
- vrml_browser->priv->resource_fetcher
- ->create_thread(load_url(*vrml_browser, url_vec, param_vec));
+ vrml_browser->priv->browser_control->load_uri(url_vec, param_vec);
} catch (const std::bad_alloc & ex) {
*error = g_error_new(OPENVRML_XEMBED_ERROR,
OPENVRML_XEMBED_ERROR_NO_MEMORY,
@@ -653,19 +500,16 @@
gchar *
openvrml_xembed_browser_get_world_url(
- OpenvrmlXembedBrowser * const vrml_browser,
+ OpenvrmlXembedBrowser * const browser,
GError ** /* error */)
{
- return g_strdup(vrml_browser->priv->browser->world_url().c_str());
+ return g_strdup(browser->priv->browser_control->world_url().c_str());
}
gboolean
openvrml_xembed_browser_initialized(OpenvrmlXembedBrowser * const browser)
{
- g_mutex_lock(browser->priv->browser_initialized_mutex);
- const bool browser_initialized = browser->priv->browser_initialized;
- g_mutex_unlock(browser->priv->browser_initialized_mutex);
- return browser_initialized;
+ return browser->priv->browser_control->initialized();
}
@@ -1249,104 +1093,6 @@
namespace {
- resource_fetcher::resource_fetcher(
- DBusGProxy & control_host,
- openvrml_xembed::uninitialized_plugin_streambuf_map &
- uninitialized_plugin_streambuf_map,
- openvrml_xembed::plugin_streambuf_map & plugin_streambuf_map):
- control_host_(control_host),
- uninitialized_plugin_streambuf_map_(uninitialized_plugin_streambuf_map),
- plugin_streambuf_map_(plugin_streambuf_map)
- {}
-
- resource_fetcher::~resource_fetcher() OPENVRML_NOTHROW
- {
- this->thread_group_.join_all();
- }
-
- void
- resource_fetcher::create_thread(const boost::function0<void> & threadfunc)
- {
- this->thread_group_.create_thread(threadfunc);
- }
-
- std::auto_ptr<openvrml::resource_istream>
- resource_fetcher::do_get_resource(const std::string & uri)
- {
- using openvrml_xembed::plugin_streambuf;
-
- class plugin_resource_istream : public openvrml::resource_istream {
- const boost::shared_ptr<plugin_streambuf> streambuf_;
- resource_fetcher & resource_fetcher_;
-
- public:
- plugin_resource_istream(const std::string & uri,
- resource_fetcher & fetcher):
- openvrml::resource_istream(0),
- streambuf_(
- new plugin_streambuf(
- uri,
- fetcher.uninitialized_plugin_streambuf_map_,
- fetcher.plugin_streambuf_map_)),
- resource_fetcher_(fetcher)
- {
- using std::ostringstream;
- using boost::ref;
-
- this->rdbuf(this->streambuf_.get());
- fetcher.uninitialized_plugin_streambuf_map_
- .insert(uri, this->streambuf_);
-
- //
- // We're in a thread started by libopenvrml here. By using
- // dbus_g_proxy_begin_call here (instead of dbus_g_proxy_call),
- // we finish the call in the main thread. That's important
- // because we want to make sure this call "finishes" before
- // we execute the host's successive NewStream call.
- //
- GError * error = 0;
- scope_guard error_guard = make_guard(g_error_free,
- boost::ref(error));
- gint get_url_result = -1;
- gboolean succeeded =
- org_openvrml_BrowserHost_get_url(&fetcher.control_host_,
- uri.c_str(),
- &get_url_result,
- &error);
- if (!succeeded) {
- g_critical(error->message);
- this->setstate(ios_base::badbit);
- return;
- }
-
- if (get_url_result != 0) {
- this->setstate(ios_base::badbit);
- }
- this->streambuf_->set_get_url_result(get_url_result);
-
- error_guard.dismiss();
- }
-
- private:
- virtual const std::string do_url() const throw ()
- {
- return this->streambuf_->url();
- }
-
- virtual const std::string do_type() const throw ()
- {
- return this->streambuf_->type();
- }
-
- virtual bool do_data_available() const throw ()
- {
- return this->streambuf_->data_available();
- }
- };
- return std::auto_ptr<openvrml::resource_istream>(
- new plugin_resource_istream(uri, *this));
- }
-
browser_listener::browser_listener(OpenvrmlXembedBrowser & browser):
browser_(browser)
{}
@@ -1357,10 +1103,6 @@
switch (event.id()) {
case openvrml::browser_event::initialized:
g_signal_emit(&this->browser_, signals[initialized_id], 0);
-
- g_mutex_lock(this->browser_.priv->browser_initialized_mutex);
- this->browser_.priv->browser_initialized = true;
- g_mutex_unlock(this->browser_.priv->browser_initialized_mutex);
break;
case openvrml::browser_event::shutdown:
g_signal_emit(&this->browser_, signals[shutdown_id], 0);
@@ -1374,7 +1116,7 @@
browser_plug_(browser_plug),
timer(0)
{
- this->browser_plug_.priv->browser->priv->browser->viewer(this);
+ this->browser_plug_.priv->browser->priv->browser_control->viewer(this);
}
GtkGLViewer::~GtkGLViewer() throw ()
Modified: trunk/src/openvrml-xembed/plugin_streambuf.h
===================================================================
--- trunk/src/openvrml-xembed/plugin_streambuf.h 2009-03-19 04:07:16 UTC (rev 3845)
+++ trunk/src/openvrml-xembed/plugin_streambuf.h 2009-03-19 04:19:27 UTC (rev 3846)
@@ -28,8 +28,11 @@
# include <boost/enable_shared_from_this.hpp>
# include <openvrml/read_write_mutex.h>
# include "bounded_buffer.h"
-# include "browser.h"
+namespace openvrml_control {
+ class browser;
+}
+
namespace openvrml_xembed {
//
@@ -86,20 +89,7 @@
public boost::enable_shared_from_this<plugin_streambuf>,
public std::streambuf {
- friend
- GObject *
- (::openvrml_xembed_browser_constructor)(
- GType type,
- guint n_construct_properties,
- GObjectConstructParam * construct_properties);
- friend
- gboolean
- (::openvrml_xembed_browser_destroy_stream)(OpenvrmlXembedStreamClient *,
- guint64, GError **);
- friend
- gboolean
- (::openvrml_xembed_browser_write)(OpenvrmlXembedStreamClient *, guint64,
- const GArray *, GError **);
+ friend class openvrml_control::browser;
public:
enum state_id {
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|