diff options
Diffstat (limited to 'libs/sigc++2/sigc++/functors/slot_base.cc')
-rw-r--r-- | libs/sigc++2/sigc++/functors/slot_base.cc | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/libs/sigc++2/sigc++/functors/slot_base.cc b/libs/sigc++2/sigc++/functors/slot_base.cc new file mode 100644 index 0000000000..bc0f173f22 --- /dev/null +++ b/libs/sigc++2/sigc++/functors/slot_base.cc @@ -0,0 +1,165 @@ +// -*- c++ -*- +/* + * Copyright 2003, The libsigc++ Development Team + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include <sigc++/functors/slot_base.h> + +namespace sigc +{ + +namespace internal { + +// only MSVC needs this to guarantee that all new/delete are executed from the DLL module +#ifdef SIGC_NEW_DELETE_IN_LIBRARY_ONLY +void* slot_rep::operator new(size_t size_) +{ + return malloc(size_); +} + +void slot_rep::operator delete(void* p) +{ + free(p); +} +#endif + +void slot_rep::disconnect() +{ + if (parent_) + { + call_ = 0; // Invalidate the slot. + // _Must_ be done here because parent_ might defer the actual + // destruction of the slot_rep and try to invoke it before that point. + void* data_ = parent_; + parent_ = 0; // Just a precaution. + (cleanup_)(data_); // Notify the parent (might lead to destruction of this!). + } +} + +//static +void* slot_rep::notify(void* data) +{ + slot_rep* self_ = (slot_rep*)data; + self_->call_ = 0; // Invalidate the slot. + self_->destroy(); // Detach the stored functor from the other referred trackables and destroy it. + self_->disconnect(); // Disconnect the slot (might lead to deletion of self_!). + return 0; +} + +} // namespace internal + +slot_base::slot_base() +: rep_(0), + blocked_(false) +{} + +slot_base::slot_base(rep_type* rep) +: rep_(rep), + blocked_(false) +{} + +slot_base::slot_base(const slot_base& src) +: rep_(0), + blocked_(src.blocked_) +{ + if (src.rep_) + rep_ = src.rep_->dup(); +} + +slot_base::~slot_base() +{ + if (rep_) + delete rep_; +} + +slot_base::operator bool() const +{ + return rep_ != 0; +} + +slot_base& slot_base::operator=(const slot_base& src) +{ + if (src.rep_ == rep_) return *this; + + if (src.empty()) + { + disconnect(); + return *this; + } + + internal::slot_rep* new_rep_ = src.rep_->dup(); + + if (rep_) // Silently exchange the slot_rep. + { + new_rep_->set_parent(rep_->parent_, rep_->cleanup_); + delete rep_; + } + + rep_ = new_rep_; + + return *this; +} + +void slot_base::set_parent(void* parent, void* (*cleanup)(void*)) const +{ + if (rep_) + rep_->set_parent(parent, cleanup); +} + +void slot_base::add_destroy_notify_callback(void* data, func_destroy_notify func) const +{ + if (rep_) + rep_->add_destroy_notify_callback(data, func); +} + +void slot_base::remove_destroy_notify_callback(void* data) const +{ + if (rep_) + rep_->remove_destroy_notify_callback(data); +} + +bool slot_base::block(bool should_block) +{ + bool old = blocked_; + blocked_ = should_block; + return old; +} + +bool slot_base::unblock() +{ + return block(false); +} + +void slot_base::disconnect() +{ + if (rep_) + rep_->disconnect(); +} + + +/*bool slot_base::empty() const // having this function not inline is killing performance !!! +{ + if (rep_ && !rep_->call_) + { + delete rep_; // This is not strictly necessary here. I'm convinced that it is + rep_ = 0; // safe to wait for the destructor to delete the slot_rep. Martin. + } + return (rep_ == 0); +}*/ + +} //namespace sigc |