// -*- c++ -*-
/*
Copyright 2000, Karl Einar Nelson
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 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
*/
#ifndef SIGC_OBJECT
#define SIGC_OBJECT
#include <sigcconfig.h>
#ifdef SIGC_CXX_NAMESPACES
namespace SigC
{
#endif
// version numbers
extern int sigc_micro_version;
extern int sigc_minor_version;
extern int sigc_major_version;
class LIBSIGC_API NodeBase;
class LIBSIGC_API ObjectBase;
// (internal)
//TODO: What does Control_ do?
struct LIBSIGC_API Control_
{
const ObjectBase* object_;
NodeBase* dep_; //TODO: What is this used for?
unsigned int count_ : 15; //TODO: What does 15 mean?
unsigned int ccount_ : 16; //TODO: What does 16 mean?
unsigned int manage_ : 1; //TODO: Why not bool?
void add_dependency(NodeBase* node);
void remove_dependency(NodeBase* node);
void cref();
void cunref();
void ref();
void unref();
void destroy();
SIGC_CXX_EXPLICIT Control_(const ObjectBase* object);
~Control_();
};
class LIBSIGC_API ObjectBase
{
public:
friend class ObjectSlot_;
void add_dependency(NodeBase*);
void remove_dependency(NodeBase*);
virtual void reference() const;
virtual void unreference() const;
virtual void set_manage();
ObjectBase& operator=(const ObjectBase& o)
{ return *this; }
ObjectBase()
: control_(0) {}
SIGC_CXX_EXPLICIT_COPY ObjectBase(const ObjectBase& o)
: control_(0) {}
virtual ~ObjectBase()=0;
Control_* control() const
{
return const_cast<ObjectBase *>(this)->control();
}
Control_* control()
{
if (!control_)
control_ = new Control_(this);
return control_;
}
private:
mutable Control_* control_;
};
/** @defgroup Object
* Classes whose member methods are signal handlers (used as Slots) must derive from SigC::Object.
* This allows libsigc++ to disconnect signals when the signal handlers' objects are deleted.
*
* For instance, in gtkmm, all widgets already derive from SigC::Object.
*
* In case you don't need/want the automatic, safe behaviour, you can also use the
* slot_class<> template-functions.
*/
/// @ingroup Object
class LIBSIGC_API Object: virtual public ObjectBase
{
public:
Object();
virtual ~Object();
};
// gtkmm namespaces this as Gtk::manage().
template <class T>
T* manage(T* t)
{ t->set_manage(); return t; }
//Shared reference-counting smart-pointer.
template <class T>
class Ptr
{
public:
Ptr()
{ assign(); }
Ptr(T* t)
{ assign(t); }
template <class T2>
Ptr(const Ptr<T2>& p2)
{
assign( p2.get() );
}
Ptr(const Ptr& p)
{ assign(p.get()); }
~Ptr()
{ if (control_) control_->unref(); }
Ptr& operator=(T* t)
{ reset(t); return *this; }
template <class T2>
Ptr& operator=(const Ptr<T2>& p2)
{ reset(p2.get()); return *this; }
Ptr& operator=(const Ptr& p)
{ reset(p.get()); return *this; }
T& operator*() const { return *get(); }
T* operator->() const { return get(); }
operator T*() const { return get(); }
T* get() const
{
if (!control_)
return 0;
if (!control_->object_)
{
control_->cunref();
control_ = 0;
return 0;
}
return object_;
}
private:
void assign(T* t = 0)
{
object_ = t;
control_ = (object_ ? object_->control() : 0 );
if (control_)
control_->ref();
}
void reset(T* t = 0)
{
if (object_ == t)
return;
if (control_)
control_->unref();
assign(t);
}
mutable Control_* control_;
T* object_;
};
#ifdef SIGC_CXX_NAMESPACES
}
#endif
#endif // SIGC_OBJECT
syntax highlighted by Code2HTML, v. 0.9.1