MezzanineEngine 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
script.h
Go to the documentation of this file.
1 // © Copyright 2010 - 2014 BlackTopp Studios Inc.
2 /* This file is part of The Mezzanine Engine.
3 
4  The Mezzanine Engine is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  The Mezzanine Engine is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with The Mezzanine Engine. If not, see <http://www.gnu.org/licenses/>.
16 */
17 /* The original authors have included a copy of the license specified above in the
18  'Docs' folder. See 'gpl.txt'
19 */
20 /* We welcome the use of the Mezzanine engine to anyone, including companies who wish to
21  Build professional software and charge for their product.
22 
23  However there are some practical restrictions, so if your project involves
24  any of the following you should contact us and we will try to work something
25  out:
26  - DRM or Copy Protection of any kind(except Copyrights)
27  - Software Patents You Do Not Wish to Freely License
28  - Any Kind of Linking to Non-GPL licensed Works
29  - Are Currently In Violation of Another Copyright Holder's GPL License
30  - If You want to change our code and not add a few hundred MB of stuff to
31  your distribution
32 
33  These and other limitations could cause serious legal problems if you ignore
34  them, so it is best to simply contact us or the Free Software Foundation, if
35  you have any questions.
36 
37  Joseph Toppi - toppij@gmail.com
38  John Blackwood - makoenergy02@gmail.com
39 */
40 #ifndef _script_h
41 #define _script_h
42 
43 /// @file
44 /// @brief This file has the interfaces for Scripts and tag derived classes.
45 
46 #include "binarybuffer.h"
47 #include "scriptargument.h"
48 #include "countedptr.h"
49 
50 namespace Mezzanine
51 {
52  namespace Scripting
53  {
54  // Forward Declares
55  class iScriptCompilable;
56  class iScriptMultipleReturn;
57 
58  ///////////////////////////////////////////////////////////////////////////////////////////////////
59  /// @brief The interface for a script
60  /// @details All the methods that all scripts for all languages must implement.
61  /// These are tiny pieces of data that can be run like miniature programs.
62  /// @n @n
63  /// These can be executed by passing them to the appropriate Script Manager.
64  /// @n @n
65  /// This uses multiple inheritance to minimize the amount of features a scripting langauge with need to
66  /// implement. It is expected that a simple scripting language may only need to implement the base
67  /// @ref iScript interface. Other languages that support more features can have their script classes
68  /// multiply inherit from the other classes like
69  ///////////////////////////////////////
71  {
72  public:
73  ///////////////////////////////////////////////////////////////////////////////////////////////////
74  // Work With Arguments
75 
76  /// @brief This adds an argument to be passed to the script.
77  /// @details All arguments added with this are passed in FIFO order to the Script during or just
78  /// before execution. This should normally run in constant time. Some scripting implementations may
79  /// change the order arguments are passed if doing it another way mays more sense.
80  /// @param Arg This accepts a CountedPtr to a script argument and The script shares responsibility with caller for deleting the argument.
81  virtual void AddArgument(CountedPtr<iScriptArgument> Arg) = 0;
82 
83  /// @brief Remove an argument based on a CountedPtr to the script
84  /// @details This searches through the internal list and removes the first entry it finds matching this.
85  /// This should be treated as taking linear time, relative to the total count of arguments assigned to this script, to run.
86  /// This can be used with AddArgument to re-order the way parameters are passed into a script
87  /// @param Arg A CountedPtr matching the one to be removed
88  virtual void RemoveArgument(CountedPtr<iScriptArgument> Arg) = 0;
89 
90  /// @brief Remove a Script argument based on the order it will be passed into the Script at Execution.
91  /// @details This removes the specified Argument from the internal list. This should be treated as taking linear
92  /// time, relative to the total count of arguments assigned to this script, to run.
93  /// @param ArgNumber The number of the Argument to be removed. This behaves similar to an array or vector as it starts counting at 0.
94  virtual void RemoveArgument(Whole ArgNumber) = 0;
95 
96  /// @brief How many arguments have been attached to this script?
97  /// @return A Whole containing the amount of arguments passed in so far.
98  virtual Whole GetArgumentCount() const = 0;
99 
100  /// @brief Remove all the ARGs!!! http://imgur.com/DJhw7
101  /// @details This should run in constant time. It still might be slower than removing and readding just one a few arguments
102  /// in simple cases
103  virtual void ClearArguments() = 0;
104 
105  /// @brief Retrieve a argument previously passed in.
106  /// @param ArgNumber The index of the passed parameter to retrun.
107  /// @return A reference counted pointer to a ScriptArgument.
108  virtual CountedPtr<iScriptArgument> GetArgument(Whole ArgNumber) const = 0;
109 
110  ///////////////////////////////////////////////////////////////////////////////////////////////////
111  // Source of the Script
112 
113  /// @brief Sets the string version of the script.
114  /// @param Code A string that defines the source code to be executed or compiled whne running the script.
115  /// @details It is recomended that when this is called that implentors clear any bytecode or any other compiled
116  /// version of the script. This will prevent issues with mismatched version of source and bytecode.
117  virtual void SetSourceCode(const String& Code) = 0;
118 
119  /// @brief If present this returns the code of script
120  /// @return This will return either an empty @ref String or the code. In cases where bytcode is set it is advised to clear this in implementations.
121  virtual String GetSourceCode() const = 0;
122 
123  ///////////////////////////////////////////////////////////////////////////////////////////////////
124  // Compilation Detection support
125 
126  /// @brief Used to check if there is a bytecode version of the script available.
127  /// @return This will return false on all scripts not implementing ScriptCompilable and only false when the bytecode is already compiled.
128  virtual bool IsCompiled() const
129  { return false; }
130 
131  /// @brief Used to check if this Script supports compilation bytecode.
132  /// @return This will return false on all scripts not implementing ScriptCompilable and on those that do implement it.
133  virtual bool IsCompilable() const
134  { return false; }
135 
136  /// @brief If your only handle to this is a pointer of type @ref iScript this can be called to get a pointer to an @ref iScriptCompilable if it would be valid
137  /// @return A null pointer if this conversion is invalid or a valid pointer to this as an @ref iScriptCompilable if it is valid.
139  { return 0; }
140 
141  /// @copydoc GetAsScriptCompilable
143  { return 0; }
144 
145  ///////////////////////////////////////////////////////////////////////////////////////////////////
146  // Multiple return Detection Support
147 
148  /// @brief Does this script support multiple return values.
149  /// @details Some scripting language support return tuples of values(Python), return an array of values (javascript), returning tables made of records
150  /// which are groups of values(sql), and some allow return an arbitrary number of items that could be tables, or values and allow for tables to contain
151  /// more tables and values(Lua). This allows for checking for an interface to retrieve some of these.
152  /// @return This default implementation returns false, but if the target language supports this it is expected to overload this and return true instead.
153  virtual bool CanReturnMultples()
154  { return false; }
155 
156  /// @brief If your only handle to this is a pointer of type @ref iScript this can be called to get a pointer to an @ref iScriptMultipleReturn if it would be valid
157  /// @return A null pointer if this conversion is invalid or a valid pointer to this as an @ref iScriptMultipleReturn if it is valid.
159  { return 0; }
160 
161  virtual ~iScript(){}
162 
163  ///////////////////////////////////////////////////////////////////////////////////////////////////
164  // Internal Reference count for CountedPtr
165 
166  protected:
167  /// @brief This is the Counter that stores how many references exist
169 
170  public:
171  /// @brief default constructor
172  /// @details Initializes the internal reference counter.
173  iScript() : RefCount(0)
174  {}
175 
176  /// @brief Increase the reference count by one and return the updated count.
177  /// @return The updated count;
179  { return ++RefCount; }
180 
181  /// @brief Decrease the reference count by one and return the updated count.
182  /// @return The updated count;
184  { return --RefCount; }
185 
186  /// @brief Gets the actual pointer to the target.
187  /// @return A Pointer of the targeted type to the object being managed.
189  { return this; }
190 
191  /// @brief Get the current amount of references.
192  /// @return A Whole with the current reference count
194  { return RefCount; }
195 
196  /// @brief Get a pointer to the most Derived type of this class
197  /// @return A pointer of the most derived pointing to this.
199  { return this; }
200  }; // iScript
201  }
202 
203  /// @brief Marks IScript for internal reference counting if a CountedPtr checks
204  template <>
205  class ReferenceCountTraits <Scripting::iScript>
206  {
207  public:
208  /// @brief The Scripting::iScript is its own reference count
210 
211  /// @brief The Construction Pointer for a Scripting::iScript is the pointer created during the New call
212  /// @param Target The pointer returned by new during construction of Scripting::iScript
214  { return Target; }
215 
216  /// @brief This should be cast dynamically when doing conversions inside CountedPtr.
217  enum { IsCastable = CastDynamic };
218  };
219 
220  namespace Scripting
221  {
222 
223  ///////////////////////////////////////////////////////////////////////////////////////////////////
224  /// @brief The interface for a script that can be compiled to bytecode
225  /// @details All the members that all script for all languages must implement that
226  /// support dynamic compilation in the Mezzanine.
227  /// @n @n
228  /// These are tiny pieces of data that can be run like miniature programs. In some cases
229  /// they will be compiled to a bytecode that can swiftly be executed by the appropriate
230  /// bytecode interpretter. This is generally faster than interpretting text, but slower than
231  /// running machine code.
232  /// @n @n
233  /// This class is designed for use with multiple inheritance. If a script returns true from
234  /// @ref IsCompilable then its pointer can safely be cast to a ScriptCompilable pointer.
235  /// @todo Add sample code of safe cast in ScriptCompilable, becuase that is kinda wierd.
236  /// @todo Put the Virtual inheritance back into the this class
237  ///////////////////////////////////////
238  class MEZZ_LIB iScriptCompilable : public virtual iScript
239  {
240  public:
241 
242  /// @brief Set the bytecode used when this script is executed.
243  /// @param Code The Binary version of the script
244  /// @details This is what will be executed. No reverse compiling support is provided, so it is advisable
245  /// that implementations of this either clear the source code or set it to the source that matches the
246  /// compiled binary.
247  virtual void SetByteCode(BinaryTools::BinaryBuffer Code) = 0;
248 
249  /// @brief Get the compiled version of the code if it is available.
250  /// @return If there is valid byte code this will retrieve that, otherwise this will return an empty bytecode.
251  virtual BinaryTools::BinaryBuffer GetByteCode() const = 0;
252 
253  /// @brief Has this script already been compiled into a bytecode.
254  /// @return True if there is bytecode available false otherwise.
255  virtual bool IsCompiled() const = 0;
256 
257  /// @brief Any script implementing this class is compilable.
258  /// @return returns true.
259  virtual bool IsCompilable() const
260  { return true; }
261 
263  { return this; }
264 
265  /// @brief Get a pointer to the most Derived type of this class
266  /// @return A pointer of the most derived pointing to this.
268  { return this; }
269 
270  virtual ~iScriptCompilable(){}
271  };
272  }
273 
274  /// @brief Marks iScriptCompilable for internal reference counting if a CountedPtr checks
275  template <>
276  class ReferenceCountTraits <Scripting::iScriptCompilable>
277  {
278  public:
279  /// @brief The Scripting::iScriptCompilable is its own reference count
281 
282  /// @brief The Construction Pointer for a Scripting::iScriptCompilable is the pointer created during the New call
283  /// @param Target The pointer returned by new during construction of Scripting::iScript
285  { return Target; }
286 
287  /// @brief This should be cast dynamically when doing conversions inside CountedPtr.
288  enum { IsCastable = CastDynamic };
289  };
290 
291  namespace Scripting
292  {
293  /// @brief A group of arguments that can be returned from some scripts
294  /// @details A vector is used to preserve ordering of returns for languages that support multiple returns in order
295  typedef std::vector< CountedPtr<iScriptArgument> > ArgumentGroup;
296 
297  /// @brief This script can return simple group of values.
298  /// @details This loosely correlates to a tuple like the simple returns
299  /// in Lua or any return in Python. This cannot handle returns that include
300  /// tuples that contain tuples in a graceful way.
301  class MEZZ_LIB iScriptMultipleReturn : public virtual iScript
302  {
303  public:
304  /// @brief Does this script support multiple return values.
305  /// @return Any implementation of this returns true.
306  virtual bool CanReturnMultples() const
307  { return true; }
308 
310  { return this; }
311 
312  /// @brief How many values are being returned
313  /// @return A Whole with the amount of items available to be returned now(from the last script call).
314  virtual Whole GetReturnCount() const = 0;
315 
316  /// @brief Get the returns from the last exection of the script
317  /// @return An ArgumentSet that can be iterated over to get all the values returned.
318  virtual ArgumentGroup GetAllReturns() const = 0;
319 
320  /// @brief Add another value to be returned.
321  /// @param A copy assignable script argument that conveys type information to the specific language runtime
322  /// @details Some scripting languages (Lua51) require knowledge of the return types
323  /// of the scripts in order to extract them from the language runtime. Pointers to
324  /// classes derived from iScriptArgument should convey that typing information to
325  /// such language runtimes.
326  virtual void AddReturn(CountedPtr<iScriptArgument> ReturnArg) = 0;
327 
328  /// @brief Get a pointer to the most Derived type of this class
329  /// @return A pointer of the most derived pointing to this.
331  { return this; }
332 
333  virtual ~iScriptMultipleReturn(){}
334  };
335  }
336 
337  /// @brief Marks iScriptMultipleReturn for internal reference counting if a CountedPtr checks
338  template <>
339  class ReferenceCountTraits <Scripting::iScriptMultipleReturn>
340  {
341  public:
342  /// @brief The Scripting::iScriptMultipleReturn is its own reference count
344 
345  /// @brief The Construction Pointer for a Scripting::iScriptMultipleReturn is the pointer created during the New call
346  /// @param Target The pointer returned by new during construction of Scripting::iScript
348  { return Target; }
349 
350  /// @brief This should be cast dynamically when doing conversions inside CountedPtr.
351  enum { IsCastable = CastDynamic };
352  };
353 
354 }//Mezzanine
355 
356 
357 
358 #endif // \_script_h