2012-09-19 15:15:01 +00:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
// Copyright (c) 2012 GarageGames, LLC
|
|
|
|
|
//
|
|
|
|
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
|
// of this software and associated documentation files (the "Software"), to
|
|
|
|
|
// deal in the Software without restriction, including without limitation the
|
|
|
|
|
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
|
|
|
// sell copies of the Software, and to permit persons to whom the Software is
|
|
|
|
|
// furnished to do so, subject to the following conditions:
|
|
|
|
|
//
|
|
|
|
|
// The above copyright notice and this permission notice shall be included in
|
|
|
|
|
// all copies or substantial portions of the Software.
|
|
|
|
|
//
|
|
|
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
|
|
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
|
|
|
// IN THE SOFTWARE.
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
#ifndef _CONSOLEINTERNAL_H_
|
|
|
|
|
#define _CONSOLEINTERNAL_H_
|
|
|
|
|
|
|
|
|
|
#ifndef _STRINGFUNCTIONS_H_
|
2017-11-06 04:33:32 +00:00
|
|
|
#include "core/strings/stringFunctions.h"
|
2012-09-19 15:15:01 +00:00
|
|
|
#endif
|
|
|
|
|
#ifndef _STRINGTABLE_H_
|
2017-11-06 04:33:32 +00:00
|
|
|
#include "core/stringTable.h"
|
2012-09-19 15:15:01 +00:00
|
|
|
#endif
|
|
|
|
|
#ifndef _CONSOLETYPES_H
|
2017-11-06 04:33:32 +00:00
|
|
|
#include "console/consoleTypes.h"
|
2012-09-19 15:15:01 +00:00
|
|
|
#endif
|
|
|
|
|
#ifndef _CONSOLEOBJECT_H_
|
2017-11-06 04:33:32 +00:00
|
|
|
#include "console/simObject.h"
|
2012-09-19 15:15:01 +00:00
|
|
|
#endif
|
|
|
|
|
#ifndef _DATACHUNKER_H_
|
2017-11-06 04:33:32 +00:00
|
|
|
#include "core/dataChunker.h"
|
2012-09-19 15:15:01 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/// @ingroup console_system Console System
|
|
|
|
|
/// @{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ExprEvalState;
|
|
|
|
|
struct FunctionDecl;
|
|
|
|
|
class CodeBlock;
|
|
|
|
|
class AbstractClassRep;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// A dictionary of function entries.
|
|
|
|
|
///
|
|
|
|
|
/// Namespaces are used for dispatching calls in the console system.
|
|
|
|
|
class Namespace
|
|
|
|
|
{
|
2017-11-06 04:33:32 +00:00
|
|
|
enum {
|
|
|
|
|
MaxActivePackages = 512,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static U32 mNumActivePackages;
|
|
|
|
|
static U32 mOldNumActivePackages;
|
|
|
|
|
static StringTableEntry mActivePackages[MaxActivePackages];
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
StringTableEntry mName;
|
|
|
|
|
StringTableEntry mPackage;
|
|
|
|
|
|
|
|
|
|
Namespace *mParent;
|
|
|
|
|
Namespace *mNext;
|
|
|
|
|
AbstractClassRep *mClassRep;
|
|
|
|
|
U32 mRefCountToParent;
|
|
|
|
|
|
|
|
|
|
const char* mUsage;
|
|
|
|
|
|
|
|
|
|
/// Script defined usage strings need to be cleaned up. This
|
|
|
|
|
/// field indicates whether or not the usage was set from script.
|
|
|
|
|
bool mCleanUpUsage;
|
|
|
|
|
|
|
|
|
|
/// A function entry in the namespace.
|
|
|
|
|
struct Entry
|
|
|
|
|
{
|
|
|
|
|
enum
|
|
|
|
|
{
|
|
|
|
|
ScriptCallbackType = -3,
|
|
|
|
|
GroupMarker = -2,
|
|
|
|
|
InvalidFunctionType = -1,
|
|
|
|
|
ConsoleFunctionType,
|
|
|
|
|
StringCallbackType,
|
|
|
|
|
IntCallbackType,
|
|
|
|
|
FloatCallbackType,
|
|
|
|
|
VoidCallbackType,
|
|
|
|
|
BoolCallbackType
|
2012-09-19 15:15:01 +00:00
|
|
|
};
|
|
|
|
|
|
2017-11-06 04:33:32 +00:00
|
|
|
/// Link back to the namespace to which the entry belongs.
|
|
|
|
|
Namespace* mNamespace;
|
2012-09-19 15:15:01 +00:00
|
|
|
|
2017-11-06 04:33:32 +00:00
|
|
|
/// Next function entry in the hashtable link chain of the namespace.
|
|
|
|
|
Entry* mNext;
|
|
|
|
|
|
|
|
|
|
/// Name of this function.
|
|
|
|
|
StringTableEntry mFunctionName;
|
|
|
|
|
|
|
|
|
|
///
|
|
|
|
|
S32 mType;
|
|
|
|
|
|
|
|
|
|
/// Min number of arguments expected by this function.
|
|
|
|
|
S32 mMinArgs;
|
|
|
|
|
|
|
|
|
|
/// Max number of arguments expected by this function. If zero,
|
|
|
|
|
/// function takes an arbitrary number of arguments.
|
|
|
|
|
S32 mMaxArgs;
|
|
|
|
|
|
|
|
|
|
/// Name of the package to which this function belongs.
|
2012-09-19 15:15:01 +00:00
|
|
|
StringTableEntry mPackage;
|
|
|
|
|
|
2017-11-06 04:33:32 +00:00
|
|
|
/// Whether this function is included only in TORQUE_TOOLS builds.
|
|
|
|
|
bool mToolOnly;
|
|
|
|
|
|
|
|
|
|
/// Usage string for documentation.
|
2012-09-19 15:15:01 +00:00
|
|
|
const char* mUsage;
|
|
|
|
|
|
2017-11-06 04:33:32 +00:00
|
|
|
/// Extended console function information.
|
|
|
|
|
ConsoleFunctionHeader* mHeader;
|
2012-09-19 15:15:01 +00:00
|
|
|
|
2017-11-06 04:33:32 +00:00
|
|
|
/// The compiled script code if this is a script function.
|
|
|
|
|
CodeBlock* mCode;
|
2012-09-19 15:15:01 +00:00
|
|
|
|
2017-11-06 04:33:32 +00:00
|
|
|
/// The offset in the compiled script code at which this function begins.
|
|
|
|
|
U32 mFunctionOffset;
|
2012-09-19 15:15:01 +00:00
|
|
|
|
2017-11-06 04:33:32 +00:00
|
|
|
/// If it's a script function, this is the line of the declaration in code.
|
|
|
|
|
/// @note 0 for functions read from legacy DSOs that have no line number information.
|
|
|
|
|
U32 mFunctionLineNumber;
|
2012-09-19 15:15:01 +00:00
|
|
|
|
2017-11-06 04:33:32 +00:00
|
|
|
union CallbackUnion {
|
|
|
|
|
StringCallback mStringCallbackFunc;
|
|
|
|
|
IntCallback mIntCallbackFunc;
|
|
|
|
|
VoidCallback mVoidCallbackFunc;
|
|
|
|
|
FloatCallback mFloatCallbackFunc;
|
|
|
|
|
BoolCallback mBoolCallbackFunc;
|
|
|
|
|
const char *mGroupName;
|
|
|
|
|
const char *mCallbackName;
|
|
|
|
|
} cb;
|
2012-09-19 15:15:01 +00:00
|
|
|
|
2017-11-06 04:33:32 +00:00
|
|
|
Entry();
|
2012-09-19 15:15:01 +00:00
|
|
|
|
2017-11-06 04:33:32 +00:00
|
|
|
///
|
|
|
|
|
void clear();
|
2012-09-19 15:15:01 +00:00
|
|
|
|
2017-11-06 04:33:32 +00:00
|
|
|
///
|
2021-04-01 01:09:23 +00:00
|
|
|
ConsoleValue execute(S32 argc, ConsoleValue* argv, ExprEvalState* state);
|
2012-09-19 15:15:01 +00:00
|
|
|
|
2017-11-06 04:33:32 +00:00
|
|
|
/// Return a one-line documentation text string for the function.
|
|
|
|
|
String getBriefDescription(String* outRemainingDocText = NULL) const;
|
2012-09-19 15:15:01 +00:00
|
|
|
|
2017-11-06 04:33:32 +00:00
|
|
|
/// Get the auto-doc string for this function. This string does not included prototype information.
|
|
|
|
|
String getDocString() const;
|
2012-09-19 15:15:01 +00:00
|
|
|
|
2017-11-06 04:33:32 +00:00
|
|
|
/// Return a string describing the arguments the function takes including default argument values.
|
|
|
|
|
String getArgumentsString() const;
|
2012-09-19 15:15:01 +00:00
|
|
|
|
2017-11-06 04:33:32 +00:00
|
|
|
/// Return a full prototype string for the function including return type, function name,
|
|
|
|
|
/// and arguments.
|
|
|
|
|
String getPrototypeString() const;
|
|
|
|
|
};
|
2012-09-19 15:15:01 +00:00
|
|
|
|
2017-11-06 04:33:32 +00:00
|
|
|
Entry* mEntryList;
|
2012-09-19 15:15:01 +00:00
|
|
|
|
2017-11-06 04:33:32 +00:00
|
|
|
Entry** mHashTable;
|
2012-09-19 15:15:01 +00:00
|
|
|
|
2017-11-06 04:33:32 +00:00
|
|
|
U32 mHashSize;
|
|
|
|
|
U32 mHashSequence; ///< @note The hash sequence is used by the autodoc console facility
|
|
|
|
|
/// as a means of testing reference state.
|
|
|
|
|
|
|
|
|
|
Namespace();
|
|
|
|
|
~Namespace();
|
|
|
|
|
|
|
|
|
|
void addFunction(StringTableEntry name, CodeBlock* cb, U32 functionOffset, const char* usage = NULL, U32 lineNumber = 0);
|
|
|
|
|
void addCommand(StringTableEntry name, StringCallback, const char *usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL);
|
|
|
|
|
void addCommand(StringTableEntry name, IntCallback, const char *usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL);
|
|
|
|
|
void addCommand(StringTableEntry name, FloatCallback, const char *usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL);
|
|
|
|
|
void addCommand(StringTableEntry name, VoidCallback, const char *usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL);
|
|
|
|
|
void addCommand(StringTableEntry name, BoolCallback, const char *usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL);
|
|
|
|
|
|
|
|
|
|
void addScriptCallback(const char *funcName, const char *usage, ConsoleFunctionHeader* header = NULL);
|
|
|
|
|
|
|
|
|
|
void markGroup(const char* name, const char* usage);
|
|
|
|
|
char * lastUsage;
|
2012-09-19 15:15:01 +00:00
|
|
|
|
2017-11-06 04:33:32 +00:00
|
|
|
/// Returns true if this namespace represents an engine defined
|
|
|
|
|
/// class and is not just a script defined class namespace.
|
|
|
|
|
bool isClass() const { return mClassRep && mClassRep->getNameSpace() == this; }
|
|
|
|
|
|
|
|
|
|
void getEntryList(VectorPtr<Entry *> *);
|
|
|
|
|
|
|
|
|
|
/// Return the name of this namespace.
|
|
|
|
|
StringTableEntry getName() const { return mName; }
|
|
|
|
|
|
|
|
|
|
/// Return the superordinate namespace to this namespace. Symbols are inherited from
|
|
|
|
|
/// this namespace.
|
|
|
|
|
Namespace* getParent() const { return mParent; }
|
|
|
|
|
|
|
|
|
|
/// Return the topmost package in the parent hierarchy of this namespace
|
|
|
|
|
/// that still refers to the same namespace. If packages are active and
|
|
|
|
|
/// adding to this namespace, then they will be linked in-between the namespace
|
|
|
|
|
/// they are adding to and its real parent namespace.
|
|
|
|
|
Namespace* getPackageRoot()
|
|
|
|
|
{
|
|
|
|
|
Namespace* walk = this;
|
|
|
|
|
while (walk->mParent && walk->mParent->mName == mName)
|
|
|
|
|
walk = walk->mParent;
|
|
|
|
|
|
|
|
|
|
return walk;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Return the package in which this namespace is defined.
|
|
|
|
|
StringTableEntry getPackage() const { return mPackage; }
|
|
|
|
|
|
|
|
|
|
/// Increase the count on the reference that this namespace
|
|
|
|
|
/// holds to its parent.
|
|
|
|
|
/// @note Must not be called on namespaces coming from packages.
|
|
|
|
|
void incRefCountToParent()
|
|
|
|
|
{
|
|
|
|
|
AssertFatal(mPackage == NULL, "Namespace::incRefCountToParent - Must not be called on a namespace coming from a package!");
|
|
|
|
|
mRefCountToParent++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Decrease the count on the reference that this namespace
|
|
|
|
|
/// holds to its parent.
|
|
|
|
|
/// @note Must not be called on namespaces coming from packages.
|
|
|
|
|
void decRefCountToParent()
|
|
|
|
|
{
|
|
|
|
|
unlinkClass(NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Entry *lookup(StringTableEntry name);
|
|
|
|
|
Entry *lookupRecursive(StringTableEntry name);
|
|
|
|
|
Entry *createLocalEntry(StringTableEntry name);
|
|
|
|
|
void buildHashTable();
|
|
|
|
|
void clearEntries();
|
|
|
|
|
bool classLinkTo(Namespace *parent);
|
|
|
|
|
bool unlinkClass(Namespace *parent);
|
|
|
|
|
void getUniqueEntryLists(Namespace *other, VectorPtr<Entry *> *outThisList, VectorPtr<Entry *> *outOtherList);
|
|
|
|
|
|
|
|
|
|
const char *tabComplete(const char *prevText, S32 baseLen, bool fForward);
|
|
|
|
|
|
|
|
|
|
static U32 mCacheSequence;
|
|
|
|
|
static DataChunker mCacheAllocator;
|
|
|
|
|
static DataChunker mAllocator;
|
|
|
|
|
static void trashCache();
|
|
|
|
|
static Namespace *mNamespaceList;
|
|
|
|
|
static Namespace *mGlobalNamespace;
|
|
|
|
|
|
|
|
|
|
static void init();
|
|
|
|
|
static void shutdown();
|
|
|
|
|
static Namespace *global();
|
|
|
|
|
|
|
|
|
|
static Namespace *find(StringTableEntry name, StringTableEntry package = NULL);
|
|
|
|
|
|
|
|
|
|
static void activatePackage(StringTableEntry name);
|
|
|
|
|
static void deactivatePackage(StringTableEntry name);
|
|
|
|
|
static void deactivatePackageStack(StringTableEntry name);
|
|
|
|
|
static void dumpClasses(bool dumpScript = true, bool dumpEngine = true);
|
|
|
|
|
static void dumpFunctions(bool dumpScript = true, bool dumpEngine = true);
|
|
|
|
|
static void printNamespaceEntries(Namespace * g, bool dumpScript = true, bool dumpEngine = true);
|
|
|
|
|
static void unlinkPackages();
|
|
|
|
|
static void relinkPackages();
|
|
|
|
|
static bool isPackage(StringTableEntry name);
|
|
|
|
|
static U32 getActivePackagesCount();
|
|
|
|
|
static StringTableEntry getActivePackage(U32 index);
|
2012-09-19 15:15:01 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
typedef VectorPtr<Namespace::Entry *>::iterator NamespaceEntryListIterator;
|
|
|
|
|
|
|
|
|
|
class Dictionary
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
|
|
struct Entry
|
|
|
|
|
{
|
2021-04-13 01:26:26 +00:00
|
|
|
friend class Dictionary;
|
|
|
|
|
|
|
|
|
|
enum
|
|
|
|
|
{
|
|
|
|
|
TypeInternalInt = -3,
|
|
|
|
|
TypeInternalFloat = -2,
|
|
|
|
|
TypeInternalString = -1,
|
|
|
|
|
};
|
|
|
|
|
|
2012-09-19 15:15:01 +00:00
|
|
|
StringTableEntry name;
|
|
|
|
|
Entry *nextEntry;
|
2021-04-13 01:26:26 +00:00
|
|
|
S32 type;
|
2012-09-19 15:15:01 +00:00
|
|
|
|
|
|
|
|
typedef Signal<void()> NotifySignal;
|
|
|
|
|
|
|
|
|
|
/// The optional notification signal called when
|
|
|
|
|
/// a value is assigned to this variable.
|
|
|
|
|
NotifySignal *notify;
|
2017-11-06 04:33:32 +00:00
|
|
|
|
2012-09-19 15:15:01 +00:00
|
|
|
/// Usage doc string.
|
|
|
|
|
const char* mUsage;
|
2017-11-06 04:33:32 +00:00
|
|
|
|
2012-09-19 15:15:01 +00:00
|
|
|
/// Whether this is a constant that cannot be assigned to.
|
|
|
|
|
bool mIsConstant;
|
|
|
|
|
|
2021-04-13 01:26:26 +00:00
|
|
|
protected:
|
|
|
|
|
|
|
|
|
|
// NOTE: This is protected to ensure no one outside
|
|
|
|
|
// of this structure is messing with it.
|
|
|
|
|
|
|
|
|
|
#pragma warning( push )
|
|
|
|
|
#pragma warning( disable : 4201 ) // warning C4201: nonstandard extension used : nameless struct/union
|
|
|
|
|
|
|
|
|
|
// An variable is either a real dynamic type or
|
|
|
|
|
// its one exposed from C++ using a data pointer.
|
|
|
|
|
//
|
|
|
|
|
// We use this nameless union and struct setup
|
|
|
|
|
// to optimize the memory usage.
|
|
|
|
|
union
|
|
|
|
|
{
|
|
|
|
|
struct
|
|
|
|
|
{
|
|
|
|
|
char* sval;
|
|
|
|
|
U32 ival; // doubles as strlen when type is TypeInternalString
|
|
|
|
|
F32 fval;
|
|
|
|
|
U32 bufferLen;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct
|
|
|
|
|
{
|
|
|
|
|
/// The real data pointer.
|
|
|
|
|
void* dataPtr;
|
|
|
|
|
|
|
|
|
|
/// The enum lookup table for enumerated types.
|
|
|
|
|
const EnumTable* enumTable;
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#pragma warning( pop ) // C4201
|
|
|
|
|
|
2012-09-19 15:15:01 +00:00
|
|
|
public:
|
|
|
|
|
|
2012-09-23 08:59:48 +00:00
|
|
|
Entry() {
|
|
|
|
|
name = NULL;
|
|
|
|
|
notify = NULL;
|
|
|
|
|
nextEntry = NULL;
|
|
|
|
|
mUsage = NULL;
|
|
|
|
|
mIsConstant = false;
|
2020-05-11 19:40:31 +00:00
|
|
|
mNext = NULL;
|
2012-09-23 08:59:48 +00:00
|
|
|
}
|
2017-11-06 04:33:32 +00:00
|
|
|
|
2012-09-19 15:15:01 +00:00
|
|
|
Entry(StringTableEntry name);
|
|
|
|
|
~Entry();
|
2017-11-06 04:33:32 +00:00
|
|
|
|
2012-09-23 08:59:48 +00:00
|
|
|
Entry *mNext;
|
2017-11-06 04:33:32 +00:00
|
|
|
|
2021-04-13 01:26:26 +00:00
|
|
|
void reset();
|
2012-09-19 15:15:01 +00:00
|
|
|
|
2012-09-23 08:59:48 +00:00
|
|
|
inline U32 getIntValue()
|
2012-09-19 15:15:01 +00:00
|
|
|
{
|
2021-04-13 01:26:26 +00:00
|
|
|
if (type <= TypeInternalString)
|
|
|
|
|
return ival;
|
|
|
|
|
else
|
|
|
|
|
return dAtoi(Con::getData(type, dataPtr, 0, enumTable));
|
2012-09-19 15:15:01 +00:00
|
|
|
}
|
|
|
|
|
|
2012-09-23 08:59:48 +00:00
|
|
|
inline F32 getFloatValue()
|
2012-09-19 15:15:01 +00:00
|
|
|
{
|
2021-04-13 01:26:26 +00:00
|
|
|
if (type <= TypeInternalString)
|
|
|
|
|
return fval;
|
|
|
|
|
else
|
|
|
|
|
return dAtof(Con::getData(type, dataPtr, 0, enumTable));
|
2012-09-19 15:15:01 +00:00
|
|
|
}
|
|
|
|
|
|
2012-09-23 08:59:48 +00:00
|
|
|
inline const char *getStringValue()
|
2012-09-19 15:15:01 +00:00
|
|
|
{
|
2021-04-13 01:26:26 +00:00
|
|
|
if (type == TypeInternalString)
|
|
|
|
|
return sval;
|
|
|
|
|
if (type == TypeInternalFloat)
|
|
|
|
|
return Con::getData(TypeF32, &fval, 0);
|
|
|
|
|
else if (type == TypeInternalInt)
|
|
|
|
|
return Con::getData(TypeS32, &ival, 0);
|
|
|
|
|
else
|
|
|
|
|
return Con::getData(type, dataPtr, 0, enumTable);
|
2012-09-19 15:15:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void setIntValue(U32 val)
|
|
|
|
|
{
|
2017-11-06 04:33:32 +00:00
|
|
|
if (mIsConstant)
|
2012-09-19 15:15:01 +00:00
|
|
|
{
|
2017-11-06 04:33:32 +00:00
|
|
|
Con::errorf("Cannot assign value to constant '%s'.", name);
|
2012-09-19 15:15:01 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2017-11-06 04:33:32 +00:00
|
|
|
|
2021-04-13 01:26:26 +00:00
|
|
|
if (type <= TypeInternalString)
|
|
|
|
|
{
|
|
|
|
|
fval = (F32)val;
|
|
|
|
|
ival = val;
|
|
|
|
|
if (sval != typeValueEmpty)
|
|
|
|
|
{
|
|
|
|
|
dFree(sval);
|
|
|
|
|
sval = typeValueEmpty;
|
|
|
|
|
}
|
|
|
|
|
type = TypeInternalInt;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
const char* dptr = Con::getData(TypeS32, &val, 0);
|
|
|
|
|
Con::setData(type, dataPtr, 0, 1, &dptr, enumTable);
|
|
|
|
|
}
|
2012-09-19 15:15:01 +00:00
|
|
|
|
|
|
|
|
// Fire off the notification if we have one.
|
2017-11-06 04:33:32 +00:00
|
|
|
if (notify)
|
2012-09-19 15:15:01 +00:00
|
|
|
notify->trigger();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void setFloatValue(F32 val)
|
|
|
|
|
{
|
2017-11-06 04:33:32 +00:00
|
|
|
if (mIsConstant)
|
2012-09-19 15:15:01 +00:00
|
|
|
{
|
2017-11-06 04:33:32 +00:00
|
|
|
Con::errorf("Cannot assign value to constant '%s'.", name);
|
2012-09-19 15:15:01 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2017-11-06 04:33:32 +00:00
|
|
|
|
2021-04-13 01:26:26 +00:00
|
|
|
if (type <= TypeInternalString)
|
2012-09-19 15:15:01 +00:00
|
|
|
{
|
2021-04-13 01:26:26 +00:00
|
|
|
fval = val;
|
|
|
|
|
ival = static_cast<U32>(val);
|
|
|
|
|
if (sval != typeValueEmpty)
|
|
|
|
|
{
|
|
|
|
|
dFree(sval);
|
|
|
|
|
sval = typeValueEmpty;
|
|
|
|
|
}
|
|
|
|
|
type = TypeInternalFloat;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
const char* dptr = Con::getData(TypeF32, &val, 0);
|
|
|
|
|
Con::setData(type, dataPtr, 0, 1, &dptr, enumTable);
|
2012-09-19 15:15:01 +00:00
|
|
|
}
|
2017-11-06 04:33:32 +00:00
|
|
|
|
2012-09-19 15:15:01 +00:00
|
|
|
// Fire off the notification if we have one.
|
2017-11-06 04:33:32 +00:00
|
|
|
if (notify)
|
2012-09-19 15:15:01 +00:00
|
|
|
notify->trigger();
|
|
|
|
|
}
|
2021-04-13 01:26:26 +00:00
|
|
|
|
|
|
|
|
void setStringValue(const char* value);
|
2012-09-19 15:15:01 +00:00
|
|
|
};
|
|
|
|
|
|
2012-10-11 20:29:39 +00:00
|
|
|
struct HashTableData
|
|
|
|
|
{
|
|
|
|
|
Dictionary* owner;
|
|
|
|
|
S32 size;
|
|
|
|
|
S32 count;
|
|
|
|
|
Entry **data;
|
|
|
|
|
FreeListChunker< Entry > mChunker;
|
2017-11-06 04:33:32 +00:00
|
|
|
|
|
|
|
|
HashTableData(Dictionary* owner)
|
|
|
|
|
: owner(owner), size(0), count(0), data(NULL) {}
|
2012-10-11 20:29:39 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
HashTableData* hashTable;
|
|
|
|
|
HashTableData ownHashTable;
|
|
|
|
|
ExprEvalState *exprState;
|
|
|
|
|
|
|
|
|
|
StringTableEntry scopeName;
|
|
|
|
|
Namespace *scopeNamespace;
|
|
|
|
|
CodeBlock *code;
|
|
|
|
|
U32 ip;
|
|
|
|
|
|
|
|
|
|
Dictionary();
|
|
|
|
|
~Dictionary();
|
|
|
|
|
|
|
|
|
|
Entry *lookup(StringTableEntry name);
|
|
|
|
|
Entry *add(StringTableEntry name);
|
2017-11-06 04:33:32 +00:00
|
|
|
void setState(ExprEvalState *state, Dictionary* ref = NULL);
|
2012-10-11 20:29:39 +00:00
|
|
|
void remove(Entry *);
|
|
|
|
|
void reset();
|
|
|
|
|
|
2017-11-06 04:33:32 +00:00
|
|
|
void exportVariables(const char *varString, const char *fileName, bool append);
|
|
|
|
|
void exportVariables(const char *varString, Vector<String> *names, Vector<String> *values);
|
|
|
|
|
void deleteVariables(const char *varString);
|
2012-10-11 20:29:39 +00:00
|
|
|
|
|
|
|
|
void setVariable(StringTableEntry name, const char *value);
|
|
|
|
|
const char *getVariable(StringTableEntry name, bool *valid = NULL);
|
|
|
|
|
S32 getIntVariable(StringTableEntry name, bool *valid = NULL);
|
|
|
|
|
F32 getFloatVariable(StringTableEntry name, bool *entValid = NULL);
|
|
|
|
|
|
|
|
|
|
U32 getCount() const
|
|
|
|
|
{
|
2012-09-19 15:15:01 +00:00
|
|
|
return hashTable->count;
|
2012-10-11 20:29:39 +00:00
|
|
|
}
|
|
|
|
|
bool isOwner() const
|
|
|
|
|
{
|
2012-09-19 15:15:01 +00:00
|
|
|
return hashTable->owner;
|
2012-10-11 20:29:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// @see Con::addVariable
|
2017-11-06 04:33:32 +00:00
|
|
|
Entry* addVariable(const char *name,
|
|
|
|
|
S32 type,
|
|
|
|
|
void *dataPtr,
|
|
|
|
|
const char* usage);
|
2012-09-19 15:15:01 +00:00
|
|
|
|
2012-10-11 20:29:39 +00:00
|
|
|
/// @see Con::removeVariable
|
|
|
|
|
bool removeVariable(StringTableEntry name);
|
2012-09-19 15:15:01 +00:00
|
|
|
|
2012-10-11 20:29:39 +00:00
|
|
|
/// @see Con::addVariableNotify
|
2017-11-06 04:33:32 +00:00
|
|
|
void addVariableNotify(const char *name, const Con::NotifyDelegate &callback);
|
2012-09-19 15:15:01 +00:00
|
|
|
|
2012-10-11 20:29:39 +00:00
|
|
|
/// @see Con::removeVariableNotify
|
2017-11-06 04:33:32 +00:00
|
|
|
void removeVariableNotify(const char *name, const Con::NotifyDelegate &callback);
|
2012-09-19 15:15:01 +00:00
|
|
|
|
2012-10-11 20:29:39 +00:00
|
|
|
/// Return the best tab completion for prevText, with the length
|
|
|
|
|
/// of the pre-tab string in baseLen.
|
|
|
|
|
const char *tabComplete(const char *prevText, S32 baseLen, bool);
|
2012-09-19 15:15:01 +00:00
|
|
|
|
2012-10-11 20:29:39 +00:00
|
|
|
/// Run integrity checks for debugging.
|
|
|
|
|
void validate();
|
2012-09-19 15:15:01 +00:00
|
|
|
};
|
|
|
|
|
|
2021-03-30 23:33:19 +00:00
|
|
|
struct ConsoleValueFrame
|
|
|
|
|
{
|
|
|
|
|
ConsoleValue* values;
|
|
|
|
|
bool isReference;
|
|
|
|
|
|
2021-04-02 04:57:49 +00:00
|
|
|
ConsoleValueFrame() : values(NULL), isReference(false)
|
|
|
|
|
{}
|
|
|
|
|
|
2021-03-30 23:33:19 +00:00
|
|
|
ConsoleValueFrame(ConsoleValue* vals, bool isRef)
|
|
|
|
|
{
|
|
|
|
|
values = vals;
|
|
|
|
|
isReference = isRef;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2012-09-19 15:15:01 +00:00
|
|
|
class ExprEvalState
|
|
|
|
|
{
|
|
|
|
|
public:
|
2012-10-11 20:29:39 +00:00
|
|
|
/// @name Expression Evaluation
|
|
|
|
|
/// @{
|
|
|
|
|
|
|
|
|
|
///
|
|
|
|
|
SimObject *thisObject;
|
|
|
|
|
Dictionary::Entry *currentVariable;
|
|
|
|
|
Dictionary::Entry *copyVariable;
|
|
|
|
|
bool traceOn;
|
|
|
|
|
|
|
|
|
|
U32 mStackDepth;
|
2014-12-10 00:33:40 +00:00
|
|
|
bool mShouldReset; ///< Designates if the value stack should be reset
|
|
|
|
|
bool mResetLocked; ///< mShouldReset will be set at the end
|
2012-10-11 20:29:39 +00:00
|
|
|
|
|
|
|
|
ExprEvalState();
|
|
|
|
|
~ExprEvalState();
|
|
|
|
|
|
|
|
|
|
/// @}
|
|
|
|
|
|
|
|
|
|
/// @name Stack Management
|
|
|
|
|
/// @{
|
|
|
|
|
|
|
|
|
|
/// The stack of callframes. The extra redirection is necessary since Dictionary holds
|
|
|
|
|
/// an interior pointer that will become invalid when the object changes address.
|
|
|
|
|
Vector< Dictionary* > stack;
|
|
|
|
|
|
2021-04-03 05:53:40 +00:00
|
|
|
S32 getTopOfStack() { return (S32)mStackDepth; }
|
|
|
|
|
|
2021-03-30 23:33:19 +00:00
|
|
|
Vector< ConsoleValueFrame > localStack;
|
|
|
|
|
ConsoleValueFrame* currentRegisterArray; // contains array at to top of localStack
|
|
|
|
|
|
2012-10-11 20:29:39 +00:00
|
|
|
///
|
|
|
|
|
Dictionary globalVars;
|
|
|
|
|
|
|
|
|
|
void setCurVarName(StringTableEntry name);
|
|
|
|
|
void setCurVarNameCreate(StringTableEntry name);
|
|
|
|
|
|
|
|
|
|
S32 getIntVariable();
|
|
|
|
|
F64 getFloatVariable();
|
|
|
|
|
const char *getStringVariable();
|
|
|
|
|
void setIntVariable(S32 val);
|
|
|
|
|
void setFloatVariable(F64 val);
|
|
|
|
|
void setStringVariable(const char *str);
|
|
|
|
|
|
2021-03-30 23:33:19 +00:00
|
|
|
TORQUE_FORCEINLINE S32 getLocalIntVariable(S32 reg)
|
|
|
|
|
{
|
|
|
|
|
return currentRegisterArray->values[reg].getInt();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TORQUE_FORCEINLINE F64 getLocalFloatVariable(S32 reg)
|
|
|
|
|
{
|
|
|
|
|
return currentRegisterArray->values[reg].getFloat();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TORQUE_FORCEINLINE const char* getLocalStringVariable(S32 reg)
|
|
|
|
|
{
|
|
|
|
|
return currentRegisterArray->values[reg].getString();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TORQUE_FORCEINLINE void setLocalIntVariable(S32 reg, S64 val)
|
|
|
|
|
{
|
|
|
|
|
currentRegisterArray->values[reg].setInt(val);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TORQUE_FORCEINLINE void setLocalFloatVariable(S32 reg, F64 val)
|
|
|
|
|
{
|
|
|
|
|
currentRegisterArray->values[reg].setFloat(val);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TORQUE_FORCEINLINE void setLocalStringVariable(S32 reg, const char* val, S32 len)
|
|
|
|
|
{
|
|
|
|
|
currentRegisterArray->values[reg].setString(val, len);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TORQUE_FORCEINLINE void setLocalStringTableEntryVariable(S32 reg, StringTableEntry val)
|
|
|
|
|
{
|
|
|
|
|
currentRegisterArray->values[reg].setStringTableEntry(val);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void pushFrame(StringTableEntry frameName, Namespace *ns, S32 regCount);
|
2012-10-11 20:29:39 +00:00
|
|
|
void popFrame();
|
|
|
|
|
|
|
|
|
|
/// Puts a reference to an existing stack frame
|
|
|
|
|
/// on the top of the stack.
|
|
|
|
|
void pushFrameRef(S32 stackIndex);
|
2017-11-06 04:33:32 +00:00
|
|
|
|
2012-10-11 20:29:39 +00:00
|
|
|
U32 getStackDepth() const
|
|
|
|
|
{
|
|
|
|
|
return mStackDepth;
|
|
|
|
|
}
|
2017-11-06 04:33:32 +00:00
|
|
|
|
2012-10-11 20:29:39 +00:00
|
|
|
Dictionary& getCurrentFrame()
|
|
|
|
|
{
|
2017-11-06 04:33:32 +00:00
|
|
|
return *(stack[mStackDepth - 1]);
|
2012-10-11 20:29:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// @}
|
2012-09-19 15:15:01 +00:00
|
|
|
|
2012-10-11 20:29:39 +00:00
|
|
|
/// Run integrity checks for debugging.
|
|
|
|
|
void validate();
|
2012-09-19 15:15:01 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
namespace Con
|
|
|
|
|
{
|
|
|
|
|
/// The current $instantGroup setting.
|
|
|
|
|
extern String gInstantGroup;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// @}
|
|
|
|
|
|
|
|
|
|
#endif
|