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/// @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