Torque3D Documentation / _generateds / consoleInternal.h

consoleInternal.h

Engine/source/console/consoleInternal.h

More...

Classes:

class

A dictionary of function entries.

class

A function entry in the namespace.

Namespaces:

namespace

This namespace contains the core of the console functionality.

Public User Defined

VectorPtr< Namespace::Entry * >::iterator
NamespaceEntryListIterator 

Detailed Description

Public User Defined

typedef VectorPtr< Namespace::Entry * >::iterator NamespaceEntryListIterator 
  1
  2//-----------------------------------------------------------------------------
  3// Copyright (c) 2012 GarageGames, LLC
  4//
  5// Permission is hereby granted, free of charge, to any person obtaining a copy
  6// of this software and associated documentation files (the "Software"), to
  7// deal in the Software without restriction, including without limitation the
  8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  9// sell copies of the Software, and to permit persons to whom the Software is
 10// furnished to do so, subject to the following conditions:
 11//
 12// The above copyright notice and this permission notice shall be included in
 13// all copies or substantial portions of the Software.
 14//
 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 21// IN THE SOFTWARE.
 22//-----------------------------------------------------------------------------
 23
 24#ifndef _CONSOLEINTERNAL_H_
 25#define _CONSOLEINTERNAL_H_
 26
 27#ifndef _STRINGFUNCTIONS_H_
 28#include "core/strings/stringFunctions.h"
 29#endif
 30#ifndef _STRINGTABLE_H_
 31#include "core/stringTable.h"
 32#endif
 33#ifndef _CONSOLETYPES_H
 34#include "console/consoleTypes.h"
 35#endif
 36#ifndef _CONSOLEOBJECT_H_
 37#include "console/simObject.h"
 38#endif
 39#ifndef _DATACHUNKER_H_
 40#include "core/dataChunker.h"
 41#endif
 42
 43/// @ingroup console_system Console System
 44/// @{
 45
 46
 47class ExprEvalState;
 48struct FunctionDecl;
 49class CodeBlock;
 50class AbstractClassRep;
 51
 52
 53/// A dictionary of function entries.
 54///
 55/// Namespaces are used for dispatching calls in the console system.
 56class Namespace
 57{
 58   enum {
 59      MaxActivePackages = 512,
 60   };
 61
 62   static U32 mNumActivePackages;
 63   static U32 mOldNumActivePackages;
 64   static StringTableEntry mActivePackages[MaxActivePackages];
 65
 66public:
 67   StringTableEntry mName;
 68   StringTableEntry mPackage;
 69
 70   Namespace *mParent;
 71   Namespace *mNext;
 72   AbstractClassRep *mClassRep;
 73   U32 mRefCountToParent;
 74
 75   const char* mUsage;
 76
 77   /// Script defined usage strings need to be cleaned up. This
 78   /// field indicates whether or not the usage was set from script.
 79   bool mCleanUpUsage;
 80
 81   /// A function entry in the namespace.
 82   struct Entry
 83   {
 84      enum
 85      {
 86         ScriptCallbackType = -3,
 87         GroupMarker = -2,
 88         InvalidFunctionType = -1,
 89         ConsoleFunctionType,
 90         StringCallbackType,
 91         IntCallbackType,
 92         FloatCallbackType,
 93         VoidCallbackType,
 94         BoolCallbackType
 95      };
 96
 97      /// Link back to the namespace to which the entry belongs.
 98      Namespace* mNamespace;
 99
100      /// Next function entry in the hashtable link chain of the namespace.
101      Entry* mNext;
102
103      /// Name of this function.
104      StringTableEntry mFunctionName;
105
106      ///
107      S32 mType;
108
109      /// Min number of arguments expected by this function.
110      S32 mMinArgs;
111
112      /// Max number of arguments expected by this function.  If zero,
113      /// function takes an arbitrary number of arguments.
114      S32 mMaxArgs;
115
116      /// Name of the package to which this function belongs.
117      StringTableEntry mPackage;
118
119      /// Whether this function is included only in TORQUE_TOOLS builds.
120      bool mToolOnly;
121
122      /// Usage string for documentation.
123      const char* mUsage;
124
125      /// Extended console function information.
126      ConsoleFunctionHeader* mHeader;
127
128      /// The compiled script code if this is a script function.
129      CodeBlock* mCode;
130
131      /// The offset in the compiled script code at which this function begins.
132      U32 mFunctionOffset;
133
134      /// If it's a script function, this is the line of the declaration in code.
135      /// @note 0 for functions read from legacy DSOs that have no line number information.
136      U32 mFunctionLineNumber;
137
138      union CallbackUnion {
139         StringCallback mStringCallbackFunc;
140         IntCallback mIntCallbackFunc;
141         VoidCallback mVoidCallbackFunc;
142         FloatCallback mFloatCallbackFunc;
143         BoolCallback mBoolCallbackFunc;
144         const char *mGroupName;
145         const char *mCallbackName;
146      } cb;
147
148      Entry();
149
150      ///
151      void clear();
152
153      ///
154      ConsoleValueRef execute(S32 argc, ConsoleValueRef* argv, ExprEvalState* state);
155
156      /// Return a one-line documentation text string for the function.
157      String getBriefDescription(String* outRemainingDocText = NULL) const;
158
159      /// Get the auto-doc string for this function.  This string does not included prototype information.
160      String getDocString() const;
161
162      /// Return a string describing the arguments the function takes including default argument values.
163      String getArgumentsString() const;
164
165      /// Return a full prototype string for the function including return type, function name,
166      /// and arguments.
167      String getPrototypeString() const;
168   };
169
170   Entry* mEntryList;
171
172   Entry** mHashTable;
173
174   U32 mHashSize;
175   U32 mHashSequence;   ///< @note The hash sequence is used by the autodoc console facility
176                        ///        as a means of testing reference state.
177
178   Namespace();
179   ~Namespace();
180
181   void addFunction(StringTableEntry name, CodeBlock* cb, U32 functionOffset, const char* usage = NULL, U32 lineNumber = 0);
182   void addCommand(StringTableEntry name, StringCallback, const char *usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL);
183   void addCommand(StringTableEntry name, IntCallback, const char *usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL);
184   void addCommand(StringTableEntry name, FloatCallback, const char *usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL);
185   void addCommand(StringTableEntry name, VoidCallback, const char *usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL);
186   void addCommand(StringTableEntry name, BoolCallback, const char *usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL);
187
188   void addScriptCallback(const char *funcName, const char *usage, ConsoleFunctionHeader* header = NULL);
189
190   void markGroup(const char* name, const char* usage);
191   char * lastUsage;
192
193   /// Returns true if this namespace represents an engine defined
194   /// class and is not just a script defined class namespace.
195   bool isClass() const { return mClassRep && mClassRep->getNameSpace() == this; }
196
197   void getEntryList(VectorPtr<Entry*> *);
198
199   /// Return the name of this namespace.
200   StringTableEntry getName() const { return mName; }
201
202   /// Return the superordinate namespace to this namespace. Symbols are inherited from
203   /// this namespace.
204   Namespace* getParent() const { return mParent; }
205
206   /// Return the topmost package in the parent hierarchy of this namespace
207   /// that still refers to the same namespace.  If packages are active and
208   /// adding to this namespace, then they will be linked in-between the namespace
209   /// they are adding to and its real parent namespace.
210   Namespace* getPackageRoot()
211   {
212      Namespace* walk = this;
213      while (walk->mParent && walk->mParent->mName == mName)
214         walk = walk->mParent;
215
216      return walk;
217   }
218
219   /// Return the package in which this namespace is defined.
220   StringTableEntry getPackage() const { return mPackage; }
221
222   /// Increase the count on the reference that this namespace
223   /// holds to its parent.
224   /// @note Must not be called on namespaces coming from packages.
225   void incRefCountToParent()
226   {
227      AssertFatal(mPackage == NULL, "Namespace::incRefCountToParent - Must not be called on a namespace coming from a package!");
228      mRefCountToParent++;
229   }
230
231   /// Decrease the count on the reference that this namespace
232   /// holds to its parent.
233   /// @note Must not be called on namespaces coming from packages.
234   void decRefCountToParent()
235   {
236      unlinkClass(NULL);
237   }
238
239   Entry *lookup(StringTableEntry name);
240   Entry *lookupRecursive(StringTableEntry name);
241   Entry *createLocalEntry(StringTableEntry name);
242   void buildHashTable();
243   void clearEntries();
244   bool classLinkTo(Namespace *parent);
245   bool unlinkClass(Namespace *parent);
246   void getUniqueEntryLists(Namespace *other, VectorPtr<Entry*> *outThisList, VectorPtr<Entry*> *outOtherList);
247
248   const char *tabComplete(const char *prevText, S32 baseLen, bool fForward);
249
250   static U32 mCacheSequence;
251   static DataChunker mCacheAllocator;
252   static DataChunker mAllocator;
253   static void trashCache();
254   static Namespace *mNamespaceList;
255   static Namespace *mGlobalNamespace;
256
257   static void init();
258   static void shutdown();
259   static Namespace *global();
260
261   static Namespace *find(StringTableEntry name, StringTableEntry package = NULL);
262
263   static void activatePackage(StringTableEntry name);
264   static void deactivatePackage(StringTableEntry name);
265   static void deactivatePackageStack(StringTableEntry name);
266   static void dumpClasses(bool dumpScript = true, bool dumpEngine = true);
267   static void dumpFunctions(bool dumpScript = true, bool dumpEngine = true);
268   static void printNamespaceEntries(Namespace * g, bool dumpScript = true, bool dumpEngine = true);
269   static void unlinkPackages();
270   static void relinkPackages();
271   static bool isPackage(StringTableEntry name);
272   static U32 getActivePackagesCount();
273   static StringTableEntry getActivePackage(U32 index);
274};
275
276typedef VectorPtr<Namespace::Entry *>::iterator NamespaceEntryListIterator;
277
278
279
280class Dictionary
281{
282public:
283
284   struct Entry
285   {
286      StringTableEntry name;
287      ConsoleValue value;
288      Entry *nextEntry;
289
290      typedef Signal<void()> NotifySignal;
291
292      /// The optional notification signal called when
293      /// a value is assigned to this variable.
294      NotifySignal *notify;
295
296      /// Usage doc string.
297      const char* mUsage;
298
299      /// Whether this is a constant that cannot be assigned to.
300      bool mIsConstant;
301
302   public:
303
304      Entry() {
305         name = NULL;
306         notify = NULL;
307         nextEntry = NULL;
308         mUsage = NULL;
309         mIsConstant = false;
310         mNext = NULL;
311         value.init();
312      }
313
314      Entry(StringTableEntry name);
315      ~Entry();
316
317      Entry *mNext;
318
319      void reset() {
320         name = NULL;
321         value.cleanup();
322         if (notify)
323            delete notify;
324      }
325
326      inline U32 getIntValue()
327      {
328         return value.getIntValue();
329      }
330
331      inline F32 getFloatValue()
332      {
333         return value.getFloatValue();
334      }
335
336      inline const char *getStringValue()
337      {
338         return value.getStringValue();
339      }
340
341      void setIntValue(U32 val)
342      {
343         if (mIsConstant)
344         {
345            Con::errorf("Cannot assign value to constant '%s'.", name);
346            return;
347         }
348
349         value.setIntValue(val);
350
351         // Fire off the notification if we have one.
352         if (notify)
353            notify->trigger();
354      }
355
356      void setFloatValue(F32 val)
357      {
358         if (mIsConstant)
359         {
360            Con::errorf("Cannot assign value to constant '%s'.", name);
361            return;
362         }
363
364         value.setFloatValue(val);
365
366         // Fire off the notification if we have one.
367         if (notify)
368            notify->trigger();
369      }
370
371      void setStringStackPtrValue(StringStackPtr newValue)
372      {
373         if (mIsConstant)
374         {
375            Con::errorf("Cannot assign value to constant '%s'.", name);
376            return;
377         }
378
379         value.setStringStackPtrValue(newValue);
380
381
382         // Fire off the notification if we have one.
383         if (notify)
384            notify->trigger();
385      }
386
387      void setStringValue(const char *newValue)
388      {
389         if (mIsConstant)
390         {
391            Con::errorf("Cannot assign value to constant '%s'.", name);
392            return;
393         }
394
395         value.setStringValue(newValue);
396
397
398         // Fire off the notification if we have one.
399         if (notify)
400            notify->trigger();
401      }
402   };
403
404   struct HashTableData
405   {
406      Dictionary* owner;
407      S32 size;
408      S32 count;
409      Entry **data;
410      FreeListChunker< Entry> mChunker;
411
412      HashTableData(Dictionary* owner)
413         : owner(owner), size(0), count(0), data(NULL) {}
414   };
415
416   HashTableData* hashTable;
417   HashTableData ownHashTable;
418   ExprEvalState *exprState;
419
420   StringTableEntry scopeName;
421   Namespace *scopeNamespace;
422   CodeBlock *code;
423   U32 ip;
424
425   Dictionary();
426   ~Dictionary();
427
428   Entry *lookup(StringTableEntry name);
429   Entry *add(StringTableEntry name);
430   void setState(ExprEvalState *state, Dictionary* ref = NULL);
431   void remove(Entry *);
432   void reset();
433
434   void exportVariables(const char *varString, const char *fileName, bool append);
435   void exportVariables(const char *varString, Vector<String> *names, Vector<String> *values);
436   void deleteVariables(const char *varString);
437
438   void setVariable(StringTableEntry name, const char *value);
439   const char *getVariable(StringTableEntry name, bool *valid = NULL);
440   S32 getIntVariable(StringTableEntry name, bool *valid = NULL);
441   F32 getFloatVariable(StringTableEntry name, bool *entValid = NULL);
442
443   U32 getCount() const
444   {
445      return hashTable->count;
446   }
447   bool isOwner() const
448   {
449      return hashTable->owner;
450   }
451
452   /// @see Con::addVariable
453   Entry* addVariable(const char *name,
454      S32 type,
455      void *dataPtr,
456      const char* usage);
457
458   /// @see Con::removeVariable
459   bool removeVariable(StringTableEntry name);
460
461   /// @see Con::addVariableNotify
462   void addVariableNotify(const char *name, const Con::NotifyDelegate &callback);
463
464   /// @see Con::removeVariableNotify
465   void removeVariableNotify(const char *name, const Con::NotifyDelegate &callback);
466
467   /// Return the best tab completion for prevText, with the length
468   /// of the pre-tab string in baseLen.
469   const char *tabComplete(const char *prevText, S32 baseLen, bool);
470
471   /// Run integrity checks for debugging.
472   void validate();
473};
474
475class ExprEvalState
476{
477public:
478   /// @name Expression Evaluation
479   /// @{
480
481   ///
482   SimObject *thisObject;
483   Dictionary::Entry *currentVariable;
484   Dictionary::Entry *copyVariable;
485   bool traceOn;
486
487   U32 mStackDepth;
488   bool mShouldReset; ///< Designates if the value stack should be reset
489   bool mResetLocked; ///< mShouldReset will be set at the end
490
491   ExprEvalState();
492   ~ExprEvalState();
493
494   /// @}
495
496   /// @name Stack Management
497   /// @{
498
499   /// The stack of callframes.  The extra redirection is necessary since Dictionary holds
500   /// an interior pointer that will become invalid when the object changes address.
501   Vector< Dictionary*> stack;
502
503   ///
504   Dictionary globalVars;
505
506   void setCurVarName(StringTableEntry name);
507   void setCurVarNameCreate(StringTableEntry name);
508
509   S32 getIntVariable();
510   F64 getFloatVariable();
511   const char *getStringVariable();
512   void setIntVariable(S32 val);
513   void setFloatVariable(F64 val);
514   void setStringVariable(const char *str);
515   void setStringStackPtrVariable(StringStackPtr str);
516   void setCopyVariable();
517
518   void pushFrame(StringTableEntry frameName, Namespace *ns);
519   void popFrame();
520
521   /// Puts a reference to an existing stack frame
522   /// on the top of the stack.
523   void pushFrameRef(S32 stackIndex);
524
525   U32 getStackDepth() const
526   {
527      return mStackDepth;
528   }
529
530   Dictionary& getCurrentFrame()
531   {
532      return *(stack[mStackDepth - 1]);
533   }
534
535   /// @}
536
537   /// Run integrity checks for debugging.
538   void validate();
539};
540
541namespace Con
542{
543   /// The current $instantGroup setting.
544   extern String gInstantGroup;
545}
546
547/// @}
548
549#endif
550