[rkward-cvs] rkward/rkward/rbackend rcommand.h,1.11,1.12 rcommandstack.h,1.2,1.3 rinterface.cpp,1.17,1.18 rinterface.h,1.8,1.9

Thomas Friedrichsmeier tfry at users.sourceforge.net
Thu Apr 21 19:57:15 UTC 2005


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

Modified Files:
	rcommand.h rcommandstack.h rinterface.cpp rinterface.h 
Log Message:
Some further API-documentation updates

Index: rcommand.h
===================================================================
RCS file: /cvsroot/rkward/rkward/rkward/rbackend/rcommand.h,v
retrieving revision 1.11
retrieving revision 1.12
diff -C2 -d -r1.11 -r1.12
*** rcommand.h	18 Apr 2005 11:19:11 -0000	1.11
--- rcommand.h	21 Apr 2005 19:57:12 -0000	1.12
***************
*** 84,88 ****
  	The type-parameter is used to indicate the type of command (e.g. direct User input vs. generated by a Plugin vs.
  	command generated by the main application vs. command used merely to sync data back and forth), and also how the command
! 	should retrieve information (as a usual string, or as a data vector). @See RCommand::CommandTypes
  	
  	There are several ways to identify a command when it's finished (needed, if a single RCommandReceiver needs to handle the results of
--- 84,88 ----
  	The type-parameter is used to indicate the type of command (e.g. direct User input vs. generated by a Plugin vs.
  	command generated by the main application vs. command used merely to sync data back and forth), and also how the command
! 	should retrieve information (as a usual string, or as a data vector). @see RCommand::CommandTypes
  	
  	There are several ways to identify a command when it's finished (needed, if a single RCommandReceiver needs to handle the results of
***************
*** 98,107 ****
    
  class RCommand {
! public: 
  	RCommand(const QString &command, int type = 0, const QString &rk_equiv = "", RCommandReceiver *receiver=0, int flags=0);
  	~RCommand();
  	int type () { return _type; };
  	QString rkEquivalent () { return _rk_equiv; };
  	QString command () { return _command; };
  	int id () { return _id; };
  /** TODO: Adjust these two functions to allow re-getting of output and error-messages from logs */
--- 98,119 ----
    
  class RCommand {
! public:
! /** constructs an RCommand.
! @param command The command (string) to be run in the backend. This may include newlines and ";". The command should be a complete statement. If it is an incomplete statement, the backend will not wait for the rest of the command to come in, but rather the command will fail with RCommand::errorIncomplete.
! @param type An integer being the result of a bit-wise OR combination of the values in RCommand::CommandTypes, determining, how the command will be dealt with, and what type of output it will return.
! @param rk_equiv Not yet used: a short descriptive string attached to the RCommand, that allows the user to make some sense of what this command is all about.
! @param receiver The RCommandReceiver this command should be passed on to, when finished.
! @param flags A freely assignable integer, that you can use to identify what the command was all about. Only the RCommandReceiver handling the results will have to know what exactly the flags mean.
! */
  	RCommand(const QString &command, int type = 0, const QString &rk_equiv = "", RCommandReceiver *receiver=0, int flags=0);
  	~RCommand();
+ /** @returns the type as specified in RCommand::RCommand */
  	int type () { return _type; };
+ /** @returns the rk_equiv as specified in RCommand::RCommand */
  	QString rkEquivalent () { return _rk_equiv; };
+ /** @returns the command string (i.e. the input) as specified in RCommand::RCommand */
  	QString command () { return _command; };
+ /** Each RCommand is assigned a unique integer id (incrementing from 0 to integer overflow) upon creation. This returns this id. 
+ 	@returns the unique id of this command */
  	int id () { return _id; };
  /** TODO: Adjust these two functions to allow re-getting of output and error-messages from logs */
***************
*** 109,113 ****
  	QString error () { return _error; };
  /** Types of commands (potentially more to come), bitwise or-able,
! 	although partially exclusive. */
  	enum CommandTypes {User=1, Plugin=2, PluginCom=4, App=8, Sync=16, EmptyCommand=32, GetIntVector=512, GetStringVector=1024, GetRealVector=2048, DirectToOutput=4096, Canceled=8192 };
  	enum CommandStatus {WasTried=1, Failed=2, HasOutput=4, HasError=8, ErrorIncomplete=512, ErrorSyntax=1024, ErrorOther=2048};
--- 121,125 ----
  	QString error () { return _error; };
  /** Types of commands (potentially more to come), bitwise or-able,
! 	although partially exclusive. TODO: find out, why Canceled is in here, and document that fact. */
  	enum CommandTypes {User=1, Plugin=2, PluginCom=4, App=8, Sync=16, EmptyCommand=32, GetIntVector=512, GetStringVector=1024, GetRealVector=2048, DirectToOutput=4096, Canceled=8192 };
  	enum CommandStatus {WasTried=1, Failed=2, HasOutput=4, HasError=8, ErrorIncomplete=512, ErrorSyntax=1024, ErrorOther=2048};

Index: rcommandstack.h
===================================================================
RCS file: /cvsroot/rkward/rkward/rkward/rbackend/rcommandstack.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** rcommandstack.h	18 Apr 2005 11:19:11 -0000	1.2
--- rcommandstack.h	21 Apr 2005 19:57:12 -0000	1.3
***************
*** 33,58 ****
  	~RCommandStack ();
  
! /// add a command to the given chain (static, as it does no matter, which stack the chain belongs to)
  	static void issueCommand (RCommand *command, RCommandChain *chain);
  
! /// add a sub-chain to the given chain (static, as it does no matter, which stack the chain belongs to)
  	static RCommandChain *startChain (RCommandChain *parent);
  /** close the given chain, i.e. signal the chain may be deleted once its remaining commands are done
!  (static, as it does no matter, which stack the chain belongs to).  @Returns the parent of the closed chain. */
  	static RCommandChain *closeChain (RCommandChain *chain);
  
! /// @Returns true, if there are no commands or open chains waiting in this stack
  	bool isEmpty ();
! /// @Returns true, if the currently processed chain is not closed and not empty
  	bool isBlocked ();
! /// @Returns true, if there are commands to be processed in the current chain
  	bool isActive ();
  
! /// removes the RCommand to be processed next from the stack and returns it. If there is no command to process right now, returns 0
  	RCommand *pop ();
  
! /// the regular command stack, i.e. not a callback
  	static RCommandStack *regular_stack;
! /// return the parent RCommandStack of the given RCommandChain
  	static RCommandStack *chainStack (RCommandChain *child);
  private:
--- 33,58 ----
  	~RCommandStack ();
  
! /** add a command to the given chain (static, as it does no matter, which stack the chain belongs to) */
  	static void issueCommand (RCommand *command, RCommandChain *chain);
  
! /** add a sub-chain to the given chain (static, as it does no matter, which stack the chain belongs to) */
  	static RCommandChain *startChain (RCommandChain *parent);
  /** close the given chain, i.e. signal the chain may be deleted once its remaining commands are done
!  (static, as it does no matter, which stack the chain belongs to).  @returns the parent of the closed chain. */
  	static RCommandChain *closeChain (RCommandChain *chain);
  
! /** @returns true, if there are no commands or open chains waiting in this stack */
  	bool isEmpty ();
! /** @returns true, if the currently processed chain is not closed and not empty */
  	bool isBlocked ();
! /** @returns true, if there are commands to be processed in the current chain */
  	bool isActive ();
  
! /** removes the RCommand to be processed next from the stack and returns it. If there is no command to process right now, returns 0 */
  	RCommand *pop ();
  
! /** the regular command stack, i.e. not a callback */
  	static RCommandStack *regular_stack;
! /** return the parent RCommandStack of the given RCommandChain */
  	static RCommandStack *chainStack (RCommandChain *child);
  private:

Index: rinterface.cpp
===================================================================
RCS file: /cvsroot/rkward/rkward/rkward/rbackend/rinterface.cpp,v
retrieving revision 1.17
retrieving revision 1.18
diff -C2 -d -r1.17 -r1.18
*** rinterface.cpp	19 Sep 2004 17:33:19 -0000	1.17
--- rinterface.cpp	21 Apr 2005 19:57:13 -0000	1.18
***************
*** 43,47 ****
  
  extern "C" {
! 	// this is the var in R-space that stores an interrupt
  	extern int R_interrupts_pending;
  }
--- 43,47 ----
  
  extern "C" {
! 	/** this is the var in R-space that stores an interrupt */
  	extern int R_interrupts_pending;
  }
***************
*** 83,87 ****
  void RInterface::issueCommand (const QString &command, int type, const QString &rk_equiv, RCommandReceiver *receiver, int flags, RCommandChain *chain) {
  	RK_TRACE (RBACKEND);
! 	issueCommand (new RCommand (command, type, rk_equiv, receiver, flags), chain);
  }
  
--- 83,88 ----
  void RInterface::issueCommand (const QString &command, int type, const QString &rk_equiv, RCommandReceiver *receiver, int flags, RCommandChain *chain) {
  	RK_TRACE (RBACKEND);
! 	RCommand *command = new RCommand (command, type, rk_equiv, receiver, flags);
! 	issueCommand (command, chain);
  }
  

Index: rinterface.h
===================================================================
RCS file: /cvsroot/rkward/rkward/rkward/rbackend/rinterface.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -C2 -d -r1.8 -r1.9
*** rinterface.h	9 Sep 2004 15:13:13 -0000	1.8
--- rinterface.h	21 Apr 2005 19:57:13 -0000	1.9
***************
*** 78,80 ****
--- 78,174 ----
  };
  
+ /**
+ \page UsingTheInterfaceToR Using the Interface to R
+ \brief An Introduction to using the R-backend: Running commands in R and handling the results
+ 
+ This page tries to give you an introduction into using the RInterface and related classes. You'll learn how to submit a command for evaluation
+ by R and how you can get and handle the results. Note that is fairly low-level. You do not need to read this documentation in order to develop
+ plugins. You'll only need to know this in order to do C++-hacking in rkward.
+ The page is divided into several sections on special problems, but if you're new to rkward, you will probably want to read it as a whole instead of
+ jumping right to those sections.
+ 
+ \section UsingTheInterfaceToRTheSimpleCase The simple case: Fire and forget
+ 
+ In the most simple case, all you want to do is to send a command to be evaluated executed in the R backend, and you are not interested in what
+ happens (whether the command runs successfully, or what the output is). For this, all you need is the following
+ code:
+ 
+ \code
+ #include "rkglobals.h"
+ #include "rbackend/rinterface.h"
+ 
+ RKGlobals::rInter->issueCommand ("print (\"hello world!\")", RCommand::User);
+ \endcode
+ 
+ You will note, that actually there are two RInterface::issueCommand functions, this one is obviously the one taking a QString and several further
+ parameters as argument. It is actually quite similar to the other RInterface::issueCommand function which takes an RCommand as a paramter. This convenience class basically just creates an RCommand with the same parameters as the constructor of RCommand (RCommand::RCommand), and then submits this RCommand. We'll discuss what an RCommand really is further down below. For now a good enough explanations is, that it's simply a container for a command.
+ 
+ The first parameter here, is fairly obvious, the command-string the R backend should evaluate.
+ 
+ The second parameter (RCommand::User) is and integer, which can be a bit-wise or-able combination of the values in the RCommand::CommandTypes enum. We'll deal with the more specific values in that enum later. Here, were just using RCommand::User, which signifies, that the command came
+ directly from the user. This information is fairly important, as it affects the handling of the command at several places: Which color it will be given in
+ the R-command log (currently class RKWatch), whether the command can be cancelled (RCommand::User commands can be cancelled, but some other types of commands can not be cancelled), etc. See the documentation on RCommand::CommandTypes (not yet complete) for more information.
+ 
+ \section UsingTheInterfaceToRHandlingReturns A slightly more realistic example: Handling the result of an RCommand
+ 
+ Most of the time you don't just want to run a command, but you also want to know the result. Now, this is a tad bit more difficult than one might expect at first glance. The reason for this is, that the R backend runs in a separate thread. Hence, whenever you submit a command, it generally does not get executed right away - or at least you just don't know, when exactly it gets executed, and when the result is available. This is neccessary, so (expensive) commands running in the backend do not block operations in the GUI/frontend.
+ 
+ Ok, so how do you get informed, when you command was completed? Using RCommandReceiver. What you will want to do is inherit the class you
+ want to handle the results of RCommands from RCommandReceiver. When finished, the RCommand will be submitted to the (pure virtual) RCommandReceiver::rCommandDone function, which of course you'll have to implement in a meaningful way in your derived class.
+ 
+ The corresponding code would look something like this:
+ 
+ \code
+ #include "rkglobals.h"
+ #include "rbackend/rinterface.h"
+ #include "rbackend/rcommandreceiver.h"
+ 
+ class MyReceiver : public RCommandReceiver {
+ //...
+ protected:
+ /// receives finished RCommands and processes them
+ 	void rCommandDone (RCommand *command);
+ //...
+ private:
+ /// does something by submitting an RCommand
+ 	void someFunction ();
+ //...
+ };
+ 
+ 
+ void MyReceiver::someFunction () {
+ 	RKGlobals::rInter->issueCommand ("print (1+1)", RCommand::App, "", this);
+ }
+ 
+ void MyReceiver::rCommandDone (RCommand *command) {
+ 	if (command->successful ()) {
+ 		qDebug ("Result was %s", command->output ()->utf8 ());
+ 	}
+ }
+ \endcode
+ 
+ First thing to note is, that this time we're passing two additional parameters to RInterface::issueCommand. The first (or rather third) is really not used as of the time of this writing. What it's meant to become is a short descriptive string attached to the RCommand, that allows the user to make some sense of what this command is all about. The other (fourth) is a pointer to an RCommandReceiver that should be informed of the result. In this case, we'll handle the result in the same object that we issued the command from, so we use "this".
+ 
+ So next the RCommand created with RInterface::issueCommand goes on its way to/through the backend (we'll discuss what happens there further down below). Then later, when it has completed its journey, rCommandDone will be called with a pointer to the command as parameter. Now we can use this pointer to retrieve the information we need to know. RCommand::successful and some further simple functions give information about whether the command had any errors and what kind of errors (see RCommand for details). RCommand::output contains the output of the command as a QString (provided the command was successful and had any output). In this case that should be "[1] 2".
+ 
+ \section UsingTheInterfaceToRMultipleCommands Dealing with several RCommands in the same object
+ 
+ \section UsingTheInterfaceToRInternalHandling What happens with and RCommand internally?
+ 
+ \section UsingTheInterfaceToRCommandChains How to ensure commands get executed in the correct order: RCommandChain
+ 
+ \section UsingTheInterfaceToROutputOptions Sending results to the output and retrieving low-level data from the backend
+ 
+ \section UsingTheInterfaceToRFurtherReading Where to find more detailed information on these topics
+ 
+ \section ToBeContinued To be continued
+ This page is still incomplete!
+ 
+ @see RInterface
+ @see RCommand
+ @see RCommandReceiver
+ @see RCommandStack
+ 
+ */
+ 
  #endif





More information about the rkward-tracker mailing list