lua++
C:/Documents and Settings/Kalith/My Documents/Programmation/luapp/include/luapp_function.hpp
Go to the documentation of this file.
00001 #ifndef LUAPP_FUNCTION_H
00002 #define LUAPP_FUNCTION_H
00003 
00004 #include "luapp_var.hpp"
00005 #include <utils_refptr.hpp>
00006 #include <utils_wptr.hpp>
00007 #include <map>
00008 
00009 namespace lua
00010 {
00011 class argument;
00012 class function;
00013 
00014 /// Lua data
00015 class data
00016 {
00017 public :
00018 
00019     /// Default constructor
00020     data();
00021 
00022     /// Main constructor
00023     /** \param sName    The name associated to this data
00024     *   \param mLuaType The expected type in Lua
00025     *   \param pParent  A pointer to the argument that'll be using it
00026     *   \note You shouldn't have to call it. Consider using function instead.
00027     */
00028     data(const std::string& sName, type mLuaType, argument* pParent);
00029 
00030     /// gets data from Lua
00031     /** \param pLua   The Lua state to use
00032     *   \param iIndex The index at which to get the value
00033     *   \note Only called on a valid data (expected type is found).
00034     */
00035     void set(state* pLua, int iIndex);
00036 
00037     /// Returns this argument's name.
00038     /** \return This argument's name
00039     */
00040     const std::string& get_name() const;
00041 
00042     /// Returns this argument's value.
00043     /** \return This argument's value
00044     */
00045     const var& get_value() const;
00046 
00047     /// Returns this argument's Lua type.
00048     /** \return This argument's Lua type
00049     */
00050     lua::type get_type() const;
00051 
00052 private :
00053 
00054     std::string sName_;
00055     var         mValue_;
00056     type        mLuaType_;
00057     argument*   pParent_;
00058 };
00059 
00060 /// argument of a Lua glue
00061 /** Used internally by function.<br>
00062 *   If, for some reason, you need to add an argument
00063 *   without using function's interface, please let me
00064 *   know on the forums and I'll try to see what can be
00065 *   done.
00066 */
00067 class argument
00068 {
00069 friend class function;
00070 public :
00071 
00072     /// Constructor.
00073     /** \param sName    The name of this argument (used to print errors in the log)
00074     *   \param mLuaType The expected type in Lua
00075     *   \param pParent  A pointer to the function that'll be using it
00076     */
00077     argument(const std::string& sName, type mLuaType, function* pParent);
00078 
00079     /// Adds an alternative to this argument.
00080     /** \param sName    The name of this alternative argument (used to print errors in the log)
00081     *   \param mLuaType The expected type in Lua
00082     */
00083     void        add(const std::string& sName, type mLuaType);
00084 
00085     /// Returns the associated data.
00086     /** \return The associated data
00087     */
00088     data*       get_data() const;
00089 
00090     /// Returns the value and converts it to a float.
00091     /** \return The value and converts it to a float
00092     */
00093     float       get_number() const;
00094 
00095     /// Returns the value and converts it to a bool.
00096     /** \return The value and converts it to a bool
00097     */
00098     bool        get_bool() const;
00099 
00100     /// Returns the value and converts it to a string.
00101     /** \return The value and converts it to a string
00102     */
00103     std::string get_string() const;
00104 
00105     /// Returns the value as userdata.
00106     /** \return The value as userdata
00107     */
00108     template<class T>
00109     T*          get() const
00110     {
00111         return pLua_->get<T>(pData_->get_value().get<int>());
00112     }
00113 
00114     /// Returns the value and converts it to an int.
00115     /** \return The value and converts it to an int
00116     */
00117     int         get_index() const;
00118 
00119     /// Returns the actual type of this value.
00120     /** \return The actual type of this value
00121     */
00122     type        get_type() const;
00123 
00124     /// Checks if this argument has been provided (in case it is optional).
00125     /** \return 'true' if the user has provided this argument
00126     */
00127     bool        is_provided() const;
00128 
00129     /// Sets this argument's data
00130     /** \param pdata A pointer to the good data
00131     */
00132     void        set_data(data* pdata);
00133 
00134 private :
00135 
00136     /// Checks if this argument has the expected type(s).
00137     /** \param pLua        The Lua state to use
00138     *   \param iIndex      The index to check
00139     *   \param bPrintError Set to 'false' if you don't want that function
00140     *                      to print errors in the log
00141     *   \return 'true' if everything went fine
00142     */
00143     bool        test(state* pLua, int iIndex, bool bPrintError = true);
00144 
00145     bool              bSet_;
00146     data*             pData_;
00147     std::vector<data> lData_;
00148     function*         pParent_;
00149     state*            pLua_;
00150 };
00151 
00152 /// Holds all possible arguments of a Lua function's argument set.
00153 struct argument_list
00154 {
00155     std::map<uint, utils::refptr<argument>> lArg_;
00156     std::map<uint, utils::refptr<argument>> lOptional_;
00157     uint                                    uiRank_;
00158 };
00159 
00160 /// A helper to write Lua glues
00161 /** A glue is a C++ function that is executed
00162 *   in Lua. Due to the way Lua communicates with
00163 *   C++, creating such functions can become boring
00164 *   if you check every argument's type, or if you
00165 *   allow optional arguments, or even two possible
00166 *   types for a single argument.<br>
00167 *   This is done quite easilly with this class.<br>
00168 *   Look at the source code for existing glues to see
00169 *   how things work (UIObject::_SetPoint() is a good
00170 *   example).
00171 */
00172 class function
00173 {
00174 public :
00175 
00176     /// Default constructor.
00177     /** \param sName       The name of your function (used to print errors in the log)
00178     *   \param pLua        The Lua state to use
00179     *   \param uiReturnNbr The maximum number of returned values
00180     *   \note Call this at the beginning of your glue
00181     */
00182     function(const std::string& sName, lua_State* pLua, uint uiReturnNbr = 0u);
00183 
00184     /// Default constructor.
00185     /** \param sName       The name of your function (used to print errors in the log)
00186     *   \param pLua        The Lua state to use
00187     *   \param uiReturnNbr The maximum number of returned values
00188     *   \note Call this at the beginning of your glue
00189     */
00190     function(const std::string& sName, state* pLua, uint uiReturnNbr = 0u);
00191 
00192     /// Destructor.
00193     ~function();
00194 
00195     /// Adds an argument to that function.
00196     /** \param uiIndex    The index of this argument
00197     *   \param sName      The name of this argument (used to print errors in the log)
00198     *   \param mLuaType   The expected type in Lua
00199     *   \param bOptional 'true' if this argument is not essential and can be ommited
00200     *   \note Optional arguments work just like in C++ : if you say argument n is optional,
00201     *         then all the following arguments will have to be optional too.<br>
00202     *         You can add several different arguments with the same index, but they must
00203     *         have different Lua types. The function will then choose the right one acording
00204     *         to the actual Lua type that the user has provided.
00205     */
00206     void               add(uint uiIndex, const std::string& sName, type mLuaType, bool bOptional = false);
00207 
00208     /// Tells the function there is another parameter set that will be provided.
00209     void               new_param_set();
00210 
00211     /// Returns the indice of the paramater set that the user has provided.
00212     /** \return The indice of the paramater set that the user has provided
00213     *   \note Should be called after Check() has been called.
00214     */
00215     uint               get_param_set_rank();
00216 
00217     /// Checks if all the arguments types and retreive them.
00218     /** \param bPrintError If set to 'false', this function will fail
00219     *          silently
00220     *   \return 'true' if everything went fine
00221     *   \note You should always check the return value of this function.
00222     */
00223     bool               check(bool bPrintError = true);
00224 
00225     /// Returns the argument at the provided index.
00226     /** \param uiIndex The index of the argument
00227     *   \return The argument at the provided index
00228     */
00229     utils::wptr<argument> get(uint uiIndex);
00230 
00231     /// Checks if an argument has been provided (in case it is optional).
00232     /** \param uiIndex The index of the argument
00233     *   \return 'true' if the user has provided this argument
00234     *   \note You should always check the return value of this function
00235     *         whenever you want to use an optional argument.
00236     */
00237     bool               is_provided(uint uiIndex) const;
00238 
00239     /// Returns the number of provided arguments.
00240     /** \return The number of provided arguments
00241     *   \note Should be called after Check() has been called.
00242     */
00243     uint               get_argument_count() const;
00244 
00245     /// Adds a return value.
00246     /** \param vValue One of the returned value
00247     *   \note - If you want to return a complex Lua object (a table,
00248     *         a function, ...), <b>you must put it on the
00249     *         stack yourself</b>, and then call Notifypushed();<br>
00250     *         - Values are immediatly pushed onto the Lua stack, so
00251     *         the order in which you return your values is important.<br>
00252     *         - If, for some reason, your can't push one of your return
00253     *         values, push nil instead.<br>
00254     *         - Note that this class will automatically fill the stack with
00255     *         nil until the proper number of return values is reached when
00256     *         Return() is called.
00257     */
00258     void               push(const var& vValue);
00259 
00260     /// Adds nil to the return values.
00261     /** \param uiNbr The number of nil to push
00262     *   \note Calling push(var()) does exactly the same thing. But this
00263     *         function is clearer.
00264     */
00265     void               push_nil(uint uiNbr = 1);
00266 
00267     /// Tells this function you pushed a return value.
00268     /** \note See push for more infos.
00269     */
00270     void               notify_pushed();
00271 
00272     /// ends the function.
00273     /** \return The number of returned values
00274     *   \note Use the return of this function as return value of your glue.<br>
00275     *         Note that this class will automatically fill the stack with
00276     *         nil until the proper number of return values is reached.
00277     */
00278     int                on_return();
00279 
00280     /// Returns the name of this function.
00281     /** \return The name of this function
00282     */
00283     const std::string& get_name() const;
00284 
00285     /// Returns the state used by this function.
00286     /** \return The state used by this function
00287     */
00288     state* get_state() const;
00289 
00290 private :
00291 
00292     std::string                sName_;
00293     state*                     pLua_;
00294     uint                       uiArgumentCount_;
00295     uint                       uiReturnNbr_;
00296     uint                       uiReturnCount_;
00297     std::vector<argument_list> lArgListStack_;
00298     argument_list*             pArgList_;
00299 };
00300 }
00301 
00302 #endif