[rkward-cvs] rkward/rkward/rbackend rembed.h,1.6,1.7 rembedinternal.h,1.8,1.9 rinterface.h,1.12,1.13 rthread.h,1.11,1.12

Thomas Friedrichsmeier tfry at users.sourceforge.net
Thu Apr 28 23:41:11 UTC 2005


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

Modified Files:
	rembed.h rembedinternal.h rinterface.h rthread.h 
Log Message:
Further API-documentation updates.

Index: rembedinternal.h
===================================================================
RCS file: /cvsroot/rkward/rkward/rkward/rbackend/rembedinternal.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -C2 -d -r1.8 -r1.9
*** rembedinternal.h	20 Apr 2005 17:41:37 -0000	1.8
--- rembedinternal.h	28 Apr 2005 23:41:08 -0000	1.9
***************
*** 22,25 ****
--- 22,28 ----
  	that R- and Qt-includes don't like each other. Hence this class is Qt-agnostic while
  	REmbed is essentially R-agnostic.
+ 	
+ 	@see REmbed
+ 
  	*@author Thomas Friedrichsmeier
    */
***************
*** 27,52 ****
  class REmbedInternal {
  public: 
  	REmbedInternal();
  	virtual ~REmbedInternal();
! 	
! 	enum RKWardRError { NoError=0, Incomplete=1, SyntaxError=2, OtherError=3 };
  protected:
  	bool startR (const char* r_home, int argc, char **argv);
  	void shutdown ();
  	void runCommandInternal (const char *command, RKWardRError *error, bool print_result=false);
! 	
  	char **getCommandAsStringVector (const char *command, int *count, RKWardRError *error);
  	double *getCommandAsRealVector (const char *command, int *count, RKWardRError *error);
  	int *getCommandAsIntVector (const char *command, int *count, RKWardRError *error);
- 
  public:
  /** call this periodically to make R's x11 windows process their events */
  	static void processX11Events ();
  
! // these will need QStrings and stuff and hence are handled in REmbed
  	virtual void handleSubstackCall (char **call, int call_length) = 0;
  	//virtual char **handleGetValueCall (char **call, int call_length, int *reply_length) = 0;
  
! /// only one instance of this class may be around. This pointer keeps the reference to it, for interfacing to from C to C++
  	static REmbedInternal *this_pointer;
  private:
--- 30,94 ----
  class REmbedInternal {
  public: 
+ /** constructor. You can't create an instance of this class do to pure virtual functions. Create an instance of REmbed instead. */
  	REmbedInternal();
+ /** destructor */
  	virtual ~REmbedInternal();
! 
! /** Enum specifying types of errors that may occur while parsing/evaluation a command in R */
! 	enum RKWardRError {
! 		NoError=0,			/**< No error */
! 		Incomplete=1,		/**< The command is incomplete. Command was syntactically ok up to given point, but incomplete. It may or may not be semantically correct. */
! 		SyntaxError=2,		/**< Syntax error */
! 		OtherError=3		/**< Other error, usually a semantic error, e.g. object not found */
! 	};
  protected:
+ /** low-level initialization of R
+ @param r_home R_HOME-directory
+ @param argc Number of arguments as would be passed on the commandline to R
+ @param argv Arguments as would be passed on the commandline to R */
  	bool startR (const char* r_home, int argc, char **argv);
+ /** clean shutdown of R. Not yet implemented! (TODO!) */
  	void shutdown ();
+ /** low-level running of a command.
+ @param command char* of the command to be run
+ @param error this will be set to a value in RKWardError depending on success/failure or the command
+ @param print_result whether the R_Visible flag should be set. If true, R will behave mostly as if in a regular console session. Otherwise values
+ will only be printed if called for expressedly with print ("...") or similar. */
  	void runCommandInternal (const char *command, RKWardRError *error, bool print_result=false);
! 
! /** basically a wrapper to runCommandInternal (). Tries to convert the result of the command to an array of char* after running the command. Since
! this will not ever be done for user commands, the R_Visible flag will never be set.
! @param command char* of the command to be run 
! @param count length of array returned
! @param error this will be set to a value in RKWardError depending on success/failure or the command
! @returns an array of char* or 0 on failure
! @see RCommand::GetStringVector */
  	char **getCommandAsStringVector (const char *command, int *count, RKWardRError *error);
+ /** basically a wrapper to runCommandInternal (). Tries to convert the result of the command to an array of double after running the command. Since
+ this will not ever be done for user commands, the R_Visible flag will never be set.
+ @param command char* of the command to be run 
+ @param count length of array returned
+ @param error this will be set to a value in RKWardError depending on success/failure or the command
+ @returns an array of double or 0 on failure
+ @see RCommand::GetRealVector */
  	double *getCommandAsRealVector (const char *command, int *count, RKWardRError *error);
+ /** basically a wrapper to runCommandInternal (). Tries to convert the result of the command to an array of int after running the command. Since
+ this will not ever be done for user commands, the R_Visible flag will never be set.
+ @param command char* of the command to be run 
+ @param count length of array returned
+ @param error this will be set to a value in RKWardError depending on success/failure or the command
+ @returns an array of int or 0 on failure
+ @see RCommand::GetIntVector */
  	int *getCommandAsIntVector (const char *command, int *count, RKWardRError *error);
  public:
  /** call this periodically to make R's x11 windows process their events */
  	static void processX11Events ();
  
! /** The main callback from R to rkward. Since we need QStrings and stuff to handle the requests, this is only a pure virtual function. The real
! implementation is in REmbed::handleSubstackCall () */
  	virtual void handleSubstackCall (char **call, int call_length) = 0;
  	//virtual char **handleGetValueCall (char **call, int call_length, int *reply_length) = 0;
  
! /** only one instance of this class may be around. This pointer keeps the reference to it, for interfacing to from C to C++ */
  	static REmbedInternal *this_pointer;
  private:

Index: rthread.h
===================================================================
RCS file: /cvsroot/rkward/rkward/rkward/rbackend/rthread.h,v
retrieving revision 1.11
retrieving revision 1.12
diff -C2 -d -r1.11 -r1.12
*** rthread.h	19 Sep 2004 17:33:19 -0000	1.11
--- rthread.h	28 Apr 2005 23:41:08 -0000	1.12
***************
*** 35,61 ****
  #define RSTARTUP_ERROR_EVENT 13000
  
! /** encapsulates the R-Backend in a separate thread. Use the inlines in RInterface and see documentation there.
  @author Thomas Friedrichsmeier
  */
  class RThread : public QThread {
  public:
!     RThread (RInterface *parent);
! 
!     ~RThread();
  
! 	void unlock () { locked=false; };
  	void lock () { locked=true; };
  	void kill () { killed = true; };
! 	
  	void doSubstack (char **call, int call_length);
! 	
  	RCommand *current_command;
- 	
- 	void domsleep (int ms) { msleep (ms); };
  protected:
  	void run ();
  private:
  	RInterface *inter;
! /** This is the last step in the chain of committing a command, and actually writes it */
  	void doCommand (RCommand *command);
  	REmbed *embeddedR;
--- 35,97 ----
  #define RSTARTUP_ERROR_EVENT 13000
  
! /** This class represents the thread the R backend is running in. So to speak, this is where the "eventloop" of R is running. The main thing happening
! in this class, is that an infinite loop is running. Whenever there are commands to be executed, those get evaluated. Also, at regular intervals,
! processing of X11-Events in R is triggered. The rest of the time the thread sleeps.
! 
! Actually, there are really two copies of the main loop: The regular one, and a second one which gets run when the R backend has requested some
! task to be carried out. In this case, we might have to run some further child commands in the backend, before we proceed with the commands in
! the main queque. Some thing like:
! 
! - Run some R commands
! 	- R backend asks for some information / action
! 		- potentially some more R commands are needed to accomplish this request
! 			- (additional levels of substacks)
! 		- return the result
! 	- R backend request completed
! - Run some more R commands
! 
! This subordinate/nested eventloop is done in doSubstack ().
! 
! Internally, this class is closely related to REmbed and REmbedInternal, which is where the "real work" is being done. RThread basically just takes care of delegating the work. Also related is RInterface: RThread communicates with RInterface by placing QCustomEvent s, when commands are done
! or when the backend needs information from the frontend.
! 
! Unless you really want to modify the internal workings of the backend, you will want to look at RInterface and use the functions there.
! 
! @see RInterface
! @see REmbed
! @see REmbedInternal
! 
  @author Thomas Friedrichsmeier
  */
  class RThread : public QThread {
  public:
! /** constructor. You need to specify a pointer to the RInterface, so the thread knows where to post its events. Only one RThread should ever be
! created, and that happens in RInterface::RInterface (). */
! 	RThread (RInterface *parent);
! /** destructor */
! 	~RThread();
  
! /** Locks the thread. This is called by RInterface, when the currently running command is to be cancelled. It is used to make sure that the
! backend thread does not proceed with further commands, before the main thread takes notice. @see unlock @see RInterface::cancelCommand */
  	void lock () { locked=true; };
+ /** Unlocks the thread. The thread is initially locked so the main thread can check for some conditions before the backend thread may produce
+ more errors/crashes. Also the thread may get locked when cancelling the currently running command. @see lock */
+ 	void unlock () { locked=false; };
+ /** "Kills" the thread. Actually this just tells the thread that is is about to be terminated. Allows the thread to terminate gracefully */
  	void kill () { killed = true; };
! 
! /** this is a sub-eventloop, being run when the backend request information from the frontend. See \ref RThread for a more detailed description */
  	void doSubstack (char **call, int call_length);
! 
! /** The command currently being executed. This is used from RInterface::cancelCommand to find out, whether the command to be cancelled is
! already/still running. */
  	RCommand *current_command;
  protected:
+ /** the main loop. See \ref RThread for a more detailed description */
  	void run ();
  private:
  	RInterface *inter;
! /** This is the function in which an RCommand actually gets processed. Basically it passes the command to REmbed::doCommand () and sends
! RInterface some events about what is currently happening. */
  	void doCommand (RCommand *command);
  	REmbed *embeddedR;

Index: rinterface.h
===================================================================
RCS file: /cvsroot/rkward/rkward/rkward/rbackend/rinterface.h,v
retrieving revision 1.12
retrieving revision 1.13
diff -C2 -d -r1.12 -r1.13
*** rinterface.h	24 Apr 2005 16:03:48 -0000	1.12
--- rinterface.h	28 Apr 2005 23:41:08 -0000	1.13
***************
*** 31,44 ****
  class RKwardApp;
  
! /** This class does the rather low-level interfacing to the R-processor. The
! 	interface can be used by submitting new commands with issueCommand () (see
! 	the RCommand-class). Your command will then be placed in a first in first
! 	out stack of commands to be executed. If you specified a receiver/slot in the
! 	constructor of the RCommand, you will be notified, when the command has
! 	finished.
  
  	Note that since communication with R is asynchronous, there is no way to get
  	R-output within the same function, the request is submitted. You have to
! 	provide a callback-slot, if you're interested in the output. (@see RCommand)
    *@author Thomas Friedrichsmeier
    */
--- 31,43 ----
  class RKwardApp;
  
! /** This class provides the main interface to the R-processor.
  
  	Note that since communication with R is asynchronous, there is no way to get
  	R-output within the same function, the request is submitted. You have to
! 	provide an RCommandReceiver object, if you're interested in the output.
! 	
! 	For a detailed explanation see \ref UsingTheInterfaceToR .
! 
! 	@see RCommand
    *@author Thomas Friedrichsmeier
    */
***************
*** 46,51 ****
  class RInterface : public QObject {
  	Q_OBJECT
! public: 
  	RInterface();
  	~RInterface();
  
--- 45,52 ----
  class RInterface : public QObject {
  	Q_OBJECT
! public:
! /** constructor */
  	RInterface();
+ /** destructor */
  	~RInterface();
  

Index: rembed.h
===================================================================
RCS file: /cvsroot/rkward/rkward/rkward/rbackend/rembed.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -C2 -d -r1.6 -r1.7
*** rembed.h	7 Sep 2004 13:45:24 -0000	1.6
--- rembed.h	28 Apr 2005 23:41:08 -0000	1.7
***************
*** 26,52 ****
  class RThread;
  
! /** This class (together with its base class REmbedInternal) takes care of the
  	communication with the R-backend. It should only be used encapsulated in a thread, so
  	commands get executed non-blocking.
  	Only one REmbed-object can be used in an application.
  	Don't use this class in RKWard directly. Use the interface provided by RInterface, instead.
! 	REmbed should really be merged with RThread. Don't wonder about strange up-and-down calls.
  @author Thomas Friedrichsmeier
  */
  class REmbed : public REmbedInternal {
  public:
!     REmbed (RThread *thread);
  
!     ~REmbed ();
! 	
  	void runCommand (RCommand *command);
  	
! 	enum InitStatus { Ok=0, LibLoadFail=1, SinkFail=2, OtherFail=4 };
! 	
! 	/** initializes the R-backend. Returns an error-code that consists of a bit-wise or-conjunction of the InitStatus-enum. 0 on success.
! 	Note that you should call initialize only once in a application */
  	int initialize ();
  	
! /// these functions are public for technical reasons, only. Don't use except from REmbedInternal!
  	void handleSubstackCall (char **call, int call_length);
  	//char **handleGetValueCall (char **call, int call_length, int *reply_length);
--- 26,66 ----
  class RThread;
  
! /** This class (together with its base class REmbedInternal) takes care of the low level
  	communication with the R-backend. It should only be used encapsulated in a thread, so
  	commands get executed non-blocking.
+ 
  	Only one REmbed-object can be used in an application.
+ 
  	Don't use this class in RKWard directly. Use the interface provided by RInterface, instead.
! 	REmbed could really be merged with RThread. Don't wonder about strange up-and-down calls.
! 	Also REmbed and REmbedInternal are only separate for technical reasons (R-includes and Qt-includes clashing).
! 
  @author Thomas Friedrichsmeier
  */
  class REmbed : public REmbedInternal {
  public:
! /** constructor. You need to specify a pointer to the parent thread. Don't create REmbed-instances. There should only ever be one instance of
! REmbed and that is created in RThread::RThread */
! 	REmbed (RThread *thread);
! /** destructor */
! 	~REmbed ();
  
! /** runs the specified RCommand immediately. Also adds some information on the success/failure/status to the RCommand after running. */
  	void runCommand (RCommand *command);
+ 
+ /** An enum describing whether initialization of the embedded R-process went well, or what errors occurred. */
+ 	enum InitStatus {
+ 		Ok=0,					/**< No error */
+ 		LibLoadFail=1,		/**< Error while trying to load the rkward R package */
+ 		SinkFail=2,			/**< Error while redirecting R's stdout and stderr to files to be read from rkward */
+ 		OtherFail=4			/**< Other error while initializing the embedded R-process */
+ 	};
  	
! /** initializes the R-backend. Returns an error-code that consists of a bit-wise or-conjunction of the REmbed::InitStatus -enum, REmbed::Ok on success.
! Note that you should call initialize only once in a application */
  	int initialize ();
  	
! /** this function is public for technical reasons, only. Don't use except from REmbedInternal! Called from REmbedInternal when the R backend
! places a call to the frontend. The call will be directly passed up to RThread::doSubstack (). */
  	void handleSubstackCall (char **call, int call_length);
  	//char **handleGetValueCall (char **call, int call_length, int *reply_length);





More information about the rkward-tracker mailing list