paragui-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[paragui-cvs] CVS: paragui/src/libsigc++/doc API,NONE,1.1.2.1 FAQ,NONE,


From: Alexander Pipelka <address@hidden>
Subject: [paragui-cvs] CVS: paragui/src/libsigc++/doc API,NONE,1.1.2.1 FAQ,NONE,1.1.2.1 Makefile.am,NONE,1.1.2.1 Makefile_web.am_fragment,NONE,1.1.2.1 UML,NONE,1.1.2.1 conventions,NONE,1.1.2.1 diagrams,NONE,1.1.2.1 marshal,NONE,1.1.2.1 powerusers,NONE,1.1.2.1 requirements,NONE,1.1.2.1 riscos,NONE,1.1.2.1 signals,NONE,1.1.2.1 win32,NONE,1.1.2.1
Date: Mon, 03 Feb 2003 19:08:18 -0500

Update of /cvsroot/paragui/paragui/src/libsigc++/doc
In directory subversions:/tmp/cvs-serv19686/src/libsigc++/doc

Added Files:
      Tag: devel-opengl
        API FAQ Makefile.am Makefile_web.am_fragment UML conventions 
        diagrams marshal powerusers requirements riscos signals win32 
Log Message:
added libsigc++ 1.2.3 (building statically linked versions, Win32)
physfs autoconf / automake fixes



--- NEW FILE ---
* WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * 
  This file is grossly out of data with current version (1.0 != 1.1) 
* WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * 

Object & Handles
=================
In order for a signal to be connected to object, the object must
have Object somewhere in its inheritence tree.

class virtual Object
  {
   public:
     bool is_dynamic();
     bool is_floating();
     Object();
     virtual ~Object();
  };

Objects are 
 - Reference counted
 - Capable of deleting self if told to be managed.


Handles are used for internal memory management.  They are a signature not 
a real class so they can incapsulate any class that has the necessary 
functions.

signature class Handle<ObjType,Policy>
  {
   public:
     operator ObjType*();
     ObjType operator *();
     ObjType* operator ->();

     bool connected();

     Handle& operator =(ObjType*);
     Handle& operator =(ObjType&);
     Handle& operator =(const Handle<O,P> &);

     Handle(ObjType*);
     Handle(ObjType&);
     Handle(const Handle<O,P>&);
  };



Slots
======
Slots are an encapsulation of a callable object.  A factory called slot() 
builds Slots from object/methods, static functions and signals.

class Slot#<rettype,ARGS>: public Object
  {
   public:
     rettype call(ARGS);
     Slot#()
     virtual ~Slot#()
  };

Slots build up in a tree to contain a wide number of connection types.  

There is a class of functions call Adaptors.  Adaptors take a slot
and alter it to a different profile.  

Planned adaptors
  bind - bind callback data starting from the end.
  extend - add dummy arguments to the end of a slot.
  convert - convert the calling arguments with a function. 

Internally slots are just handles to an internal abstract slot
type called Slot#_, which is a pimple on SlotData.  

Slots can not be duplicated as they may have a large list of internal
data.  You should not reuse a slot in multiple lists.


Signals
=======
A list of slots can be called with a signal.  A signal is considered a 
slot container.

class Signal#<RETURN,ARGS,Policy>
  {
   public:
     typedef Slot#<RETURN,ARGS> InSlotType;
     typedef Slot#<MARSH_RETURN,ARGS> OutSlotType;

     OutSlotType slot();
     Connection connect(InSlotType& s);
     MARSH_RETURN emit(ARGS);
     MARSH_RETURN operator()(ARGS); // alias for emit
     Signal();
     Signal(InSlotType& );
     ~Signal();
  };   

Two typedefs are specified InSlotType and OutSlotType.  InSlotType
is the type taken by this signal for connections.  OutSlotType
is the type of slot this function returns and is determented by
the Marshaller.  In most cases InSlotType and OutSlotType match,
but this is not necessarily the case.  Signals do not need to
have these typedefs, but it eases building new Signal classes from
them.

The basic methods shown there are
  emit - call all slots contained within.
  slot - give away a slot that receive incoming calls.
  connect - insert a slot into the call list.

Slots are removed by calling disconnect on their connections.

There is also the ablity to have a marshaller that takes care of handling 
signal callbacks.  This functionality is dependent on the implementation 
of the signal.  For the basic signal type, the marshaller is a hidden 
template parameter.

Connect() may also take optional implementation dependent arguments
for specifying behavior.  For example, timeout.connect(slot(&foo),10) 
where the second argument it a time in seconds is a good use of
optional connect flags.

Additional functionality may optionally be defined such as
ablity to check if there are any signals attached (empty()) or
remove all connected signals (clear()).  However these are
not a requirement and are implementation dependent.


Connections
=============
Connections are given to the user on each connect to allow individual 
connections to be broken or altered.  

class Connection
  {
   public:
     void disconnect();
     Connection();
  };

They are a handle to the data, so when the last connection goes away and 
the slot is not yet properly held in a Signal the slot will go away.

 

--- NEW FILE ---
This is a list of questions and answers that I have collected from
messages to my mailbox

--------------------------------------------------------------------- 

Q: Why isn't sigcconfig.h installed with the rest of the headers?

A: Traditionally include files that are dependent on the compiler
   or srchitecture belong under lib trees and not the include tree.
   This allows machines to share include directories on large multiuser
   systems.

   Examples:
     /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.57/include 
     /usr/lib/glib/include
     /usr/lib/qt/include

   To access that file you should include a -I PREFIX/lib/sigc++/include
   in your compiler switchs.

   This can be done for you automatically through the use of 
   the sigc-config script.  

     c++ myfile.cc `sigc-config --cflags --libs`

   Last, if you really don't like this just symlink the file into
   PREFIX/include.  (Don't copy or the next version of libsigc++ 
   very likely won't work right!) 


Q: Why on Visual C++ can do I get piles of errors when trying to
   use classes which contain Signals?  

A: Visual C++ requires all classes which are parameterized to be
   explicitely exported.  This is the same problem encountered 
   when using STL classes in VC++.  Microsoft Knowledge Base
   article Q168958 contains the solution.

   (http://support.microsoft.com/support/kb/articles/Q168/9/58.ASP)

   You will need to create an export file with all the signals,
   slots, and parameterized functions explicitely instantiated
   and include it in your library source.  (Anyone have an example
   of this?)


Q: Do you accept code contributions?

A: Yes and no.  Karl is current the sole author of libsigc++ 
   in part because he plans at some point to relicense the code 
   to BSD if sigc++ is found to be appropraite for a standards
   body like boost.  Thus I accept ports and modifications which
   come from the current code base or portions of code too small
   to be considered copyright.  Larger code contributions may be
   included in the dist, but will need to be a separate library.


Q: How is a template library LGPL?  Does this mean the binaries
   linked to it must be GPL since the compiled templates generate
   GPL compiled functions?

A: No, the compiled templates are not considered GPL.
   I inquired with RMS prior to release of libsigc++.  The
   intent of a template library like this is for the template source (the
   headers) to be distributable, modifications to those sources
   to be open, and only the binary code generated from the .cc
   files to be help to the LGPL standard.  Binary code compiled from
   the templates which is build with the users types belongs
   to the user and not the library and thus may be licensed in
   any way the user wants.  Thus you may freely use sigc++ with
   comercial programs and those programs may be license however
   you chose, so long as the linkage with the non-template portions
   obeys the LGPL.  

   In practical terms here is the only burden LGPL places.  If you 
   take a source file from this distribution and modify it, it must be 
   LGPL.  That means people can request a copy of your modified source
   under that license.  If your program is licenced something other than 
   LGPL or GPL, you should either use sigc++ as a shared library or have 
   the object files available upon request so the user can relink
   with a later version of sigc++. 


--- NEW FILE ---
## Copyright (c) 2002
## The libsigc++ development team.

## This voodoo stuff lets automake see the subdirs
## without including them into recursive builds.
if LIBSIGC_FALSE
SUBDIRS         = reference manual
endif
DIST_SUBDIRS    = reference manual

EXTRA_DIST      = Makefile_web.am_fragment \
        API                     \
        UML             diagrams        signals         \
        conventions     powerusers      requirements    \
        win32   FAQ             riscos          \
        marshal



--- NEW FILE ---
web_path_docs = /home/groups/l/li/libsigc/htdocs/libsigc1_2/

--- NEW FILE ---
Here is a reference to the UML class diagram symbols:
(Taken from a number of sources.)

Class
-----
A Class description containing a 
   ____________
  | Class Name |
  |------------|
  | Attributes | 
  |------------|
  | Operations |
  |____________|

Association
-----------
An association represents a physical or conceptual connection 
betwen objects.  This is represented by a line between the two objects.
If the association has a name it would often be written on top.

          AssocName
  Class1 ----------- Class2

There is a possiblity of a multidirectional association that would be 
represented by a diamond connecting the related sets.
                

  Class1 -----<O>---- Class3
               |
            Class2

Arrows can be used to indicate the navigablity of a association.
So an arrow from one class to another would indicate that Class1
uses the services of Class2 but Class2 is not aware of Class1.
It also indicates that nature of Class2 scope.  Since there
is no aggregation relationship here, Class2 may outlive Class1
instances.  This would be used to indicate a pointer or reference
relationship.

  Class1 -------> Class2

In some places it is necessary to represent that a Class can
be associated with a set instead of a single instance.  This
will be represented by a star at the end of the association.

  Class1 ------->* Class2

Composition (Strong Aggregation) 
---------
This means that Class2 is a part of Class1.  It is a strong form
of aggregation in that when Class1 is destroyed Class2 goes with it.

The symbol for a composition relationship is a diamond filled to an arrow.

 Class1 <*>----->  Class2  

Aggregation
-----------
A weaker form of aggregation than composition is represented with
an unfilled diamond.  It still demotes the life time of Class2 is 
restricted to Class1, but Class2 is not part of Class1.  This may
be implemented by a pointer in Class1 to Class2 with the dtor 
destroying Class2.    

 Class1 <>------> Class2
 

Inheritance
-----------

Inheratance is indicated with an triangle pointing up to the 
class form which the other derives.  (Having no triangles a
A will do.)
  
Class1
  A
  |
Class2


So now a quick example:

         +--> Shape
         |      A
 parent_ |      |
         |      |         points_
         +--- Polygon <>------------->* Point

This would indicate that a Polygon is derived from a Shape.  It also
indicates that Polygon can have a reference to a Shape.  Further,
Polygon contains a set of Points that it is responsible for.

This might be implemented like

  class Shape 
    {//...
    };

  class Polygon: public Shape
    {
     private:
       Shape*         parent_;
       list<auto_ptr<Point>> points_;
     public:
       //...
    };
          
     
References:
  UML Class Diagrams
    Robert C. Martin
    Engineering Notebook Column
    C++ Report, August, 1997 
    http://www.oma.com/PDF/umlClassDiagrams.pdf

  OML Object Model
    http://wwwis.cs.utwente.nl:8080/dmrg/MEE/misop007/

 

--- NEW FILE ---
Okay here are the conventions for this project.

macros   - all caps (MY_MACRO)
enum     - same as macros

classes  - cap each word lower others (Signal)
private classes - same as class with underscore or trailing _ (BasicSignal_)

function - lowercase with underscore (foo_bar())
methods  - lowercase with underscore (m.foo_bar())
data     - lowercase (m.mydata)
private data - lowercase with trailing underscore (m.mydata_)

Namespaces are used where possible.  

Format is GNU or modified GNU (indent first bracket)

class MyClass
  { 
    MyClass();
  } 


--- NEW FILE ---
* WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING *
  This file is grossly out of data with current version (1.0 != 1.1)
* WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING *

Here are some UML diagrams of the relationships in Libsigc++:

Scopes, Handles, Objects:   
------------------------     
                           
                     _________    scope_    _____________
                    |  Scope  |*<-------<> | Object_Impl |   
                    |         |    obj_    |             |
                    |_________|----------> |             |
                         A        (obj)    |             |
                         |          +----> |             |
                         |          |      |_____________|
                         |          |            A 
                     __________     |            |
 ________    scope_ |  Limit   |<>--+            *
|Handle  |<*>------>|          |            _____________
| <Limit>|          |__________|           | Object      |
|        |                                 |             |
|        |            (obj)                |             |  
|        |   (<>----------------------->)  |             |
|________|                                 |_____________|


Okay here is what you are supposed to get out of this.
Object comes from Object_Impl with multiplicity (VI).
Handle<Limit> in this case forms a virtual aggregate relationship
with the Object it points to.  

For future diagrams I would reduce this to
  
   Handle<Limit> <>--------> Object

Other handle relationships are formed with different types of
scopes.  Reference Count for example would have the same
diagram (but very different behavior.)

There is also a relation when the pointed to
object deletes itself when the object is removed.  This is
a dependency that will be written as

    A -----><> B

  
BasicSignal:
-----------

                ____________________     incoming_
               | BasicSignal_::InOut| <>----------->* Slot
               |                    | 
               |                    |    outgoing_ 
               |____________________| <>----------->* Slot
                            A
                            |
                            |
                ---------------------
               | BasicSignal#        |
               |                     |
               |_____________________|

It is clear from here that a BasicSignal is formed from a number of different
objects.


Connections between a BasicSignal and a Object method:

                         ----------                  ________
                        | SlotData |                | Object |
                        |__________|                |________|
                              A                         A
                              |                         |
                              |                         |
  ___________              _____________                |
 |BasicSignal| outgoing_  | ObjectSlot# |           ----------
 |___________|<>-------->*|             |          | MyObject | 
                          |             |-------><>|          |
  ___________             |             |          |__________|
 |Connection |----------> |_____________|
 |___________|


--- NEW FILE ---
* WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING *
  This file is grossly out of data with current version (1.0 != 1.1)
* WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING *


1.0 Marshallers
===============

Marshallers offer the opportunity to control the emittion process, and 
collate return values. By default signals have a marshaller which does 
nothing, and throws away all but the last return value.

A marshaller can be any class with:
  struct  SomeMarshal
    {
       // both typedefs must be defined.
       typedef Type1 InType;
       typedef Type2 OutType;

       // Return final return code.
       OutType value();  
       
       // Return value if marshaller does not get built
       static OutType default_value();

       // Captures return codes and returns TRUE to stop emittion.
       bool marshal(const InType&);

       SomeMarshal();
   };

The function marshal() will be called with the return value of each slot 
connected to the signal as they are called. The emittion process can be 
stopped by marshal() returning true.

Once all the slots have been called, value() is called to determine what 
to return to the emitter.  If the signal gets called and there is
nothing attached the default_value() is used.

2.0 Possible uses
=================
A marshaller could stop emittion when the signal had been handled:
  struct StopOnTrue
    {
      typedef bool InType;
      typedef bool OutType;
      OutType  return_value_;

      OutType value() { return return_value_; }
      static OutType default_value() { return false; }
      bool marshal(const InType& val) { return_value_ = val; return val; }

      StopOnTrue() : return_value_(false) {}
    };

marshal() here returns true as soon as one of the things connected to the 
signal returns true. It also keeps track of whether anything stopped the 
emittion in the return_value_ member. This way when something emits the 
signal, it can tell whether the signal was dealt with (signal.emit() 
returns true) or not (signal.emit() returns false).

Now, if OutType was a list or a vector, marshal() could push_back() all 
the values, returning to the emitter all the return values rather than just 
one.

3.0 Standard Marshallers
========================

The following marshallers are provided by default.
 
  Marshal<void>
  Marshal<T> 
  Marshal<R>  (untested, may not be portable)
  FixedMarshal<T,V>  
  FastMarshal<T>  

where
 -  T can be a type, class, or pointer
 -  R can be a reference  
 -  V is the initial value of the marshaller
    which is returned if nothing is connected.

All of the standard defined marshallers, with the exception of
FastMarshal,  check for a possiblity of a skipped return code via 
RetCode::check_ignore().  You can cause a return code to be 
ignored by the marshaller by setting RetCode::ignore() prior to returning 
to a function.  Please note that you must be sure that you are returning to
signal call to use ignore().  Calling at other times may result in other
functions incorrectly skipping. 

The check_ignore function is thread safe which may induce
unnecessary delays in slot calling.  To avoid this overhead
either define the signal to have a void return or
use a FastMarshal.

(This will all be replaced by an exeption mechanism at some point;
however, current compiler technology is too slow for this to
work.)


--- NEW FILE ---
Copyright 2001 Karl Einar Nelson
----------------------------------------------------------------------
* WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING *
  This file is grossly out of data with current version (1.0 != 1.1)
* WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING *

The following things are be available to powerusers.

  - changing the return type of a slot
  - changing the paramete types of slot
  - signal overloading
  - mixed type signals

=======================================================================
* Slot type changing

Slots can be made to change their input types based on a static function.

Example:

  // write some conversion functions
  int convert_mysignal_c(Callback1<int,const char*> *s,const string &str)
    {return s->call(str.c_str());}
  Slot1<int,const string&> myconvert(const Slot1<int,const char*> &s)
    {return convert(s,convert_mysignal_c);}


  Signal1<int,const string&> mysignal;
  int foo(const char*);
  mysignal.connect(myconvert(slot(foo));


* Signal overloading

One signal can have multiple behavior for a single signal name.  
This is done with multiple inheritance.

Example:

  class MyClass
    {
      public:
        class MySig 
          :public Signal1<int,int>, 
           public Signal1<void,double>
         {} mysig;
   } myclass;

  int foo(int);
  void foo2(double);
  myclass.mysig.connect(slot(foo));
  myclass.mysig.connect(slot(foo2));
  myclass.mysig(1);   // calls foo
  myclass.mysig(1.0); // calls foo2

         

* Mixed type signals

A signal can be made to accept a wide group of slots with similar data
types.

Example:

  class A
    {

     public:
     class MySig: public Signal1<int,string&>
       {
          static int _mysig_convert(Callback1<int,const char*> *s,
                                    const string &str)
            {return s->call(str.c_str());}
        public:
          Connection connect(const Slot1<int,const char*> &s)
            {return connect(convert(s,_mysig_convert));}
       }  mysig;
    };

  int foo(const char* c);
  int foo2(string& s);

  mysig.connect(slot(foo));  // this is acceptable
  mysig.connect(slot(foo2)); // this is also acceptable
  string h="hello";
  mysig(h);                  // calls both foo and foo2.


Still in works
----------------
* Signal overloading over classes

This should be extendable accross different levels of a class.

Example: (details still in progress)

  

* Signals with translation

Signals can be made to convert and proxy accross other systems.


--- NEW FILE ---
Copyright 2001 Karl Einar Nelson
------------------------------------------------------------------
The following things are required for Libsigc++.

A good compiler with the following features
 - capable of handling numerous templates (>200)
 - proper template specialization
 - proper partial specialization
 - templates with default arguments.

It works better with (but does not require)
 - template friend specialization 
 - namespaces
 - void returns

M4 to parse the header files if you wish to rebuild the headers from 
macro source.

==================================================

Platform Issues:

A number of platforms do not support global C++ objects
in shared libraries.  Although not required by this 
library, it may result in problems when building C++ 
libraries on those platforms.  The work arround is
to use statics in functions or pointers which must
be initialized. 

Platforms known to have this bug include
NetBSD, HP-UX 9, HP-UX 10, Solaris without patch.

==================================================

Compiler Issues:

UNIX
----

 Cfront-based compilers: Fails
   -----
   Forget it, get a modern c++ compiler.


 GNU G++ 2.7.2: Fails
   -----
   Upgrade, new versions of GNU G++ are easily and freely available.
   A port to this compiler is possible with effort.


 GNU G++ 2.8: unknown (marginal on 1.0)
   namespaces: no
   partial specialization: yes 
   void returns: yes 
   -----
   Is known to work correctly, but some performance may be subpar.
   Recommend upgrading to latest gcc.


 GNU egcs 1.0: unknown (marginal on 1.0)
   namespaces: no
   partial specialization: yes
   void returns: yes 
   -----
   Is known to work correctly, but some performance may be subpar.
   Recommend upgrading to latest gcc.


 GNU egcs 1.1: unknown (pass on 1.0)
   namespaces: yes
   partial specialization: yes
   void returns: yes 
   -----
   Some issues with multiple inheritance require swapping around
   object declaration orders.  Known problems with dynamic cast 
   in constructors.


 GNU gcc 2.95.2: works
   namspaces: yes
   partial specialization: yes
   void returns: yes
   -----
   Some issues with multiple inheritance require swapping around
   object declaration orders.  Known problems with dynamic cast
   in constructors.  ABI is not compatible with egcs nor 2.96,
   thus do not mix binaries.


 GNU gcc 2.96 (redhat): unknown
   namespaces: yes
   partial specialization: yes
   void returns: yes
   -----
   Compiler is slightly more picky than 2.95.2 thus older code
   may fail without minor corrections.  ABI is not compatible
   with previous versions, do not mix binaries. 


 HP C++: fails
   -----
   This is a cfront compiler.  No where close.
   Get a modern c++ compiler.


 HP aC++ A.01.22: unknown (works on 1.0)
   namespaces: yes
   partial specialization: yes
   void returns: yes (only most recent version)
   -----
   HP improved template support thus allowing compilation.
   Earlier compilers lacked support for void returns and proper
   templates.

   Missing <iostream> - use one below


 MipsPro 7.3 Compler on Irix: unknown (marginal on 1.0)
   namespaces: yes
   partial specialization: yes
   void returns: no
   -----
   This compiler is barely within the range of usable compilers.
   Requires compiling a specialization for all types in library
   due to non-standard return behavior.  Should be usable.
   In effort to cut compile times a void return kludge is used
   in place of partial specialization.

   Requires a switch to get templates right.  
   Use 
     CC=cc CXX=CC CPPFLAGS="-ptused" ./configure

   Missing <iostream> - use one below

   
 SunPro C++ 4.1: fails
   namespaces: no
   partial specialization: no
   void returns: no
   -----
   lacks basic template support.


 SunPro C++ 5.0: fails
   namespaces: yes 
   partial specialization: yes
   void returns: no
   specialize references: no
   member templates: no
   use of traits: no
   -----
   Lack of traits and member templates kill the current 
   formulation.  Port possible but functionality damaged.

 SunPro Forte C++ 6.0: fails
   namespaces: yes
   partial specialization: yes
   void returns: no
   specialize references: no
   member templates: no
   use of traits: no
   -----


NON-UNIX
--------

 Visual C++ 5.0: unknown (special on 1.0)
   namespaces: yes
   partial specialization: no
   void returns: no 
   -----
   Although not quite up to par, a port was completed and should
   be the basis for porting back to other earlier compilers.  
   VC++ lacks the ablity to use optional class arguments so
   marshallers must be explicitly declared.  (see doc/win32)


 Borland C++ builder 4: unknown (pass on 1.0)
   namespaces: yes
   partial specialization: yes
   void returns: yes
   -----
   This was a clear pass in 1.0, needs testing for 1.1.


 Metrowerks CodwWarrior 6: unknown (pass on 1.0)
   namespaces: yes
   partial specialization: yes
   void returns: yes
   -----
   1.0 required mild alterations, needs testing for 1.1.
  

==================================================

Some compilers have not yet fully adopted the standard header
files.  (Usually because they lack some compiler feature
required for the standard header.)  For those compilers a
kludge is necessary to make the same code compile on both
standard and non-standard headers.  Add the following file
to the standard include path.

#ifndef IOSTREAM_KLUDGE
#define IOSTREAM_KLUDGE
#include <iostream.h>
namespace std { void iostream_kludge(); };
#endif


--- NEW FILE ---
RISC OS Specific notes:
  To use include "sigc:signal_system.h" in your source. 
   (Use <> if you really want).

  Use "-Lsigc: -lsigc" in the command line to link.

If your filetypes aren't set properly, set 'stype,feb' to type Obey (FEB) 
and run it.

A port of the libsigc++ was done for RISC OS by Ainsley Pereira.  
He maintains a page on how to port the source at 
http://www.snowplains.org/~marble/libsigc++/

To build a RISC OS distribution on a unix machine...
 - unpack the unix distribution
 - configure
 - make dist
 - make riscos-dist 


--- NEW FILE ---
* WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING *
  This file is grossly out of data with current version (1.0 != 1.1)
* WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING *

1.0 Signals
==============

Signals are used for communication between objects.  Rather
that using messy pointers or pointers to member functions to implement 
callbacks this library provides an elegant connection framework for
connecting between static functions, member functions and function objects. 
To add to this all types of connections can be made with compile time
type checking through an extensable template set.  Unlike other solutions
that break the C++ language and add incompatible extensions or code 
generation, Libsigc++ uses only the standard C++ definitions.  Thus it
will not decrease the ability of tools designed to parse the C++ language 
to handle your code.  Libsigc++ provides signal framework which solves 
your problems with communication between objects.  This signal framework 
makes your objects reusable components which are independent of other 
objects it communicates with. This means reducing coupling between 
objects and resulting less dependencies and thus more reusable code. 
 
1.1 How does the communication work?
------------------------------------

In the callback mechanism there's 3 separate entities involved. 

     sender 
     receiver 
     someone making connection between sender and receiver 

In actual code, the sender specifies an interface which it can call when 
it wants to tell other objects something. This interface is specified as 
a function object and is called "Signal". Calling that interface is 
called "emitting a signal". 

The receiver of the signal can be almost anything.  In Libsigc++ the 
following objects can receive messages: 

     member function of any object derived from SigC::Object
     function object derived from SigC::Object 
     static, global or friend function 
     static function object 
     member function to a static object 

All connections share a common syntax through a factory that creates a
abstract function object called a "Slot."


     signal.connect(slot(object,Object::&method));
     signal.connect(slot(&function));
     signal.connect(functionobject.slot())

Making a connection connects sender to the receiver.  After that, if the 
sender emits a signal, all methods, functions and function objects that 
have been connected to that signal are called with the arguments given at
signal emission.  Signature of both sender interface and receiver method 
must match exactly to be able to make connection between them.  If there's 
type mismatches in the signatures, C++ compiler will give compile time 
type error. 



2.0 Implementation of signals
=============================

Signals are C++ function objects.  Because signals are normal C++-objects, 
you can use them in file scope, in function local scope - but they're 
most used inside class scope. A signal definition is of form: 

  Signal2<void, int, float> buttonPressed;

  where
    2     = number of arguments
    void  = type of the return
    int   = type of the first parameter of the signal
    float = type of the 2nd parameter of the signal

This way application programmers can specify interface for a signal. 
A connection from a signal to a (member) function matching signal's 
interface can be made:

  void my_function(int param1, float param2);
  buttonPressed.connect(slot(&my_function));

If the function is a member function, you'll need to specify the object 
too. Note that this object's class needs to be derived from Signal: 

  MyClass myobject; 
  buttonPressed.connect(slot(myobject,&MyClass::my_function));

If the signal is inside an object, you'll need to specify it too: 

  obj.buttonPressed.connect(slot(myobject, &MyClass::my_function));


When connection between a signal and a function has been made, calling 
the signal will make the system call all the connected functions with 
given parameters. Of course many connections can be made to same signal 
and the system will call all of them when the signal is called.

Calling a signal looks exactly like calling normal C++ function: 

  buttonPressed(10, 20.0);

or in case where you have the signal inside an object, call is in format: 

  obj.buttonPressed(10, 20.0);

An alternative method with a function name is also provided with
a method emit.  This is to make it easier to distiguish and provides
a method name for STL connection calls.

  obj.buttonPressed.emit(10, 20.0);



2.1 Signals with return types
------------------------------

All signals have a return type which may be void.  

  Signal1<int,int> signal;

That signal can be connected to the methods with the following signature:

  int my_callback(int);

There are a few restrictions on the types of returns.  Return
types must have:

   a default constructor  T t;
   a copy constructor     T t1,t2;  t1=t2;
   a reference form       T t1;  void func(T& t); func(t1);

A default ctor is required so that a temporary object can be
created to hold the return type.  A copy constructor is required
so that the signal can be marshalled.  A reference form is required
to pass the return types to the marshaller functions.

This means that the return type must not be a reference itself.  



2.2 Connecting to a signals 
-----------------------------

Because Libsigc++ signals use function objects heavily, there needs to be 
way to connect a signal to another signal.  Lets connect a button's 
clicked()-signal to another button's clicked signal: 

struct My_Button 
  {
   Signal0<void> clicked;
  } b1,b2;

b1.clicked.connect(b2.clicked.slot());


2.3 Summery
------------

Here is the summery of the properties of a signal

class Signal<Rettype,Args>
  {
   public:
      Connection connect(const Slot<Rettype Args>&);
      Slot<Rettype,Args> slot();
      Rettype emit(Args);
      Rettype operator()(Args);
  };

Where:
  Rettype is the return type of the signal.
  Args are the arguments taken.

connect() inserts a slot with the same profile into the signal.
slot() returns a slot for connecting this signal to another.
emit() calls all slots in the signal.
 

3.0 Common errors in use of the signals
=======================================

Here are some common errors and an example of some of the errors that
they generate.  (Do not take this as an example of proper use!
Errors similified for clarity.  Your compiler messages will differ)

 * Signature of function does not match signal 
     Return type? 
     arguments have correct type? 
     the signal has correct types?

   Example error session:
     void foo(int i);
     Signal1<int,int> sig;
     sig.connect(slot(foo));
   
     >>foobar.cc: In function `int main()':
     >>foobar.cc:17: no matching function for call to 
         `Signal1<int,int>::connect (Slot1<void,int> *)'
                                         ^^^^^^^^^^^^^^^^
                                       Signiture of function
     >>signal.h: candidates are: 
          Signal1<int,int>::connect<int, int> (Slot1<int,int> *)
                                              ^^^^^^^^^^^^^^
                                           Signiture of Signal
 
 * Using a reference as a return type

   Example error session:
     Signal1<int&,int> sig;

     >>basic_signal.h: In method `int & Signal1_<int &,int>::Impl::
       emit<int &, int>(int)':
     >>signal.h:100:   instantiated from here
     >>basic_signal.h:244: `rc' declared as reference but not initialized

  

 * Connecting object is not derived from SigC::Object
     
   Example error session:
     struct A {int foo(int);} a;
     Signal1<int,int> sig;

     sig.connect(slot(a,&A::foo));

     foobar.cc:58: conversion from `A' to non-scalar type `Object' requested
    
   
 * Forgot to name the connected function as a method.
  
   Example error session: 
     struct A:public SigC::Object {int foo(int);} a;
     Signal1<int,int> sig;

     sig.connect(slot(a,foo));  // should be sig.connect(slot(a,&A::foo));

     >>foobar.cc:47: no matching function for call to `slot (A &, int ()(int))'


 * Forgot to use address of method on connection 
   
   Example error session:
     struct A:public SigC::Object {int foo(int);} a;
     Signal1<int,int> sig;

     sig.connect(slot(a,A::foo)); // should be sig.connect(slot(a,&A::foo));

     >> foobar.cc:23: warning: assuming & on `A::foo1(int)'
  
 
 * Passed a pointer as object (**This is different from Gtk--**)
    
   Example error session:
     struct A:public SigC::Object {int foo(int);} a;
     Signal1<int,int> sig;

     sig.connect(slot(&a,&A::foo)); // should be sig.connect(slot(a,&A::foo));

     >>foobar.cc:93: conversion from `A *' to non-scalar type `Object' 
       requested
     >>object_slot.h:177: in passing argument 1 of 
       `slot<A, int, int>(Object &, int (A::*)(int))'


4.0 Connections
===============

4.1 Disconnecting signals
-------------------------

Every signal.connect()-function returns a Connection object, 
which can be stored and it can be used to disconnect the connection 
by calling function disconnect(). 

Connection c;
c=o.buttonPressed.connect(slot(&myfunction));
...
c.disconnect();

Its perfectly legal to just ignore the return value of connect() functions - 
all bookeeping information used by signal system is released properly.


5.0 Adaptors
============

Often it is desirable to connect to a function and a signal
in which the signal and function signatures are not
exactly the same.

For example, it would be good to ignore the return type
of a function when placing it into a signal with a void return 
type.  

Fortunately, Libsigc++ provides a mechanism to accomplish this
type of connection.  There is a broad class of slot "Adaptors".
These functions take a slot of one type and produce a slot of
another.  Here are some sample adaptors provided:

  bind(Slot, v1) - Passes v1 as last argument to Slot
    (The number of arguments is reduced for the resulting slot)
  bind(Slot, v1, v2) - Passes v1 and v2 as last arguments to Slot

  Examples:

    int func(float);
    Signal1<void,float> sig1;
    Signal1<int> sig2;

    // cover up float argument 
    sig2.connect(bind(slot(&func),20.0f));    
   



--- NEW FILE ---
Building libsigc++ on Win32
===========================

Currently, both the cygwin (posix layer) and mingw (native win32) gcc
compilers are supported through the gnu autotools (automake, autoconf, libtool.
Because the major purpose of the libsigc++ library is to be used for
signal/callback handling in the gtkmm library, mingw is of course the
main target.

1. Cygwin

While using gcc as provided by cygwin, compilation should be as simple 
as typing

./configure
make
make install

2. Mingw

The mingw distribution which has been tested with this release is the following

MinGW-1.1 as the base distribution plus the update packages :
mingw-runtime-1.3
bunutils-2_12_90-20020518-1
w32api-1.4-2

The bare mingw distribution does not provide the necessary tools (sh, perl, m4
, autoconf, automake, ..) to run the provided configure script "as is". One 
(currently non supported) solution is to use mingw in conjunction with msys,
which is readily available on the mingw website (http://www.mingw.org/).

The preferred method is to combine the cygwin distribution (for the unix tools
that were mentioned above) with mingw by making sure that the mingw
tools (gcc, ld, dlltool, ..) are called first.

The configure script can be called using (as an example) the following options

./configure --prefix=/target --build=i386-pc-mingw32 --disable-static

then

make
make check
make install

Because Dll support with libtool on the mingw32 platform is fairly recent, it 
requires developement version of autoconf/automake and libtool, as provided by
the autotools-devel package in the cygwin distribution. Currently, this means

libtool : 1.4e
automake : 1.5b
autoconf : 2.52

IMPORTANT WARNING : the libtool scripts contained in the source distribution
of the library might not be recent enough to support dll creation. It will 
create a static library instead. The main reason for this situation
comes from the fact that the gnome distribution uses the last stable
releases of the autotools, as opposed to their development (cvs)
versions. Therefore, it is recommended to always checked the version
of libtool that is being used when compiling libsigc++ on win32 by calling

libtool --version 

once it has be created by the configure script.

If libtool is too old, it will be necessary to overwrite it using 

libtoolize --force 

from the cygwin autotools-devel package (usually located on 
/usr/autotools/devel), followed by

aclocal
automake
autoconf

before running the configure script again.

In the future, a specially tuned source distribution along with a binary 
package might be provided for mingw.

3. Oher compilers (MSVC, borland)

While some compiler options are present in sigc++/config/sigcconfig.h.in,
other compilers are currently not supported but anyone is free to give it 
a try ! 









reply via email to

[Prev in Thread] Current Thread [Next in Thread]