From: Lars Gullik Bjønnes Date: Sun, 26 May 2002 13:02:17 +0000 (+0000) Subject: add the boost signals librarys source files, and compile the libboostsignals.la library X-Git-Tag: 1.6.10~19208 X-Git-Url: https://git.lyx.org/gitweb/?a=commitdiff_plain;h=6352b88f9fb252d8acc14f155a22dea87d9a229d;p=features.git add the boost signals librarys source files, and compile the libboostsignals.la library git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@4209 a592a061-630c-0410-9148-cb99ea01b6c8 --- diff --git a/ChangeLog b/ChangeLog index 4baf5a97f5..7f4959396b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2002-05-26 Lars Gullik Bjønnes + + * configure.in: add the boost::signals makefiles. + 2002-05-26 Michael Koziarski * configure.in: gtkconfig.patch diff --git a/boost/ChangeLog b/boost/ChangeLog index af24a5fee9..3b8df45d9f 100644 --- a/boost/ChangeLog +++ b/boost/ChangeLog @@ -1,3 +1,18 @@ +2002-05-26 Lars Gullik Bjønnes + + * libs/signals/Makefile.am: new file + * libs/signals/.cvsignore: ditto + * libs/signals/src/.cvsignore: ditto + * libs/signals/src/Makefile.am: ditto + * libs/signals/src/connection.cpp: ditto + * libs/signals/src/signal_base.cpp: ditto + * libs/signals/src/slot.cpp: ditto + * libs/signals/src/trackable.cpp: ditto + + * libs/regex/src/.cvsignore: add libboostregex.la + + * libs/Makefile.am (SUBDIRS): add signals + 2002-05-24 Lars Gullik Bjønnes * libs/regex/src/Makefile.am (libboostregex_la_SOURCES): add a diff --git a/boost/libs/Makefile.am b/boost/libs/Makefile.am index c200c53387..b8bc3cc3e5 100644 --- a/boost/libs/Makefile.am +++ b/boost/libs/Makefile.am @@ -1,3 +1,3 @@ include $(top_srcdir)/config/common.am -SUBDIRS = regex +SUBDIRS = regex signals diff --git a/boost/libs/regex/src/.cvsignore b/boost/libs/regex/src/.cvsignore index 282522db03..5318b15474 100644 --- a/boost/libs/regex/src/.cvsignore +++ b/boost/libs/regex/src/.cvsignore @@ -1,2 +1,3 @@ Makefile Makefile.in +libboostregex.la diff --git a/boost/libs/signals/.cvsignore b/boost/libs/signals/.cvsignore new file mode 100644 index 0000000000..282522db03 --- /dev/null +++ b/boost/libs/signals/.cvsignore @@ -0,0 +1,2 @@ +Makefile +Makefile.in diff --git a/boost/libs/signals/Makefile.am b/boost/libs/signals/Makefile.am new file mode 100644 index 0000000000..c677165dc7 --- /dev/null +++ b/boost/libs/signals/Makefile.am @@ -0,0 +1,4 @@ +include $(top_srcdir)/config/common.am + +SUBDIRS = src + diff --git a/boost/libs/signals/src/.cvsignore b/boost/libs/signals/src/.cvsignore new file mode 100644 index 0000000000..ce8671c3cb --- /dev/null +++ b/boost/libs/signals/src/.cvsignore @@ -0,0 +1,3 @@ +Makefile +Makefile.in +libboostsignals.la diff --git a/boost/libs/signals/src/Makefile.am b/boost/libs/signals/src/Makefile.am new file mode 100644 index 0000000000..079f0c7df8 --- /dev/null +++ b/boost/libs/signals/src/Makefile.am @@ -0,0 +1,11 @@ +include $(top_srcdir)/config/common.am + +noinst_LTLIBRARIES = libboostsignals.la + +INCLUDES = $(BOOST_INCLUDES) + +libboostsignals_la_SOURCES = \ + connection.cpp \ + signal_base.cpp \ + slot.cpp \ + trackable.cpp diff --git a/boost/libs/signals/src/connection.cpp b/boost/libs/signals/src/connection.cpp new file mode 100644 index 0000000000..c1233e8b9a --- /dev/null +++ b/boost/libs/signals/src/connection.cpp @@ -0,0 +1,53 @@ +// Boost.Signals library +// +// Copyright (C) 2001 Doug Gregor (gregod@cs.rpi.edu) +// +// Permission to copy, use, sell and distribute this software is granted +// provided this copyright notice appears in all copies. +// Permission to modify the code and to distribute modified code is granted +// provided this copyright notice appears in all copies, and a notice +// that the code was modified is included with the copyright notice. +// +// This software is provided "as is" without express or implied warranty, +// and with no claim as to its suitability for any purpose. + +// For more information, see http://www.boost.org + +#include +#include + +namespace boost { + namespace signals { + void connection::disconnect() const + { + if (this->connected()) { + // Make sure we have a reference to the basic_connection object, + // because 'this' may disappear + shared_ptr local_con = con; + + void (*signal_disconnect)(void*, void*) = local_con->signal_disconnect; + + // Note that this connection no longer exists + // Order is important here: we could get into an infinite loop if this + // isn't cleared before we try the disconnect. + local_con->signal_disconnect = 0; + + // Disconnect signal + signal_disconnect(local_con->signal, local_con->signal_data); + + // Disconnect all bound objects + typedef std::list::iterator iterator; + for (iterator i = local_con->bound_objects.begin(); + i != local_con->bound_objects.end(); ++i) { + assert(i->disconnect); + i->disconnect(i->obj, i->data); + } + } + } + } // end namespace boost +} // end namespace boost + +#ifndef BOOST_MSVC +// Explicit instantiations to keep everything in the library +template class std::list; +#endif diff --git a/boost/libs/signals/src/signal_base.cpp b/boost/libs/signals/src/signal_base.cpp new file mode 100644 index 0000000000..fe839127b0 --- /dev/null +++ b/boost/libs/signals/src/signal_base.cpp @@ -0,0 +1,236 @@ +// Boost.Signals library +// +// Copyright (C) 2001 Doug Gregor (gregod@cs.rpi.edu) +// +// Permission to copy, use, sell and distribute this software is granted +// provided this copyright notice appears in all copies. +// Permission to modify the code and to distribute modified code is granted +// provided this copyright notice appears in all copies, and a notice +// that the code was modified is included with the copyright notice. +// +// This software is provided "as is" without express or implied warranty, +// and with no claim as to its suitability for any purpose. + +// For more information, see http://www.boost.org + +#include +#include + +namespace boost { + namespace signals { + namespace detail { + signal_base_impl::signal_base_impl(const compare_type& comp) : + call_depth(0), + slots(comp) + { + flags.delayed_disconnect = false; + flags.clearing = false; + } + + signal_base_impl::~signal_base_impl() + { + // Set the "clearing" flag to ignore extraneous disconnect requests, + // because all slots will be disconnected on destruction anyway. + flags.clearing = true; + } + + void signal_base_impl::disconnect_all_slots() + { + // Do nothing if we're already clearing the slot list + if (flags.clearing) + return; + + if (call_depth == 0) { + // Clearing the slot list will disconnect all slots automatically + temporarily_set_clearing set_clearing(this); + slots.clear(); + } + else { + // We can't actually remove elements from the slot list because there + // are still iterators into the slot list that must not be + // invalidated by this operation. So just disconnect each slot + // without removing it from the slot list. When the call depth does + // reach zero, the call list will be cleared. + flags.delayed_disconnect = true; + temporarily_set_clearing set_clearing(this); + for (slot_iterator i = slots.begin(); i != slots.end(); ++i) { + i->second.first.disconnect(); + } + } + } + + connection + signal_base_impl:: + connect_slot(const any& slot, + const any& name, + const std::vector& bound_objects) + { + // Allocate storage for a new basic_connection object to represent the + // connection + basic_connection* con = new basic_connection(); + + // Create a new connection handle object and place the basic_connection + // object we just created under its control. Note that the "reset" + // routine will delete con if allocation throws. + connection slot_connection; + slot_connection.reset(con); + + // Allocate storage for an iterator that will hold the point of + // insertion of the slot into the list. This is used to later remove + // the slot when it is disconnected. + std::auto_ptr saved_iter(new slot_iterator()); + + // Add the slot to the list. + + slot_iterator pos = + slots.insert(stored_slot_type(name, + connection_slot_pair(slot_connection, + slot))); + + // Make the copy of the connection in the list disconnect when it is + // destroyed + pos->second.first.set_controlling(); + + // The assignment operation here absolutely must not throw, which + // intuitively makes sense (because any container's insert method + // becomes impossible to use in an exception-safe manner without this + // assumption), but doesn't appear to be mentioned in the standard. + *saved_iter = pos; + + // Fill out the connection object appropriately. None of these + // operations can throw + con->signal = this; + con->signal_data = saved_iter.release(); + con->signal_disconnect = &signal_base_impl::slot_disconnected; + + // If an exception is thrown the connection will automatically be + // disconnected. + scoped_connection safe_connection = slot_connection; + + // Connect each of the bound objects + for(std::vector::const_iterator i = + bound_objects.begin(); + i != bound_objects.end(); + ++i) { + // Notify the object that the signal is connecting to it by passing + // it a copy of the connection. If the connection + // should throw, the scoped connection safe_connection will + // disconnect the connection completely. + bound_object binding; + (*i)->signal_connected(slot_connection, binding); + + // This will notify the bound object that the connection just made + // should be disconnected if an exception is thrown before the + // end of this iteration + auto_disconnect_bound_object disconnector(binding); + + // Add the binding to the list of bindings for the connection. + con->bound_objects.push_back(binding); + + // The connection object now knows about the bound object, so if an + // exception is thrown later the connection object will notify the + // bound object of the disconnection automatically + disconnector.release(); + } + + // No exceptions will be thrown past this point, and we must not + // disconnect the connection now + safe_connection.release(); + + return slot_connection; + } + + bool signal_base_impl::empty() const + { + // Disconnected slots may still be in the list of slots if + // a) this is called while slots are being invoked (call_depth > 0) + // b) an exception was thrown in remove_disconnected_slots + for (slot_iterator i = slots.begin(); i != slots.end(); ++i) { + if (i->second.first.connected()) + return false; + } + + return true; + } + + void signal_base_impl::disconnect(const any& group) + { + std::pair group_slots = + slots.equal_range(group); + while (group_slots.first != group_slots.second) { + slot_iterator next = group_slots.first; + ++next; + + group_slots.first->second.first.disconnect(); + group_slots.first = next; + } + } + + void signal_base_impl::slot_disconnected(void* obj, void* data) + { + signal_base_impl* self = reinterpret_cast(obj); + + // We won't need the slot iterator after this + std::auto_ptr slot( + reinterpret_cast(data)); + + // If we're flags.clearing, we don't bother updating the list of slots + if (!self->flags.clearing) { + // If we're in a call, note the fact that a slot has been deleted so + // we can come back later to remove the iterator + if (self->call_depth > 0) { + self->flags.delayed_disconnect = true; + } + else { + // Just remove the slot now, it's safe + self->slots.erase(*slot); + } + } + } + + void signal_base_impl::remove_disconnected_slots() const + { + // Remove any disconnected slots + for (slot_iterator i = slots.begin(); i != slots.end(); /* none */) { + if (!i->second.first.connected()) + slots.erase(i++); + else + ++i; + } + } + + call_notification:: + call_notification(const shared_ptr& b) : + impl(b) + { + // A call will be made, so increment the call depth as a notification + impl->call_depth++; + } + + call_notification::~call_notification() + { + impl->call_depth--; + + // If the call depth is zero and we have some slots that have been + // disconnected during the calls, remove those slots from the list + if (impl->call_depth == 0 && + impl->flags.delayed_disconnect) { + impl->remove_disconnected_slots(); + impl->flags.delayed_disconnect = false; + } + } + + signal_base::~signal_base() + { + } + } // namespace detail + } // namespace signals +} // namespace boost + +#ifndef BOOST_MSVC +// Explicit instantiations to keep in the library +template class boost::function2; +template class std::multimap >; +#endif diff --git a/boost/libs/signals/src/slot.cpp b/boost/libs/signals/src/slot.cpp new file mode 100644 index 0000000000..b76297dc42 --- /dev/null +++ b/boost/libs/signals/src/slot.cpp @@ -0,0 +1,70 @@ +// Boost.Signals library +// +// Copyright (C) 2001 Doug Gregor (gregod@cs.rpi.edu) +// +// Permission to copy, use, sell and distribute this software is granted +// provided this copyright notice appears in all copies. +// Permission to modify the code and to distribute modified code is granted +// provided this copyright notice appears in all copies, and a notice +// that the code was modified is included with the copyright notice. +// +// This software is provided "as is" without express or implied warranty, +// and with no claim as to its suitability for any purpose. + +// For more information, see http://www.boost.org + +#include + +namespace boost { + namespace signals { + namespace detail { + void slot_base::create_connection() + { + // Create a new connection object + basic_connection* con = new basic_connection(); + + /* nothrow */ { + // The signal portion isn't really necessary, except that we need a + // signal for the connection to be connected. + con->signal = static_cast(this); + con->signal_data = 0; + con->signal_disconnect = &bound_object_destructed; + } + + // This connection watches for destruction of bound objects. Note + // that the reset routine will delete con if an allocation throws + watch_bound_objects.reset(con); + + // We create a scoped connection, so that exceptions thrown while + // adding bound objects will cause a cleanup of the bound objects + // already connected. + scoped_connection safe_connection(watch_bound_objects); + + // Now notify each of the bound objects that they are connected to this + // slot. + for(std::vector::iterator i = bound_objects.begin(); + i != bound_objects.end(); ++i) { + // Notify the object that the slot is connecting to it + signals::detail::bound_object binding; + (*i)->signal_connected(watch_bound_objects, binding); + + // This will notify the bound object that the connection just made + // should be disconnected if an exception is thrown before the + // end of this iteration + signals::detail::auto_disconnect_bound_object disconnector(binding); + + // Add the binding to the list of bindings for the connection + con->bound_objects.push_back(binding); + + // The connection object now knows about the bound object, so if an + // exception is thrown later the connection object will notify the + // bound object of the disconnection automatically + disconnector.release(); + } + + // No exceptions will be thrown past this point. + safe_connection.release(); + } + } // end namespace detail + } // end namespace signals +} // end namespace boost diff --git a/boost/libs/signals/src/trackable.cpp b/boost/libs/signals/src/trackable.cpp new file mode 100644 index 0000000000..f33bdeb2cd --- /dev/null +++ b/boost/libs/signals/src/trackable.cpp @@ -0,0 +1,63 @@ +// Boost.Signals library +// +// Copyright (C) 2001 Doug Gregor (gregod@cs.rpi.edu) +// +// Permission to copy, use, sell and distribute this software is granted +// provided this copyright notice appears in all copies. +// Permission to modify the code and to distribute modified code is granted +// provided this copyright notice appears in all copies, and a notice +// that the code was modified is included with the copyright notice. +// +// This software is provided "as is" without express or implied warranty, +// and with no claim as to its suitability for any purpose. + +// For more information, see http://www.boost.org + +#include +#include + +namespace boost { + namespace signals { + void trackable::signal_disconnected(void* obj, void* data) + { + trackable* self = reinterpret_cast(obj); + connection_iterator* signal = + reinterpret_cast(data); + + // If we're dying, don't bother erasing the connection from the list; + // it'll be gone anyway + if (!self->dying) { + self->connected_signals.erase(*signal); + } + + // This iterator pointer won't ever be used again + delete signal; + } + + void + trackable::signal_connected(connection c, + signals::detail::bound_object& binding) const + { + // Insert the connection + connection_iterator pos = + connected_signals.insert(connected_signals.end(), c); + + // Make this copy of the object disconnect when destroyed + pos->set_controlling(); + + binding.obj = const_cast(reinterpret_cast(this)); + binding.data = reinterpret_cast(new connection_iterator(pos)); + binding.disconnect = &signal_disconnected; + } + + trackable::~trackable() + { + dying = true; + } + } // end namespace signals +} + +#ifndef BOOST_MSVC +// Explicit instantiations to keep in the library +template class std::list; +#endif diff --git a/configure.in b/configure.in index 598f556f97..e63a945732 100644 --- a/configure.in +++ b/configure.in @@ -342,6 +342,8 @@ AC_OUTPUT([Makefile \ boost/libs/Makefile \ boost/libs/regex/Makefile \ boost/libs/regex/src/Makefile \ + boost/libs/signals/Makefile \ + boost/libs/signals/src/Makefile \ config/Makefile \ development/lyx.spec \ lib/Makefile \ diff --git a/po/POTFILES.in b/po/POTFILES.in index 313dcd08f8..d0c3a8bdd9 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -4,14 +4,12 @@ src/BufferView2.C src/bufferview_funcs.C src/BufferView_pimpl.C src/Chktex.C -src/ColorHandler.C src/converter.C src/CutAndPaste.C src/debug.C src/exporter.C src/ext_l10n.h src/FloatList.C -src/FontLoader.C src/frontends/controllers/biblio.C src/frontends/controllers/ButtonController.h src/frontends/controllers/character.C @@ -69,6 +67,7 @@ src/frontends/qt2/QToc.C src/frontends/qt2/QURL.C src/frontends/qt2/QVCLog.C src/frontends/xforms/Alert_pimpl.C +src/frontends/xforms/ColorHandler.C src/frontends/xforms/combox.C src/frontends/xforms/FeedbackController.C src/frontends/xforms/FileDialog.C @@ -150,6 +149,7 @@ src/frontends/xforms/FormUrl.C src/frontends/xforms/FormVCLog.C src/frontends/xforms/input_validators.C src/frontends/xforms/Menubar_pimpl.C +src/frontends/xforms/xfont_loader.C src/frontends/xforms/xforms_helpers.C src/gettext.h src/importer.C