// Copyright 2001 Karl Einar Nelson
#include <iostream>
#include <sigc++/object_slot.h>

#ifdef SIGC_CXX_NAMESPACES
using namespace std;
using namespace SigC;
#endif

int result=1;

class Foo : public Object
  {
    int i;
    public:
    void foo()
      {
        cout << "hello "<<i <<endl; result+=3;
      }
    void foo2()
      {
        cout << "there "<<i <<endl; result+=5;
      }
    Foo() : i(1) {}

    ~Foo() 
      { cout << "~Foo()"<<endl; }
   };

// has no knowledge of sigc++ so doesn't derive from Object
class A
  { 
   public:
     int i,j;
     void foo() { cout << "A::foo" <<endl; result+=7; }
  };

// later a user wants to use slots so they add Object to give lifetime safety
class B : public A, public Object
  {
  };


int main()
  {
    cout << ">> test 1 (assignment to members)" << endl;
    {
      Foo f;

      Slot0<void> s;
      cout << " call nothing connected" <<endl;
      s();

      cout << " call with foo" <<endl;
      s = slot(f, &Foo::foo);
      s();

      cout << " call with foo2" <<endl;
      s = slot(f, &Foo::foo2);
      s();

      cout << " call after clear" <<endl;
      s.clear();
      s();
    }

    {
    cout << "\n>> test 2 (call after destruction)" << endl;
    Slot0<void> s;
    {
      Foo f;

      cout << " call within scope" <<endl;
      s=slot(f, &Foo::foo);
      s();
    }
    cout << " call out of scope" <<endl;
    s(); 
    }

    cout << "\n>> test 3 using derived classes to add lifetime"<<endl;
    { 
      // sigc++ 1.0 failed this.
      B b;

      Slot0<void> s = slot(b, &A::foo);
      s();
    }
      
    return !(result==19);
  }


#if defined(UNDER_CE) || (defined(_MSC_VER)&&defined(_DEBUG))

// see eVC4/README.txt

void helper()
{
    void (*proxy)(void*) = 0;
	Foo* control1 = 0;
	B* control2 = 0;
	void* object = 0;
	void (Foo::*method1)() = 0;
	void (A::*method2)() = 0;

    SigC::ObjectSlotNode node1( proxy,control1,object,method1);
    SigC::ObjectSlotNode node2( proxy,control2,object,method2);
}

SigC::ObjectSlotNode::ObjectSlotNode(FuncPtr proxy, Foo* control, void* object, void (Foo::*method)())
      : SlotNode(proxy)
      { init(control,object,reinterpret_cast<Method&>(method)); }

SigC::ObjectSlotNode::ObjectSlotNode(FuncPtr proxy, B* control, void* object, void (A::*method)())
      : SlotNode(proxy)
      { init(control,object,reinterpret_cast<Method&>(method)); }

#endif




syntax highlighted by Code2HTML, v. 0.9.1