consoleInternal.h
Engine/source/console/consoleInternal.h
Classes:
class
class
class
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 44/// @ingroup console_system Console System 45/// @{ 46 47 48class ExprEvalState; 49struct FunctionDecl; 50class CodeBlock; 51class AbstractClassRep; 52 53 54/// A dictionary of function entries. 55/// 56/// Namespaces are used for dispatching calls in the console system. 57class Namespace 58{ 59 enum { 60 MaxActivePackages = 512, 61 }; 62 63 static U32 mNumActivePackages; 64 static U32 mOldNumActivePackages; 65 static StringTableEntry mActivePackages[MaxActivePackages]; 66 67 public: 68 StringTableEntry mName; 69 StringTableEntry mPackage; 70 71 Namespace *mParent; 72 Namespace *mNext; 73 AbstractClassRep *mClassRep; 74 U32 mRefCountToParent; 75 76 const char* mUsage; 77 78 /// Script defined usage strings need to be cleaned up. This 79 /// field indicates whether or not the usage was set from script. 80 bool mCleanUpUsage; 81 82 /// A function entry in the namespace. 83 struct Entry 84 { 85 enum 86 { 87 ScriptCallbackType = -3, 88 GroupMarker = -2, 89 InvalidFunctionType = -1, 90 ConsoleFunctionType, 91 StringCallbackType, 92 IntCallbackType, 93 FloatCallbackType, 94 VoidCallbackType, 95 BoolCallbackType 96 }; 97 98 /// Link back to the namespace to which the entry belongs. 99 Namespace* mNamespace; 100 101 /// Next function entry in the hashtable link chain of the namespace. 102 Entry* mNext; 103 104 /// Name of this function. 105 StringTableEntry mFunctionName; 106 107 /// 108 S32 mType; 109 110 /// Min number of arguments expected by this function. 111 S32 mMinArgs; 112 113 /// Max number of arguments expected by this function. If zero, 114 /// function takes an arbitrary number of arguments. 115 S32 mMaxArgs; 116 117 /// Name of the package to which this function belongs. 118 StringTableEntry mPackage; 119 120 /// Whether this function is included only in TORQUE_TOOLS builds. 121 bool mToolOnly; 122 123 /// Usage string for documentation. 124 const char* mUsage; 125 126 /// Extended console function information. 127 ConsoleFunctionHeader* mHeader; 128 129 /// The compiled script code if this is a script function. 130 CodeBlock* mCode; 131 132 /// The offset in the compiled script code at which this function begins. 133 U32 mFunctionOffset; 134 135 /// If it's a script function, this is the line of the declaration in code. 136 /// @note 0 for functions read from legacy DSOs that have no line number information. 137 U32 mFunctionLineNumber; 138 139 union CallbackUnion { 140 StringCallback mStringCallbackFunc; 141 IntCallback mIntCallbackFunc; 142 VoidCallback mVoidCallbackFunc; 143 FloatCallback mFloatCallbackFunc; 144 BoolCallback mBoolCallbackFunc; 145 const char *mGroupName; 146 const char *mCallbackName; 147 } cb; 148 149 Entry(); 150 151 /// 152 void clear(); 153 154 /// 155 ConsoleValueRef execute( S32 argc, ConsoleValueRef* argv, ExprEvalState* state ); 156 157 /// Return a one-line documentation text string for the function. 158 String getBriefDescription( String* outRemainingDocText = NULL ) const; 159 160 /// Get the auto-doc string for this function. This string does not included prototype information. 161 String getDocString() const; 162 163 /// Return a string describing the arguments the function takes including default argument values. 164 String getArgumentsString() const; 165 166 /// Return a full prototype string for the function including return type, function name, 167 /// and arguments. 168 String getPrototypeString() const; 169 }; 170 171 Entry* mEntryList; 172 173 Entry** mHashTable; 174 175 U32 mHashSize; 176 U32 mHashSequence; ///< @note The hash sequence is used by the autodoc console facility 177 /// as a means of testing reference state. 178 179 Namespace(); 180 ~Namespace(); 181 182 void addFunction( StringTableEntry name, CodeBlock* cb, U32 functionOffset, const char* usage = NULL, U32 lineNumber = 0 ); 183 void addCommand( StringTableEntry name, StringCallback, const char *usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL ); 184 void addCommand( StringTableEntry name, IntCallback, const char *usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL ); 185 void addCommand( StringTableEntry name, FloatCallback, const char *usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL ); 186 void addCommand( StringTableEntry name, VoidCallback, const char *usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL ); 187 void addCommand( StringTableEntry name, BoolCallback, const char *usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL ); 188 189 void addScriptCallback( const char *funcName, const char *usage, ConsoleFunctionHeader* header = NULL ); 190 191 void markGroup(const char* name, const char* usage); 192 char * lastUsage; 193 194 /// Returns true if this namespace represents an engine defined 195 /// class and is not just a script defined class namespace. 196 bool isClass() const { return mClassRep && mClassRep->getNameSpace() == this; } 197 198 void getEntryList(VectorPtr<Entry*> *); 199 200 /// Return the name of this namespace. 201 StringTableEntry getName() const { return mName; } 202 203 /// Return the superordinate namespace to this namespace. Symbols are inherited from 204 /// this namespace. 205 Namespace* getParent() const { return mParent; } 206 207 /// Return the topmost package in the parent hierarchy of this namespace 208 /// that still refers to the same namespace. If packages are active and 209 /// adding to this namespace, then they will be linked in-between the namespace 210 /// they are adding to and its real parent namespace. 211 Namespace* getPackageRoot() 212 { 213 Namespace* walk = this; 214 while( walk->mParent && walk->mParent->mName == mName ) 215 walk = walk->mParent; 216 217 return walk; 218 } 219 220 /// Return the package in which this namespace is defined. 221 StringTableEntry getPackage() const { return mPackage; } 222 223 /// Increase the count on the reference that this namespace 224 /// holds to its parent. 225 /// @note Must not be called on namespaces coming from packages. 226 void incRefCountToParent() 227 { 228 AssertFatal( mPackage == NULL, "Namespace::incRefCountToParent - Must not be called on a namespace coming from a package!" ); 229 mRefCountToParent ++; 230 } 231 232 /// Decrease the count on the reference that this namespace 233 /// holds to its parent. 234 /// @note Must not be called on namespaces coming from packages. 235 void decRefCountToParent() 236 { 237 unlinkClass( NULL ); 238 } 239 240 Entry *lookup(StringTableEntry name); 241 Entry *lookupRecursive(StringTableEntry name); 242 Entry *createLocalEntry(StringTableEntry name); 243 void buildHashTable(); 244 void clearEntries(); 245 bool classLinkTo(Namespace *parent); 246 bool unlinkClass(Namespace *parent); 247 void getUniqueEntryLists( Namespace *other, VectorPtr<Entry*> *outThisList, VectorPtr<Entry*> *outOtherList ); 248 249 const char *tabComplete(const char *prevText, S32 baseLen, bool fForward); 250 251 static U32 mCacheSequence; 252 static DataChunker mCacheAllocator; 253 static DataChunker mAllocator; 254 static void trashCache(); 255 static Namespace *mNamespaceList; 256 static Namespace *mGlobalNamespace; 257 258 static void init(); 259 static void shutdown(); 260 static Namespace *global(); 261 262 static Namespace *find(StringTableEntry name, StringTableEntry package=<a href="/coding/file/types_8lint_8h/#types_8lint_8h_1a070d2ce7b6bb7e5c05602aa8c308d0c4">NULL</a>); 263 264 static void activatePackage(StringTableEntry name); 265 static void deactivatePackage(StringTableEntry name); 266 static void deactivatePackageStack(StringTableEntry name); 267 static void dumpClasses( bool dumpScript = true, bool dumpEngine = true ); 268 static void dumpFunctions( bool dumpScript = true, bool dumpEngine = true ); 269 static void printNamespaceEntries(Namespace * g, bool dumpScript = true, bool dumpEngine = true); 270 static void unlinkPackages(); 271 static void relinkPackages(); 272 static bool isPackage(StringTableEntry name); 273 static U32 getActivePackagesCount(); 274 static StringTableEntry getActivePackage(U32 index); 275}; 276 277typedef VectorPtr<Namespace::Entry *>::iterator NamespaceEntryListIterator; 278 279 280 281class Dictionary 282{ 283public: 284 285 struct Entry 286 { 287 StringTableEntry name; 288 ConsoleValue value; 289 Entry *nextEntry; 290 291 typedef Signal<void()> NotifySignal; 292 293 /// The optional notification signal called when 294 /// a value is assigned to this variable. 295 NotifySignal *notify; 296 297 /// Usage doc string. 298 const char* mUsage; 299 300 /// Whether this is a constant that cannot be assigned to. 301 bool mIsConstant; 302 303 public: 304 305 Entry() { 306 name = NULL; 307 notify = NULL; 308 nextEntry = NULL; 309 mUsage = NULL; 310 mIsConstant = false; 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=<a href="/coding/file/types_8lint_8h/#types_8lint_8h_1a070d2ce7b6bb7e5c05602aa8c308d0c4">NULL</a>); 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
