About
User Reference
C++ API
luafaudes
Developer
Links
libFAUDES online
libFAUDES

Sections

Index

lbp_function.h

Go to the documentation of this file.
00001 /** @file lbp_function.h luafaudes class to run scripts as rti functions */
00002 
00003 /* FAU Discrete Event Systems Library (libfaudes)
00004 
00005 Copyright (C) 2010 Thomas Moor
00006 
00007 This library is free software; you can redistribute it and/or
00008 modify it under the terms of the GNU Lesser General Public
00009 License as published by the Free Software Foundation; either
00010 version 2.1 of the License, or (at your option) any later version.
00011 
00012 This library is distributed in the hope that it will be useful,
00013 but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015 Lesser General Public License for more details.
00016 
00017 You should have received a copy of the GNU Lesser General Public
00018 License along with this library; if not, write to the Free Software
00019 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
00020 
00021 
00022 #ifndef FAUDES_LBPFUNCTION_H
00023 #define FAUDES_LBPFUNCTION_H
00024 
00025 #include "corefaudes.h"
00026 
00027 // forward
00028 struct lua_State;
00029 
00030 namespace faudes{
00031 
00032 // forward
00033 class LuaFunction;
00034 class LuaState;
00035 
00036 /**
00037  * A LuaFunctionDefinition is derived from FaunctionDefinition to
00038  * define a faudes-function by a Lua script. Thus, it has
00039  * the Lua code as an additional member variable and uses a LuaFunction as a
00040  * prototype object. In particular, LuaFunctionDefinitions are allways
00041  * valid in the sense that hey have a prototype. The LuaFunction object 
00042  * implements DoTypeCheck and DoExecute to run the specifed Lua code. 
00043  *
00044  * The token io format is demonstrated by the
00045  * following example:
00046  *
00047  * @code
00048  * <LuaFunctionDefinition name="LuaExtension::LargeGenerator">
00049  * 
00050  * <Documentation> 
00051  * Construct a generator by random.
00052  * </Documentation>
00053  * <Keywords> "luaextension" "example" </Keywords>
00054  *
00055  * <VariantSignatures>
00056  * <Signature name="LargeGen(#Q,#Sigma,GRes)">
00057  * <Parameter name="SizeQ"      ftype="Integer"   access="In"/>
00058  * <Parameter name="SizeSigma"  ftype="Integer"   access="In"/>
00059  * <Parameter name="Res"        ftype="Generator" access="Out" />
00060  * </Signature>
00061  * </VariantSignatures>
00062  * 
00063  * <LuaCode> 
00064  * <[CDATA[
00065  * 
00066  * -- Extension reports on loading
00067  * print('loading luaextension "LargeGenerator"')
00068  *
00069  * -- Define my function (mangled version of variant name)
00070  * function LargeGen_Q_Sigma_GRes(qn,sn,gen)
00071  *
00072  * -- Function reports on execution 
00073  * print(string.format('LargeGen(...): qn=%d sn=%d',qn,sn))
00074  *
00075  * -- Exeution code
00076  * gen:Clear()
00077  * for i=1,qn do
00078  *   gen:InsState(i)
00079  * end
00080  * for i=1,sn do 
00081  *   gen:InsEvent(string.format('ev_%d',i))
00082  * end
00083  *
00084  * -- Done
00085  * return 
00086  * 
00087  * -- End of function definition
00088  * end
00089  * 
00090  * -- Extension reports on loading
00091  * print('loading luaextension: done')
00092  * 
00093  * ]]>
00094  * </LuaCode>
00095  * 
00096  * </LuaFunctionDefinition>
00097  * @endcode
00098  *
00099  * Restrictions and conventions:
00100  * - Type-checking is done via the Cast() function of the faudes Type interface. As a 
00101  *   consequence, you may only use types that are registered with the run-time-interface.
00102  * - On execution, the LuaFunction instance has to locate the respective function 
00103  *   in the supplied lua code. In order to allow for multiple variants, the convention is
00104  *   to have one lua function each with the name of the corresponding variant. Since
00105  *   variant names may contain funny characters, name matching is performed after
00106  *   so called mangeling: any sequence of non-alpha-numerics is replaced by a single "_",
00107  *   a trailing "_" is dropped. E.g. the variant "res=a+b" matches the Lua function "res_a_b".
00108  * - Parameters other than elementary (integer, boolean and string) are passed to 
00109  *   the Lua function by reference. However, Lua will consistently interpret the reference itself 
00110  *   as a parameter value. Thus, to assign a value to an <tt>access="Out"</tt> or <tt>access="InOut"</tt>
00111  *   parameter, you must use the assigment memberfunction Assign (as opposed to the assignment operator "=").
00112  * - Elementary types (i.e. integers, booleans and strings) are passed to the Lua function by value.
00113  *   Thus, it would be pointless to have an elementary typed parameter with access attribute other than 
00114  *   <tt>access="In"</tt>. In order to implement elementary typed return values, the respective 
00115  *   Lua function must return the corresponding values by an approriate return statement. The signature
00116  *   should indicate this by the attribute <tt>creturn="true"</tt>. The current implementation
00117  *   will automatically imply <tt>creturn="true"</tt> for any <tt>access="Out"</tt> or 
00118  *   <tt>access="InOut"</tt>.
00119  * - Since luafaudes has no concept of const references, it is the responsability of the
00120  *   script programer to respect parameter <tt>access=</tt> attribute. 
00121  *
00122  *
00123  *
00124  * @ingroup LuabindingsPlugin
00125  */
00126 
00127 class LuaFunctionDefinition : public FunctionDefinition {
00128 
00129   // faudes type
00130   FAUDES_TYPE_DECLARATION(LuaFunctionDefinition,LuaFunctionDefinition,FunctionDefinition)
00131 
00132 public:
00133 
00134   /** 
00135    * Constructor. 
00136    *
00137    * In contrast to the std FunctionDefinition, the default constructor 
00138    * sets up a valid lua function definition with a newly created LuaFunction 
00139    * as prototype.
00140    * Of course, you will need to set the signatures and the lua code
00141    * to obtain an operational function.
00142    */
00143   LuaFunctionDefinition(const std::string& name="");
00144 
00145   /** 
00146    * Copy constructor 
00147    */
00148   LuaFunctionDefinition(const LuaFunctionDefinition& rSrc);
00149 
00150   /**
00151    * Destructor
00152    */
00153   virtual ~LuaFunctionDefinition(void){};
00154 
00155 
00156   /**
00157    * Clear documentation-data, signature and script (keep prototype)
00158    */
00159   void Clear(void);
00160 
00161   /**
00162    * Get Lua code
00163    * 
00164    * @return
00165    *   Lua code as std string
00166    */
00167   const std::string& LuaCode(void) const;
00168 
00169   /**
00170    * Set Lua code
00171    * 
00172    * @param rCode
00173    *   Lua code as std string
00174    */
00175   void LuaCode(const std::string& rCode);
00176 
00177   /**
00178    * Set default lua state.
00179    *
00180    * Sets the default lua state on which functions that refer to
00181    * this function definition will use for execution. 
00182    * If set to NULL (e.g. on consruction), the
00183    * global state is used. However, the function object
00184    * itself may overwrite the default.
00185    * 
00186    * @param pL
00187    *   Lua state
00188    */
00189   void DefaultL(LuaState* pL);
00190 
00191   /**
00192    * Get default lua state.
00193    * 
00194    *
00195    * @return
00196    *   Lua state
00197    */
00198   LuaState* DefaultL(void) const;
00199 
00200   /**
00201    * Syntax check lua code.
00202    *
00203    * This routine instantiates a LuaFunction from this function definition
00204    * and does all it needs to run the script, except to invoke the any of the
00205    * variant functions. The reasoning is, that the script may hang and, thus, 
00206    * never return. Errors are indicated by an exception.
00207    * 
00208    * @return
00209    *   Error message as string, or empty string on success
00210    */
00211   std::string SyntaxCheck(void);
00212 
00213   /**
00214    * Install this function to a Lua state
00215    * 
00216    * This routine installs the Lua code of this function
00217    * definition to the table "faudes" of the specified Lua state.
00218    * It also constructs a wrapper function
00219    * to dispatch signatures and palces this in the table "faudes".
00220    * Effectively, the resulting Lua state is prepared to execute the
00221    * Lua function with the same semantics as used for SWIG generated wrappers
00222    * of C++ functions.
00223    *
00224    * @param pL
00225    *   Reference to the Lua state
00226    */
00227   void Install(LuaState* pL) const;
00228 
00229   /**
00230    * Install this function to a Lua state.
00231    *
00232    * Alternative signature for applications that do not use the
00233    * the LuaState wrapper class. See also Install(LuaState*).
00234    *
00235    * @param pLL
00236    *   Reference to the Lua state
00237    */
00238   void Install(lua_State* pLL) const;
00239 
00240 
00241 protected:
00242 
00243   /**
00244    * Std faudes type interface: assignment.
00245    *
00246    * @param rSrc 
00247    *    Source to copy from
00248    * @return Reference to this object.
00249    */
00250   virtual void DoAssign(const LuaFunctionDefinition& rSrc);
00251 
00252   /**
00253    * Std faudes type interface: test equality
00254    * 
00255    * @param rOther 
00256    *    Other object to compare with.
00257    * @return 
00258    *   True on match.
00259    */
00260   virtual bool DoEqual(const LuaFunctionDefinition& rOther) const;
00261 
00262   /**
00263    * Read configuration data of this object from TokenReader.
00264    * Actual reading is done by DoReadCore.
00265    *
00266    * The section defaults to "LuaFunctionDefinition", context ignored.
00267    *
00268    * @param rTr
00269    *   TokenReader to read from
00270    * @param rLabel
00271    *   Section to read
00272    * @param pContext
00273    *   Read context to provide contextual information (ignored)
00274    *
00275    * @exception Exception
00276    *   - Token mismatch (id 50, 51, 52)
00277    *   - IO error (id 1)
00278    */
00279   virtual void DoRead(TokenReader& rTr,  const std::string& rLabel = "", const Type* pContext=0);
00280  
00281   /**
00282    * Read configuration data of this object from TokenReader.
00283    *
00284    * This method reads members only, it does not read the section.
00285    *
00286    * @param rTr
00287    *   TokenReader to read from
00288    *
00289    * @exception Exception
00290    *   - Token mismatch (id 50, 51, 52)
00291    *   - IO error (id 1)
00292    */
00293   virtual void DoReadCore(TokenReader& rTr);
00294  
00295   /**
00296    * Write configuration data of this object to TokenWriter.
00297    *
00298    * The section defaults to "LuaFunctionDefinition", context ignored.
00299    *
00300    * @param rTw
00301    *   Reference to TokenWriter
00302    * @param rLabel
00303    *   Label of section to write
00304    * @param pContext
00305    *   Write context to provide contextual information
00306    *
00307    * @exception Exception 
00308    *   - IO errors (id 2)
00309    */
00310   virtual void DoWrite(TokenWriter& rTw, const std::string& rLabel="",const Type* pContext=0) const;
00311 
00312   /**
00313    * Write configuration data of this object to TokenWriter.
00314    *
00315    * This method writes plain member data, the section lables are not
00316    * written.
00317    *
00318    * @param rTw
00319    *   Reference to TokenWriter
00320    *
00321    * @exception Exception 
00322    *   - IO errors (id 2)
00323    */
00324   virtual void DoWriteCore(TokenWriter& rTw) const;
00325 
00326 
00327   /**
00328    * Assign prototype object
00329    *
00330    * @param pFunc
00331    *  Function instance
00332    *
00333    */
00334   virtual void Prototype(Function* pFunc);
00335 
00336   /** Typed prototype instance */
00337   LuaFunction* pLuaFunction;
00338 
00339   /** Lua code */
00340   std::string mLuaCode;
00341 
00342   /** Lua file */
00343   std::string mLuaFile;
00344 
00345   /** Default lua state*/
00346   LuaState* pDefaultL;
00347 
00348 }; 
00349 
00350 
00351 /*
00352  * Wrapper class to maintain a Lua state.
00353  * @ingroup LuabindingsPlugin
00354  */
00355 class LuaState {
00356 public:
00357   /*
00358    * Constructor 
00359    */
00360   LuaState(void);   
00361 
00362   /*
00363    * Destructor
00364    */
00365   ~LuaState(void);   
00366 
00367   /*
00368    * Access Lua state.
00369    */
00370   lua_State* LL(void);
00371 
00372   /*
00373    * Convenience global Lua state.
00374    */
00375   static LuaState* G(void);
00376 
00377   /*
00378    * Reinitialize Lua state.
00379    *
00380    * This method reconstructs the internal Lua state.
00381    * Any references become invalid.
00382    */
00383   void Reset(void);
00384 
00385   /*
00386    * Install LuaExtension to Lua state.
00387    * 
00388    * This function instantiates a LuaFunctionDefinition objects from
00389    * the file and uses the Install member function to install each function
00390    * to the specified lua state. Thus, after the extension has been installed,
00391    * the respective Lua functions can be invoked within Lua as if they where
00392    * C++ function with SWIG generated wrappers. 
00393    *
00394    * Note: if you also want to use extension via the run-time-interface, you
00395    * must register them with the FunctionRegistry; see also the static method
00396    * Register(const std::string&).
00397    *
00398    * @param rFilename
00399    *    Source file (typically .flx)
00400    */
00401   void Install(const std::string& rFilename);
00402 
00403   /*
00404    * Initialze.
00405    * 
00406    * Loads std libraries and libFAUDES wrappers.
00407    *
00408    * Note: this static version is provided for applications
00409    * that maintain their lua state themselves. If yo use
00410    * the wrapper class LuaState, you dont need explicit 
00411    * initialisation.
00412    *
00413    * @param pLL
00414    *    Lua state
00415    */
00416   static void Initialize(lua_State* pLL);
00417 
00418   /*
00419    * Install LuaExtension to Lua state.
00420    *
00421    * Note: this static version is provided for applications
00422    * that maintain their lua state themselves. If yo use
00423    * the wrapper class LuaState, you should use the Install(const std::string&) method.
00424    *
00425    * @param pL
00426    *   Target lua state
00427    * @param rFilename
00428    *   Source file
00429    * @ingroup LuabindingsPlugin
00430    */
00431   static void Install(lua_State* pLL, const std::string& rFilename);
00432 
00433   /*
00434    * Register LuaExtension with the run-time-interface.
00435    *
00436    * This convenience method registers all LuaFunctionDefinitions found  
00437    * in an extension file with the FunctionRegistry. Thus, after registration
00438    * you can use the Lua function via the run-time-interface as if they
00439    * where C++ functions.
00440    *
00441    * Note: if you also want to use the provided functions within a Lua interpreter,
00442    * you must also install the extension to a lua state; see also 
00443    * Install(const std::string&).
00444    *
00445    *
00446    * @param rFilename
00447    *   Source file (typically .flx)
00448    */
00449   static void Register(const std::string& rFilename);
00450 
00451 
00452 private:
00453  
00454   // disable copy constructor
00455   LuaState(const LuaState&){};
00456   // lua state
00457   lua_State* mpLL;
00458   // open/close lua state
00459   void Open(void);
00460   void Close(void);
00461 };
00462 
00463 
00464 /**
00465  * A LuaFunction is a faudes-function that executes a luafaudes script. 
00466  *
00467  * LuaFunction is derived from Function and implements the DoTypeCheck and DoExecute
00468  * interface to run the lua code as supplied by the corresponding function defintion.
00469  * Thus, it is considered an error to set the function definition to an object that
00470  * does not cast to a LuaFunctionDefinition.
00471  *
00472  * @ingroup LuabindingsPlugin
00473  */  
00474 
00475 class LuaFunction : public Function {
00476 
00477  public:
00478   /** 
00479    * Constructor. 
00480    * For the function to be operational, a valid reference to the corresponding 
00481    * LuaFunctionDefinition is required. The only exception is the prototype function
00482    * object used in the LuaFunctionDefinition itself. 
00483    */
00484   LuaFunction(const LuaFunctionDefinition* fdef);
00485 
00486   /** Destructor */
00487   ~LuaFunction(void){};
00488 
00489   /**
00490    * Construct on heap.
00491    * Create a new instance of this function class and return pointer.
00492    * The new instance will use the same function definition as this instance.
00493    *
00494    * @return
00495    *  Pointer to faudes::Function instance.
00496    *
00497    */
00498   virtual LuaFunction* New() const;
00499 
00500 
00501   /**
00502    * Set function definition.
00503    * Normally, functions are provided with a function definition on construction.
00504    * The only exception are prototype objects used in function definitions themselfs 
00505    * and in the function registry.
00506    *
00507    * @param fdef
00508    *  Function definition to set.
00509    *
00510    */
00511   void Definition(const FunctionDefinition* fdef);
00512 
00513 
00514   /**
00515    * Get function definition.
00516    *
00517    * @return 
00518    *  Function definition used by this function.
00519    *
00520    */
00521   const LuaFunctionDefinition* Definition(void) const;
00522 
00523 
00524   /**
00525    * Syntax check lua code.
00526    *
00527    * This routine does all it needs to run the script,
00528    * except to invoke the specified function. The reasoning is, that
00529    * the script may hang and, thus, never return. A consequence
00530    * is, that you must set a variant and you must supply parameter 
00531    * values befor checking. You may use AllocateValues() and FreeValues() 
00532    * for this purpose. Errors are indicated by an exception.
00533    *
00534    * Note that the LuaFunctionDefinition provides a convenience wrapper
00535    * that runs the check on all variants and cares about value allocation.
00536    * 
00537    * @exception Exception
00538    *   - Error in Lua script (id 49)
00539    */
00540   void SyntaxCheck(void);
00541 
00542 
00543   /**
00544    * Set lua state
00545    *
00546    * Sets the lua state which this function will use for execution. 
00547    * If set to NULL (e.g. on consruction), the
00548    * function definition's default state will be used. If
00549    * this is not set either, the global state is used.
00550    * 
00551    * @param l
00552    *   Lua state
00553    */
00554   void L(LuaState* l);
00555 
00556   /**
00557    * Get default lua state
00558    *
00559    * @return
00560    *   Lua state
00561    */
00562   LuaState* L(void);
00563 
00564  protected:
00565 
00566   /**
00567    * Method to test the type of an assigned parameter with the
00568    * specified faudes::Signature (i.e. their TypeDefinition label).
00569    *
00570    * Note: this method is called by Function::Execute() before actual function 
00571    * execution via DoExecute(). It may be used to perform a dynamic cast in 
00572    * preparation of DoExecute(). The latter is only called, if all types match.
00573    * 
00574    * @param n
00575    *   Position of parameter to check
00576    * @return
00577    *   True if type matches signature.
00578    *
00579    * @exception Exception
00580    *  - Signature undefined (id 48)
00581    *  - Parameter number out of range (id 48)
00582    */
00583   virtual bool DoTypeCheck(int n);
00584 
00585   /**
00586    * Executes code as supplied by FunctionDefinition
00587    *
00588    * @exception Exception
00589    *  - Exception during lua setup (id 49)
00590    *  - Any exception during execution of script
00591    */
00592   virtual void DoExecute();
00593 
00594   /**
00595    * Execute stages
00596    *
00597    * @exception Exception
00598    *  - Exception during lua setup (id 49)
00599    */
00600   virtual void DoExecuteA();
00601 
00602   /**
00603    * Execute stages
00604    *
00605    * @exception Exception
00606    *  - Exception during lua setup (id 49)
00607    */
00608   virtual void DoExecuteB();
00609 
00610   /**
00611    * Execute stages
00612    *
00613    * @exception Exception
00614    *  - Exception during lua setup (id 49)
00615    *  - Any exception during execution of script
00616    */
00617   virtual void DoExecuteC();
00618 
00619   /**
00620    * Execute stages
00621    *
00622    * @exception Exception
00623    *  - Exception during lua setup (id 49)
00624    */
00625   virtual void DoExecuteD();
00626 
00627   /** Typed reference to definition */
00628   const LuaFunctionDefinition* pLuaFuncDef;
00629 
00630   /** State of Lua interpreter */
00631   LuaState* pL;
00632   lua_State* pLL;
00633   int mFtable;
00634   int mEntryStack;
00635   void* mFType;
00636   std::vector<bool> mLReturn;
00637   std::vector<bool> mLParameter;
00638   int mLReturnCount;
00639   int mLParameterCount;
00640 }; 
00641 
00642 
00643 
00644 
00645 
00646 } // namespace
00647 #endif 

libFAUDES 2.20d --- 2011.04.26 --- c++ source docu by doxygen