[rkward-cvs] rkward/rkward/rbackend rcommand.cpp, 1.8, 1.9 rcommand.h, 1.24, 1.25 rcommandreceiver.h, 1.7, 1.8

Thomas Friedrichsmeier tfry at users.sourceforge.net
Fri Sep 8 11:17:56 UTC 2006


Update of /cvsroot/rkward/rkward/rkward/rbackend
In directory sc8-pr-cvs9.sourceforge.net:/tmp/cvs-serv12281/rkward/rbackend

Modified Files:
	rcommand.cpp rcommand.h rcommandreceiver.h 
Log Message:
RCommands may have several receivers, RKCommandReceiver does not elaborate housekeeping.
Progress on package installation. New method is still pretty messy, but works in principle

Index: rcommand.h
===================================================================
RCS file: /cvsroot/rkward/rkward/rkward/rbackend/rcommand.h,v
retrieving revision 1.24
retrieving revision 1.25
diff -C2 -d -r1.24 -r1.25
*** rcommand.h	1 Sep 2006 15:38:17 -0000	1.24
--- rcommand.h	8 Sep 2006 11:17:54 -0000	1.25
***************
*** 209,212 ****
--- 209,214 ----
  /** Add an additional listener to the command */
  	void addReceiver (RCommandReceiver *receiver);
+ /** Remove a receiver from the list. This may be needed when a listener wants to self-destruct, to make sure we don't try to send any further info there */
+ 	void removeReceiver (RCommandReceiver *receiver);
  private:
  friend class RThread;

Index: rcommand.cpp
===================================================================
RCS file: /cvsroot/rkward/rkward/rkward/rbackend/rcommand.cpp,v
retrieving revision 1.8
retrieving revision 1.9
diff -C2 -d -r1.8 -r1.9
*** rcommand.cpp	1 Sep 2006 15:38:17 -0000	1.8
--- rcommand.cpp	8 Sep 2006 11:17:54 -0000	1.9
***************
*** 76,82 ****
  
  	receivers[num_receivers++] = receiver;
! 	receiver->addCommand ();
  }
  
  
  void RCommand::finished () {
--- 76,102 ----
  
  	receivers[num_receivers++] = receiver;
! 	receiver->addCommand (this);
  }
  
+ void RCommand::removeReceiver (RCommandReceiver *receiver) {
+ 	RK_TRACE (RBACKEND);
+ 
+ 	if (!receiver) return;
+ 
+ 	RCommandReceiver **newlist = new RCommandReceiver* [MAX_RECEIVERS];
+ 	int num_new_receivers = 0;
+ 	for (int i=0; i < num_receivers; ++i) {
+ 		if (receivers[i] != receiver) {
+ 			newlist[num_new_receivers++] = receiver;
+ 		}
+ 	}
+ 
+ 	if (num_new_receivers == num_receivers) {
+ 		RK_DO (qDebug ("Was not a receiver in RCommand::removeReceiver"), RBACKEND, DL_WARNING);
+ 	}
+ 
+ 	receivers = newlist;
+ 	num_receivers = num_new_receivers;
+ }
  
  void RCommand::finished () {
***************
*** 85,89 ****
  	for (int i=0; i < num_receivers; ++i) {
  		receivers[i]->rCommandDone (this);
! 		receivers[i]->delCommand ();
  	}
  }
--- 105,109 ----
  	for (int i=0; i < num_receivers; ++i) {
  		receivers[i]->rCommandDone (this);
! 		receivers[i]->delCommand (this);
  	}
  }

Index: rcommandreceiver.h
===================================================================
RCS file: /cvsroot/rkward/rkward/rkward/rbackend/rcommandreceiver.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -C2 -d -r1.7 -r1.8
*** rcommandreceiver.h	1 Sep 2006 15:38:17 -0000	1.7
--- rcommandreceiver.h	8 Sep 2006 11:17:54 -0000	1.8
***************
*** 18,25 ****
  #define RCOMMANDRECEIVER_H
  
  /**
  Use this class as a base for all classes that need to handle RCommands. Most importantly it provides a virtual function (rCommandDone ()) for handling of RCommand-results. Reimplement this to interpret the command-results.
  For windows/dialogs which interpret RCommand results, the receiver provides a special mechanism. The problem with those windows/dialogs is, that the user may close them, while there are still RCommands due to come in, i.e. they can't be deleted, but rather need to wait for the remaining results to come in.
! This class will keep track of which RCommands are still out there (and expected to return to this receiver). If you call deleteThis (), the RCommandReceiver will either self-destruct immediately or wait for any remaining commands to come in. Warning: This means, your class may be delelted immediately. You should return at once after calling deleteThis ().
  
  @author Thomas Friedrichsmeier
--- 18,31 ----
  #define RCOMMANDRECEIVER_H
  
+ #include <qvaluelist.h>
+ 
+ #include "rcommand.h"
+ 
  /**
  Use this class as a base for all classes that need to handle RCommands. Most importantly it provides a virtual function (rCommandDone ()) for handling of RCommand-results. Reimplement this to interpret the command-results.
  For windows/dialogs which interpret RCommand results, the receiver provides a special mechanism. The problem with those windows/dialogs is, that the user may close them, while there are still RCommands due to come in, i.e. they can't be deleted, but rather need to wait for the remaining results to come in.
! This class will keep track of which RCommands are still out there (and expected to return to this receiver). When deleting the object, it will unregister from all outstanding commands, so there are invalid pointer operations.
! 
! TODO: this mechanism may be slightly costly, if there are *many* commands outstanding. Maybe for special receivers like RKWatch, which are never destroyed at run-time, the mechanism should be disabled.
  
  @author Thomas Friedrichsmeier
***************
*** 32,42 ****
  public:
  /** constructor. No args */
!     RCommandReceiver () { num_commands_waiting=0; deleted=false; };
  /** destructor */
!     virtual ~RCommandReceiver () {};
! /** number of commands issued with this RCommandReceiver as receiver, that have not returned, yet */
! 	int numCommandsOut () { return num_commands_waiting; };
! /** use this instead of "delete this". Will wait until all commands still waiting (@see numCommandsOut ()), before acutally deleting the receiver */
! 	void deleteThis () { if (num_commands_waiting > 0) { deleted=true; } else { deleteThisNow (); } };
  protected:
  	friend class RCommand;
--- 38,48 ----
  public:
  /** constructor. No args */
!     RCommandReceiver () { };
  /** destructor */
!     virtual ~RCommandReceiver () {
! 		for (QValueList<RCommand*>::const_iterator it = outstanding_commands.begin (); it != outstanding_commands.end (); ++it) {
! 			(*it)->removeReceiver (this);
! 		}
! 	};
  protected:
  	friend class RCommand;
***************
*** 49,59 ****
  @param output The new output-fragment */
  	virtual void newOutput (RCommand *, ROutput *) {};
! /** calls "delete this" immediately (called from deleteThis ()). Virtual so you can use some other method of destruction, e.g. QObject::deleteLater (). */
! 	virtual void deleteThisNow () { delete this; };
  private:
! 	int num_commands_waiting;
! 	bool deleted;
! 	void addCommand () { ++num_commands_waiting; };
! 	void delCommand () { if ((--num_commands_waiting <= 0) && deleted) { deleteThisNow (); } };
  };
  
--- 55,63 ----
  @param output The new output-fragment */
  	virtual void newOutput (RCommand *, ROutput *) {};
! protected:
! 	QValueList<RCommand*> outstanding_commands;
  private:
! 	void addCommand (RCommand *command) { outstanding_commands.append (command); };
! 	void delCommand (RCommand *command) { outstanding_commands.remove (command); };
  };
  





More information about the rkward-tracker mailing list