/*
 * Author:
 *         Kendy Kutzner <kutzner@ira.uka.de>
 *
 * (c) 2005 Research Group Dr. Fuhrmann, University of Karlsruhe, Germany
 * All rights reserved.
 *
 * $Id: callback.h,v 1.6 2005/11/21 10:46:57 kutzner Exp $
 *
 */

#ifndef _CALLBACK_H_
#define _CALLBACK_H_

/** \file 
 * Implement Callbacks in C++
 */

#include <assert.h>
#include <string>
using namespace std;

/// This class contains the basic housekeeping data for callbacks

class callbackbase{
	public:
	virtual void go(int handle)=0;
	protected:
	bool _valid;
	bool _called;
	string _desc;
	public:
	void setdesc(string desc){_desc=desc;};
	string desc(){return _desc;};
	callbackbase():_valid(false), _desc("uninitialized callback"){};
	virtual ~callbackbase(){}; // XXX should we check something?
	void make_valid(){_valid = true;};
	void make_invalid(){_valid = false;}
	void make_called(){_called = true;};
	void make_uncalled(){_called = false;};
	bool getvalid(){return _valid;};
	void restart(){assert(getvalid()); make_uncalled();}; 
};

/// Classes containing a callback member should be a derived class of this template

template <class C>
class callback : public callbackbase {
	/// pointer to class instance containing callback
	C* _obj;
	/// pointer to callback member of this object
	void (C::*_f)(int,int);
	/// we just pass this
	int _state;

	public:
	/// inititalize the callback
	/// \param obj instance of class containing callback (probably *this*)
	/// \param f class member to be called
	/// \param state will be passed when callback is used
	/// \param desc human readable debug hint
	void init(C* obj, void(C::*f)(int,int),int state, string desc){
		_obj = obj;
		_f = f;
		_state = state;
		setdesc(desc);
		make_valid();
	} ;
	/// start the callback
	virtual void go(int handle){
		assert(getvalid());
		make_called();
		(*_obj.*_f)(handle, _state);
	};
};


#endif

