Merge branch 'Preview4_0' of https://github.com/TorqueGameEngines/Torque3D into BugfixQOL_20210909

This commit is contained in:
Areloch 2021-09-10 02:20:13 -05:00
commit dec9f54a9b
322 changed files with 10473 additions and 10241 deletions

View file

@ -40,6 +40,10 @@
#include "assets/assetPtr.h" #include "assets/assetPtr.h"
#endif #endif
#ifndef _SFXSOURCE_H_
#include "sfx/sfxSource.h"
#endif
// Debug Profiling. // Debug Profiling.
#include "platform/profiler.h" #include "platform/profiler.h"
#include "sfx/sfxTypes.h" #include "sfx/sfxTypes.h"
@ -159,7 +163,7 @@ void SoundAsset::initPersistFields()
addField("maxDistance", TypeF32, Offset(mProfileDesc.mMaxDistance, SoundAsset), "Max distance for sound."); addField("maxDistance", TypeF32, Offset(mProfileDesc.mMaxDistance, SoundAsset), "Max distance for sound.");
addField("coneInsideAngle", TypeS32, Offset(mProfileDesc.mConeInsideAngle, SoundAsset), "Cone inside angle."); addField("coneInsideAngle", TypeS32, Offset(mProfileDesc.mConeInsideAngle, SoundAsset), "Cone inside angle.");
addField("coneOutsideAngle", TypeS32, Offset(mProfileDesc.mConeOutsideAngle, SoundAsset), "Cone outside angle."); addField("coneOutsideAngle", TypeS32, Offset(mProfileDesc.mConeOutsideAngle, SoundAsset), "Cone outside angle.");
addField("coneOutsideVolume", TypeS32, Offset(mProfileDesc.mConeOutsideVolume, SoundAsset), "Cone outside volume."); addField("coneOutsideVolume", TypeF32, Offset(mProfileDesc.mConeOutsideVolume, SoundAsset), "Cone outside volume.");
addField("rolloffFactor", TypeF32, Offset(mProfileDesc.mRolloffFactor, SoundAsset), "Rolloff factor."); addField("rolloffFactor", TypeF32, Offset(mProfileDesc.mRolloffFactor, SoundAsset), "Rolloff factor.");
addField("scatterDistance", TypePoint3F, Offset(mProfileDesc.mScatterDistance, SoundAsset), "Randomization to the spacial position of the sound."); addField("scatterDistance", TypePoint3F, Offset(mProfileDesc.mScatterDistance, SoundAsset), "Randomization to the spacial position of the sound.");
addField("sourceGroup", TypeSFXSourceName, Offset(mProfileDesc.mSourceGroup, SoundAsset), "Group that sources playing with this description should be put into."); addField("sourceGroup", TypeSFXSourceName, Offset(mProfileDesc.mSourceGroup, SoundAsset), "Group that sources playing with this description should be put into.");
@ -181,13 +185,7 @@ void SoundAsset::initializeAsset(void)
if (mSoundFile == StringTable->EmptyString()) if (mSoundFile == StringTable->EmptyString())
return; return;
//ResourceManager::get().getChangedSignal.notify(this, &SoundAsset::_onResourceChanged);
//Ensure our path is expando'd if it isn't already
mSoundPath = getOwned() ? expandAssetFilePath(mSoundFile) : mSoundPath; mSoundPath = getOwned() ? expandAssetFilePath(mSoundFile) : mSoundPath;
mSoundPath = expandAssetFilePath(mSoundPath);
loadSound(); loadSound();
} }
@ -208,7 +206,6 @@ void SoundAsset::onAssetRefresh(void)
//Update //Update
mSoundPath = getOwned() ? expandAssetFilePath(mSoundFile) : mSoundPath; mSoundPath = getOwned() ? expandAssetFilePath(mSoundFile) : mSoundPath;
loadSound(); loadSound();
} }
@ -225,7 +222,7 @@ bool SoundAsset::loadSound()
else else
{// = new SFXProfile(mProfileDesc, mSoundFile, mPreload); {// = new SFXProfile(mProfileDesc, mSoundFile, mPreload);
mSFXProfile.setDescription(&mProfileDesc); mSFXProfile.setDescription(&mProfileDesc);
mSFXProfile.setSoundFileName(mSoundFile); mSFXProfile.setSoundFileName(mSoundPath);
mSFXProfile.setPreload(mPreload); mSFXProfile.setPreload(mPreload);
} }
@ -254,11 +251,106 @@ void SoundAsset::setSoundFile(const char* pSoundFile)
refreshAsset(); refreshAsset();
} }
StringTableEntry SoundAsset::getAssetIdByFileName(StringTableEntry fileName)
{
if (fileName == StringTable->EmptyString())
return StringTable->EmptyString();
StringTableEntry materialAssetId = "";
AssetQuery query;
U32 foundCount = AssetDatabase.findAssetType(&query, "SoundAsset");
if (foundCount != 0)
{
for (U32 i = 0; i < foundCount; i++)
{
SoundAsset* soundAsset = AssetDatabase.acquireAsset<SoundAsset>(query.mAssetList[i]);
if (soundAsset && soundAsset->getSoundPath() == fileName)
{
materialAssetId = soundAsset->getAssetId();
AssetDatabase.releaseAsset(query.mAssetList[i]);
break;
}
AssetDatabase.releaseAsset(query.mAssetList[i]);
}
}
return materialAssetId;
}
U32 SoundAsset::getAssetById(StringTableEntry assetId, AssetPtr<SoundAsset>* materialAsset)
{
(*materialAsset) = assetId;
if (materialAsset->notNull())
{
return (*materialAsset)->mLoadedState;
}
else
{
//Well that's bad, loading the fallback failed.
Con::warnf("MaterialAsset::getAssetById - Finding of asset with id %s failed with no fallback asset", assetId);
return AssetErrCode::Failed;
}
}
U32 SoundAsset::getAssetByFileName(StringTableEntry fileName, AssetPtr<SoundAsset>* soundAsset)
{
AssetQuery query;
U32 foundAssetcount = AssetDatabase.findAssetType(&query, "SoundAsset");
if (foundAssetcount == 0)
{
//Well that's bad, loading the fallback failed.
Con::warnf("MaterialAsset::getAssetByMaterialName - Finding of asset associated with filename %s failed with no fallback asset", fileName);
return AssetErrCode::Failed;
}
else
{
for (U32 i = 0; i < foundAssetcount; i++)
{
SoundAsset* tSoundAsset = AssetDatabase.acquireAsset<SoundAsset>(query.mAssetList[i]);
if (tSoundAsset && tSoundAsset->getSoundPath() == fileName)
{
soundAsset->setAssetId(query.mAssetList[i]);
AssetDatabase.releaseAsset(query.mAssetList[i]);
return (*soundAsset)->mLoadedState;
}
AssetDatabase.releaseAsset(query.mAssetList[i]); //cleanup if that's not the one we needed
}
}
//No good match
return AssetErrCode::Failed;
}
DefineEngineMethod(SoundAsset, getSoundPath, const char*, (), , "") DefineEngineMethod(SoundAsset, getSoundPath, const char*, (), , "")
{ {
return object->getSoundPath(); return object->getSoundPath();
} }
DefineEngineMethod(SoundAsset, playSound, S32, (Point3F position), (Point3F::Zero),
"Gets the number of materials for this shape asset.\n"
"@return Material count.\n")
{
if (object->getSfxProfile())
{
MatrixF transform;
transform.setPosition(position);
SFXSource* source = SFX->playOnce(object->getSfxProfile(), &transform, NULL, -1);
return source->getId();
}
else
return 0;
}
#ifdef TORQUE_TOOLS
DefineEngineStaticMethod(SoundAsset, getAssetIdByFilename, const char*, (const char* filePath), (""),
"Queries the Asset Database to see if any asset exists that is associated with the provided file path.\n"
"@return The AssetId of the associated asset, if any.")
{
return SoundAsset::getAssetIdByFileName(StringTable->insert(filePath));
}
#endif
IMPLEMENT_CONOBJECT(GuiInspectorTypeSoundAssetPtr); IMPLEMENT_CONOBJECT(GuiInspectorTypeSoundAssetPtr);
ConsoleDocClass(GuiInspectorTypeSoundAssetPtr, ConsoleDocClass(GuiInspectorTypeSoundAssetPtr,
@ -276,12 +368,63 @@ void GuiInspectorTypeSoundAssetPtr::consoleInit()
GuiControl * GuiInspectorTypeSoundAssetPtr::constructEditControl() GuiControl * GuiInspectorTypeSoundAssetPtr::constructEditControl()
{ {
return nullptr; // Create base filename edit controls
GuiControl* retCtrl = Parent::constructEditControl();
if (retCtrl == NULL)
return retCtrl;
// Change filespec
char szBuffer[512];
dSprintf(szBuffer, sizeof(szBuffer), "AssetBrowser.showDialog(\"SoundAsset\", \"AssetBrowser.changeAsset\", %s, \"\");",
getIdString());
mBrowseButton->setField("Command", szBuffer);
setDataField(StringTable->insert("targetObject"), NULL, mInspector->getInspectObject()->getIdString());
// Create "Open in Editor" button
mEditButton = new GuiBitmapButtonCtrl();
dSprintf(szBuffer, sizeof(szBuffer), "AssetBrowser.editAsset(%d.getText());", retCtrl->getId());
mEditButton->setField("Command", szBuffer);
char bitmapName[512] = "ToolsModule:SFXEmitter_image";
mEditButton->setBitmap(StringTable->insert(bitmapName));
mEditButton->setDataField(StringTable->insert("Profile"), NULL, "GuiButtonProfile");
mEditButton->setDataField(StringTable->insert("tooltipprofile"), NULL, "GuiToolTipProfile");
mEditButton->setDataField(StringTable->insert("hovertime"), NULL, "1000");
mEditButton->setDataField(StringTable->insert("tooltip"), NULL, "Test play this sound");
mEditButton->registerObject();
addObject(mEditButton);
return retCtrl;
} }
bool GuiInspectorTypeSoundAssetPtr::updateRects() bool GuiInspectorTypeSoundAssetPtr::updateRects()
{ {
return false; S32 dividerPos, dividerMargin;
mInspector->getDivider(dividerPos, dividerMargin);
Point2I fieldExtent = getExtent();
Point2I fieldPos = getPosition();
mCaptionRect.set(0, 0, fieldExtent.x - dividerPos - dividerMargin, fieldExtent.y);
mEditCtrlRect.set(fieldExtent.x - dividerPos + dividerMargin, 1, dividerPos - dividerMargin - 34, fieldExtent.y);
bool resized = mEdit->resize(mEditCtrlRect.point, mEditCtrlRect.extent);
if (mBrowseButton != NULL)
{
mBrowseRect.set(fieldExtent.x - 32, 2, 14, fieldExtent.y - 4);
resized |= mBrowseButton->resize(mBrowseRect.point, mBrowseRect.extent);
}
if (mEditButton != NULL)
{
RectI shapeEdRect(fieldExtent.x - 16, 2, 14, fieldExtent.y - 4);
resized |= mEditButton->resize(shapeEdRect.point, shapeEdRect.extent);
}
return resized;
} }
IMPLEMENT_CONOBJECT(GuiInspectorTypeSoundAssetId); IMPLEMENT_CONOBJECT(GuiInspectorTypeSoundAssetId);

View file

@ -122,6 +122,9 @@ public:
bool isLoop() { return mProfileDesc.mIsLooping; } bool isLoop() { return mProfileDesc.mIsLooping; }
bool is3D() { return mProfileDesc.mIs3D; } bool is3D() { return mProfileDesc.mIs3D; }
static StringTableEntry getAssetIdByFileName(StringTableEntry fileName);
static U32 getAssetById(StringTableEntry assetId, AssetPtr<SoundAsset>* materialAsset);
static U32 getAssetByFileName(StringTableEntry fileName, AssetPtr<SoundAsset>* matAsset);
protected: protected:
virtual void initializeAsset(void); virtual void initializeAsset(void);
@ -143,7 +146,7 @@ class GuiInspectorTypeSoundAssetPtr : public GuiInspectorTypeFileName
typedef GuiInspectorTypeFileName Parent; typedef GuiInspectorTypeFileName Parent;
public: public:
GuiBitmapButtonCtrl* mSoundButton; GuiBitmapButtonCtrl* mEditButton;
DECLARE_CONOBJECT(GuiInspectorTypeSoundAssetPtr); DECLARE_CONOBJECT(GuiInspectorTypeSoundAssetPtr);
static void consoleInit(); static void consoleInit();
@ -168,14 +171,14 @@ public:
/// Declares a sound asset /// Declares a sound asset
/// This establishes the assetId, asset and legacy filepath fields, along with supplemental getter and setter functions /// This establishes the assetId, asset and legacy filepath fields, along with supplemental getter and setter functions
/// </Summary> /// </Summary>
#define DECLARE_SOUNDASSET(className, name, profile) public: \ #define DECLARE_SOUNDASSET(className, name) public: \
Resource<SFXResource> m##name;\ Resource<SFXResource> m##name;\
StringTableEntry m##name##Name; \ StringTableEntry m##name##Name; \
StringTableEntry m##name##AssetId;\ StringTableEntry m##name##AssetId;\
AssetPtr<SoundAsset> m##name##Asset = NULL;\ AssetPtr<SoundAsset> m##name##Asset = NULL;\
SFXProfile* m##name##Profile = &profile;\ SFXProfile* m##name##Profile = NULL;\
public: \ public: \
const StringTableEntry get##name##File() const { return m##name##Name); }\ const StringTableEntry get##name##File() const { return m##name##Name; }\
void set##name##File(const FileName &_in) { m##name##Name = StringTable->insert(_in.c_str());}\ void set##name##File(const FileName &_in) { m##name##Name = StringTable->insert(_in.c_str());}\
const AssetPtr<SoundAsset> & get##name##Asset() const { return m##name##Asset; }\ const AssetPtr<SoundAsset> & get##name##Asset() const { return m##name##Asset; }\
void set##name##Asset(const AssetPtr<SoundAsset> &_in) { m##name##Asset = _in;}\ void set##name##Asset(const AssetPtr<SoundAsset> &_in) { m##name##Asset = _in;}\
@ -206,7 +209,7 @@ public: \
}\ }\
else\ else\
{\ {\
StringTableEntry assetId = SoundAsset::getAssetIdByFilename(_in);\ StringTableEntry assetId = SoundAsset::getAssetIdByFileName(_in);\
if (assetId != StringTable->EmptyString())\ if (assetId != StringTable->EmptyString())\
{\ {\
m##name##AssetId = assetId;\ m##name##AssetId = assetId;\
@ -232,9 +235,9 @@ public: \
m##name = NULL;\ m##name = NULL;\
}\ }\
\ \
if (m##name##Asset.notNull() && m##name##Asset->getStatus() != ShapeAsset::Ok)\ if (m##name##Asset.notNull() && m##name##Asset->getStatus() != SoundAsset::Ok)\
{\ {\
Con::errorf("%s(%s)::_set%s() - sound asset failure\"%s\" due to [%s]", macroText(className), getName(), macroText(name), _in, ShapeAsset::getAssetErrstrn(m##name##Asset->getStatus()).c_str());\ Con::errorf("%s(%s)::_set%s() - sound asset failure\"%s\" due to [%s]", macroText(className), getName(), macroText(name), _in, SoundAsset::getAssetErrstrn(m##name##Asset->getStatus()).c_str());\
return false; \ return false; \
}\ }\
else if (m##name)\ else if (m##name)\

View file

@ -1382,32 +1382,32 @@ void AssetImporter::processImportAssets(AssetImportObject* assetItem)
if (item->assetName != item->cleanAssetName) if (item->assetName != item->cleanAssetName)
item->assetName = item->cleanAssetName; item->assetName = item->cleanAssetName;
//handle special pre-processing here for any types that need it //process the asset items
if (item->assetType == String("ImageAsset"))
//process the asset items {
if (item->assetType == String("ImageAsset")) processImageAsset(item);
{ }
processImageAsset(item); else if (item->assetType == String("ShapeAsset"))
} {
else if (item->assetType == String("ShapeAsset")) processShapeAsset(item);
{ }
processShapeAsset(item); else if (item->assetType == String("SoundAsset"))
} {
/*else if (item->assetType == String("SoundAsset")) processSoundAsset(item);
SoundAsset::prepareAssetForImport(this, item);*/ }
else if (item->assetType == String("MaterialAsset")) else if (item->assetType == String("MaterialAsset"))
{ {
processMaterialAsset(item); processMaterialAsset(item);
} }
/*else if (item->assetType == String("ShapeAnimationAsset")) /*else if (item->assetType == String("ShapeAnimationAsset"))
ShapeAnimationAsset::prepareAssetForImport(this, item);*/ ShapeAnimationAsset::prepareAssetForImport(this, item);*/
else else
{ {
String processCommand = "process"; String processCommand = "process";
processCommand += item->assetType; processCommand += item->assetType;
if(isMethod(processCommand.c_str())) if(isMethod(processCommand.c_str()))
Con::executef(this, processCommand.c_str(), item); Con::executef(this, processCommand.c_str(), item);
} }
item->importStatus == AssetImportObject::Processed; item->importStatus == AssetImportObject::Processed;
@ -1975,93 +1975,12 @@ void AssetImporter::processShapeMaterialInfo(AssetImportObject* assetItem, S32 m
void AssetImporter::processSoundAsset(AssetImportObject* assetItem) void AssetImporter::processSoundAsset(AssetImportObject* assetItem)
{ {
dSprintf(importLogBuffer, sizeof(importLogBuffer), "Preparing Image for Import: %s", assetItem->assetName.c_str()); dSprintf(importLogBuffer, sizeof(importLogBuffer), "Preparing Sound for Import: %s", assetItem->assetName.c_str());
activityLog.push_back(importLogBuffer); activityLog.push_back(importLogBuffer);
if ((activeImportConfig->GenerateMaterialOnImport && assetItem->parentAssetItem == nullptr)/* || assetItem->parentAssetItem != nullptr*/)
{
//find our suffix match, if any
String noSuffixName = assetItem->assetName;
String suffixType;
String suffix = parseImageSuffixes(assetItem->assetName, &suffixType);
if (suffix.isNotEmpty())
{
assetItem->imageSuffixType = suffixType;
S32 suffixPos = assetItem->assetName.find(suffix, 0, String::NoCase | String::Left);
noSuffixName = assetItem->assetName.substr(0, suffixPos);
}
//We try to automatically populate materials under the naming convention: materialName: Rock, image maps: Rock_Albedo, Rock_Normal, etc
AssetImportObject* materialAsset = findImportingAssetByName(noSuffixName);
if (materialAsset != nullptr && materialAsset->assetType != String("MaterialAsset"))
{
//We may have a situation where an asset matches the no-suffix name, but it's not a material asset. Ignore this
//asset item for now
materialAsset = nullptr;
}
//If we didn't find a matching material asset in our current items, we'll make one now
if (materialAsset == nullptr)
{
if (!assetItem->filePath.isEmpty())
{
materialAsset = addImportingAsset("MaterialAsset", assetItem->filePath, nullptr, noSuffixName);
}
}
//Not that, one way or another, we have the generated material asset, lets move on to associating our image with it
if (materialAsset != nullptr && materialAsset != assetItem->parentAssetItem)
{
if (assetItem->parentAssetItem != nullptr)
{
//If the image had an existing parent, it gets removed from that parent's child item list
assetItem->parentAssetItem->childAssetItems.remove(assetItem);
}
else
{
//If it didn't have one, we're going to pull it from the importingAssets list
importingAssets.remove(assetItem);
}
//Now we can add it to the correct material asset
materialAsset->childAssetItems.push_back(assetItem);
assetItem->parentAssetItem = materialAsset;
assetHeirarchyChanged = true;
}
//Now to do some cleverness. If we're generating a material, we can parse like assets being imported(similar filenames) but different suffixes
//If we find these, we'll just populate into the original's material
//if we need to append the diffuse suffix and indeed didn't find a suffix on the name, do that here
if (suffixType.isEmpty())
{
if (activeImportConfig->UseDiffuseSuffixOnOriginImage)
{
String diffuseToken = StringUnit::getUnit(activeImportConfig->DiffuseTypeSuffixes, 0, ",;\t");
assetItem->assetName = assetItem->assetName + diffuseToken;
assetItem->cleanAssetName = assetItem->assetName;
}
else
{
//We need to ensure that our image asset doesn't match the same name as the material asset, so if we're not trying to force the diffuse suffix
//we'll give it a generic one
if ((materialAsset && materialAsset->assetName.compare(assetItem->assetName) == 0) || activeImportConfig->AlwaysAddImageSuffix)
{
assetItem->assetName = assetItem->assetName + activeImportConfig->AddedImageSuffix;
assetItem->cleanAssetName = assetItem->assetName;
}
}
//Assume for abledo if it has no suffix matches
assetItem->imageSuffixType = "Albedo";
}
}
assetItem->importStatus = AssetImportObject::Processed; assetItem->importStatus = AssetImportObject::Processed;
} }
// //
// Validation // Validation
// //
@ -2514,6 +2433,8 @@ void AssetImporter::importAssets(AssetImportObject* assetItem)
if (!refreshSuccess) if (!refreshSuccess)
{ {
const char* importReturnVal = Con::executef(this, processCommand.c_str(), childItem).getString();
assetPath = Torque::Path(importReturnVal);
dSprintf(importLogBuffer, sizeof(importLogBuffer), "AssetImporter::importAssets - Failed to refresh reimporting asset %s.", item->assetName.c_str()); dSprintf(importLogBuffer, sizeof(importLogBuffer), "AssetImporter::importAssets - Failed to refresh reimporting asset %s.", item->assetName.c_str());
activityLog.push_back(importLogBuffer); activityLog.push_back(importLogBuffer);
} }

View file

@ -331,7 +331,7 @@ DefineEngineStringlyVariadicMethod(GameConnection, setConnectArgs, void, 3, 17,
"@see GameConnection::onConnect()\n\n") "@see GameConnection::onConnect()\n\n")
{ {
StringStackWrapper args(argc - 2, argv + 2); ConsoleValueToStringArrayWrapper args(argc - 2, argv + 2);
object->setConnectArgs(args.count(), args); object->setConnectArgs(args.count(), args);
} }
@ -373,7 +373,7 @@ void GameConnection::onConnectionEstablished(bool isInitiator)
mMoveList->init(); mMoveList->init();
const char *argv[MaxConnectArgs + 2]; const char *argv[MaxConnectArgs + 2];
argv[0] = "onConnect"; argv[0] = "onConnect";
argv[1] = NULL; // Filled in later argv[1] = getIdString();
for(U32 i = 0; i < mConnectArgc; i++) for(U32 i = 0; i < mConnectArgc; i++)
argv[i + 2] = mConnectArgv[i]; argv[i + 2] = mConnectArgv[i];
// NOTE: Need to fallback to Con::execute() as IMPLEMENT_CALLBACK does not // NOTE: Need to fallback to Con::execute() as IMPLEMENT_CALLBACK does not
@ -493,33 +493,32 @@ bool GameConnection::readConnectRequest(BitStream *stream, const char **errorStr
*errorString = "CR_INVALID_ARGS"; *errorString = "CR_INVALID_ARGS";
return false; return false;
} }
ConsoleValueRef connectArgv[MaxConnectArgs + 3];
ConsoleValue connectArgvValue[MaxConnectArgs + 3];
for(U32 i = 0; i < mConnectArgc+3; i++) char buffer[256];
{ Net::addressToString(getNetAddress(), buffer);
connectArgv[i].value = &connectArgvValue[i];
connectArgvValue[i].init(); ConsoleValue connectArgv[MaxConnectArgs + 3];
}
for(U32 i = 0; i < mConnectArgc; i++) for(U32 i = 0; i < mConnectArgc; i++)
{ {
char argString[256]; char argString[256];
stream->readString(argString); stream->readString(argString);
mConnectArgv[i] = dStrdup(argString); mConnectArgv[i] = dStrdup(argString);
connectArgv[i + 3] = mConnectArgv[i]; connectArgv[i + 3].setString(argString);
} }
connectArgvValue[0].setStackStringValue("onConnectRequest");
connectArgvValue[1].setIntValue(0); connectArgv[0].setStringTableEntry("onConnectRequest");
char buffer[256]; connectArgv[1].setInt(0);
Net::addressToString(getNetAddress(), buffer); connectArgv[2].setString(buffer);
connectArgvValue[2].setStackStringValue(buffer);
// NOTE: Cannot convert over to IMPLEMENT_CALLBACK as it has variable args. // NOTE: Cannot convert over to IMPLEMENT_CALLBACK as it has variable args.
const char *ret = Con::execute(this, mConnectArgc + 3, connectArgv); ConsoleValue returnValue = Con::execute(this, mConnectArgc + 3, connectArgv);
if(ret[0])
StringTableEntry returnStr = StringTable->insert(returnValue.getString());
if(returnStr[0])
{ {
*errorString = ret; *errorString = returnStr;
return false; return false;
} }
return true; return true;
@ -1088,7 +1087,7 @@ bool GameConnection::readDemoStartBlock(BitStream *stream)
void GameConnection::demoPlaybackComplete() void GameConnection::demoPlaybackComplete()
{ {
static const char* demoPlaybackArgv[1] = { "demoPlaybackComplete" }; static const char* demoPlaybackArgv[1] = { "demoPlaybackComplete" };
static StringStackConsoleWrapper demoPlaybackCmd(1, demoPlaybackArgv); static StringArrayToConsoleValueWrapper demoPlaybackCmd(1, demoPlaybackArgv);
Sim::postCurrentEvent(Sim::getRootGroup(), new SimConsoleEvent(demoPlaybackCmd.argc, demoPlaybackCmd.argv, false)); Sim::postCurrentEvent(Sim::getRootGroup(), new SimConsoleEvent(demoPlaybackCmd.argc, demoPlaybackCmd.argv, false));
Parent::demoPlaybackComplete(); Parent::demoPlaybackComplete();

View file

@ -94,9 +94,7 @@ ColorI SFXEmitter::smRenderColorRangeSphere( 200, 0, 0, 90 );
SFXEmitter::SFXEmitter() SFXEmitter::SFXEmitter()
: SceneObject(), : SceneObject(),
mSource( NULL ), mSource( NULL ),
mTrack( NULL ),
mUseTrackDescriptionOnly( false ), mUseTrackDescriptionOnly( false ),
mLocalProfile( &mDescription ),
mPlayOnAdd( true ) mPlayOnAdd( true )
{ {
mTypeMask |= MarkerObjectType; mTypeMask |= MarkerObjectType;
@ -108,8 +106,11 @@ SFXEmitter::SFXEmitter()
mDescription.mFadeInTime = -1.f; mDescription.mFadeInTime = -1.f;
mDescription.mFadeOutTime = -1.f; mDescription.mFadeOutTime = -1.f;
mLocalProfile.mFilename = StringTable->EmptyString();
mLocalProfile._registerSignals(); mLocalProfile._registerSignals();
INIT_SOUNDASSET(Sound);
mObjBox.minExtents.set( -1.f, -1.f, -1.f ); mObjBox.minExtents.set( -1.f, -1.f, -1.f );
mObjBox.maxExtents.set( 1.f, 1.f, 1.f ); mObjBox.maxExtents.set( 1.f, 1.f, 1.f );
} }
@ -175,14 +176,16 @@ void SFXEmitter::initPersistFields()
{ {
addGroup( "Media" ); addGroup( "Media" );
addField( "track", TypeSFXTrackName, Offset( mTrack, SFXEmitter), INITPERSISTFIELD_SOUNDASSET(Sound, SFXEmitter, "");
/*addField("track", TypeSFXTrackName, Offset(mTrack, SFXEmitter),
"The track which the emitter should play.\n" "The track which the emitter should play.\n"
"@note If assigned, this field will take precedence over a #fileName that may also be assigned to the " "@note If assigned, this field will take precedence over a #fileName that may also be assigned to the "
"emitter." ); "emitter." );
addField( "fileName", TypeStringFilename, Offset( mLocalProfile.mFilename, SFXEmitter), addField( "fileName", TypeStringFilename, Offset( mLocalProfile.mFilename, SFXEmitter),
"The sound file to play.\n" "The sound file to play.\n"
"Use @b either this property @b or #track. If both are assigned, #track takes precendence. The primary purpose of this " "Use @b either this property @b or #track. If both are assigned, #track takes precendence. The primary purpose of this "
"field is to avoid the need for the user to define SFXTrack datablocks for all sounds used in a level." ); "field is to avoid the need for the user to define SFXTrack datablocks for all sounds used in a level." );*/
endGroup( "Media"); endGroup( "Media");
@ -287,12 +290,13 @@ U32 SFXEmitter::packUpdate( NetConnection *con, U32 mask, BitStream *stream )
stream->writeAffineTransform( mObjToWorld ); stream->writeAffineTransform( mObjToWorld );
// track // track
if( stream->writeFlag( mDirty.test( Track ) ) ) PACK_SOUNDASSET(con, Sound);
sfxWrite( stream, mTrack ); //if (stream->writeFlag(mDirty.test(Track)))
// sfxWrite( stream, mTrack );
// filename // filename
if( stream->writeFlag( mDirty.test( Filename ) ) ) //if( stream->writeFlag( mDirty.test( Filename ) ) )
stream->writeString( mLocalProfile.mFilename ); // stream->writeString( mLocalProfile.mFilename );
// volume // volume
if( stream->writeFlag( mDirty.test( Volume ) ) ) if( stream->writeFlag( mDirty.test( Volume ) ) )
@ -397,7 +401,8 @@ void SFXEmitter::unpackUpdate( NetConnection *conn, BitStream *stream )
} }
// track // track
if ( _readDirtyFlag( stream, Track ) ) UNPACK_SOUNDASSET(conn, Sound);
/*if (_readDirtyFlag(stream, Track))
{ {
String errorStr; String errorStr;
if( !sfxReadAndResolve( stream, &mTrack, errorStr ) ) if( !sfxReadAndResolve( stream, &mTrack, errorStr ) )
@ -406,7 +411,7 @@ void SFXEmitter::unpackUpdate( NetConnection *conn, BitStream *stream )
// filename // filename
if ( _readDirtyFlag( stream, Filename ) ) if ( _readDirtyFlag( stream, Filename ) )
mLocalProfile.mFilename = stream->readSTString(); mLocalProfile.mFilename = stream->readSTString();*/
// volume // volume
if ( _readDirtyFlag( stream, Volume ) ) if ( _readDirtyFlag( stream, Volume ) )
@ -586,8 +591,8 @@ void SFXEmitter::inspectPostApply()
// Parent will call setScale so sync up scale with distance. // Parent will call setScale so sync up scale with distance.
F32 maxDistance = mDescription.mMaxDistance; F32 maxDistance = mDescription.mMaxDistance;
if( mUseTrackDescriptionOnly && mTrack ) if( mUseTrackDescriptionOnly && mSoundAsset )
maxDistance = mTrack->getDescription()->mMaxDistance; maxDistance = mSoundAsset->getSfxDescription()->mMaxDistance;
mObjScale.set( maxDistance, maxDistance, maxDistance ); mObjScale.set( maxDistance, maxDistance, maxDistance );
@ -608,8 +613,8 @@ bool SFXEmitter::onAdd()
mDescription.validate(); mDescription.validate();
// Read an old 'profile' field for backwards-compatibility. // Read an old 'profile' field for backwards-compatibility.
/*
if( !mTrack ) if(mSoundAsset.isNull() || !mSoundAsset->getSfxProfile())
{ {
static const char* sProfile = StringTable->insert( "profile" ); static const char* sProfile = StringTable->insert( "profile" );
const char* profileName = getDataField( sProfile, NULL ); const char* profileName = getDataField( sProfile, NULL );
@ -643,7 +648,7 @@ bool SFXEmitter::onAdd()
// Remove the old 'channel' field. // Remove the old 'channel' field.
setDataField( sChannel, NULL, "" ); setDataField( sChannel, NULL, "" );
} }
} }*/
} }
else else
{ {
@ -683,6 +688,12 @@ void SFXEmitter::_update()
// we can restore it. // we can restore it.
SFXStatus prevState = mSource ? mSource->getStatus() : SFXStatusNull; SFXStatus prevState = mSource ? mSource->getStatus() : SFXStatusNull;
if (mSoundAsset.notNull() )
{
mLocalProfile = *mSoundAsset->getSfxProfile();
mDescription = *mSoundAsset->getSfxDescription();
}
// Make sure all the settings are valid. // Make sure all the settings are valid.
mDescription.validate(); mDescription.validate();
@ -695,12 +706,12 @@ void SFXEmitter::_update()
SFX_DELETE( mSource ); SFX_DELETE( mSource );
// Do we have a track? // Do we have a track?
if( mTrack ) if( mSoundAsset && mSoundAsset->getSfxProfile() )
{ {
mSource = SFX->createSource( mTrack, &transform, &velocity ); mSource = SFX->createSource(mSoundAsset->getSfxProfile(), &transform, &velocity );
if( !mSource ) if( !mSource )
Con::errorf( "SFXEmitter::_update() - failed to create sound for track %i (%s)", Con::errorf( "SFXEmitter::_update() - failed to create sound for track %i (%s)",
mTrack->getId(), mTrack->getName() ); mSoundAsset->getSfxProfile()->getId(), mSoundAsset->getSfxProfile()->getName() );
// If we're supposed to play when the emitter is // If we're supposed to play when the emitter is
// added to the scene then also restart playback // added to the scene then also restart playback
@ -739,12 +750,12 @@ void SFXEmitter::_update()
// is toggled on a local profile sound. It makes the // is toggled on a local profile sound. It makes the
// editor feel responsive and that things are working. // editor feel responsive and that things are working.
if( gEditingMission && if( gEditingMission &&
!mTrack && (mSoundAsset.isNull() || !mSoundAsset->getSfxProfile()) &&
mPlayOnAdd && mPlayOnAdd &&
mDirty.test( IsLooping ) ) mDirty.test( IsLooping ) )
prevState = SFXStatusPlaying; prevState = SFXStatusPlaying;
bool useTrackDescriptionOnly = ( mUseTrackDescriptionOnly && mTrack ); bool useTrackDescriptionOnly = ( mUseTrackDescriptionOnly && mSoundAsset.notNull() && mSoundAsset->getSfxProfile());
// The rest only applies if we have a source. // The rest only applies if we have a source.
if( mSource ) if( mSource )
@ -1087,8 +1098,8 @@ SFXStatus SFXEmitter::_getPlaybackStatus() const
bool SFXEmitter::is3D() const bool SFXEmitter::is3D() const
{ {
if( mTrack != NULL ) if( mSoundAsset.notNull() && mSoundAsset->getSfxProfile() != NULL )
return mTrack->getDescription()->mIs3D; return mSoundAsset->getSfxProfile()->getDescription()->mIs3D;
else else
return mDescription.mIs3D; return mDescription.mIs3D;
} }
@ -1124,8 +1135,8 @@ void SFXEmitter::setScale( const VectorF &scale )
{ {
F32 maxDistance; F32 maxDistance;
if( mUseTrackDescriptionOnly && mTrack ) if( mUseTrackDescriptionOnly && mSoundAsset.notNull() && mSoundAsset->getSfxProfile())
maxDistance = mTrack->getDescription()->mMaxDistance; maxDistance = mSoundAsset->getSfxProfile()->getDescription()->mMaxDistance;
else else
{ {
// Use the average of the three coords. // Use the average of the three coords.

View file

@ -36,6 +36,7 @@
#include "gfx/gfxStateBlock.h" #include "gfx/gfxStateBlock.h"
#endif #endif
#include "T3D/assets/SoundAsset.h"
class SFXSource; class SFXSource;
class SFXTrack; class SFXTrack;
@ -103,13 +104,11 @@ class SFXEmitter : public SceneObject
/// The current dirty flags. /// The current dirty flags.
BitSet32 mDirty; BitSet32 mDirty;
DECLARE_SOUNDASSET(SFXEmitter, Sound);
DECLARE_SOUNDASSET_NET_SETGET(SFXEmitter, Sound, DirtyUpdateMask);
/// The sound source for the emitter. /// The sound source for the emitter.
SFXSource *mSource; SFXSource *mSource;
/// The selected track or null if the local
/// profile should be used.
SFXTrack *mTrack;
/// Whether to leave sound setup exclusively to the assigned mTrack and not /// Whether to leave sound setup exclusively to the assigned mTrack and not
/// override part of the track's description with emitter properties. /// override part of the track's description with emitter properties.
bool mUseTrackDescriptionOnly; bool mUseTrackDescriptionOnly;

View file

@ -228,7 +228,7 @@ bool VDataTable::getValue( SimObject *pObject, const String &pFieldName, String
case VDataTable::k_TypeExpression : case VDataTable::k_TypeExpression :
{ {
// Evaluate. // Evaluate.
pValue = Con::evaluate( fieldValue, false ).getStringValue(); pValue = Con::evaluate( fieldValue, false ).getString();
} break; } break;

View file

@ -2638,23 +2638,25 @@ DefineEngineStringlyVariadicMethod(afxMagicSpell, setTimeFactor, void, 3, 4, "(F
"@ingroup AFX") "@ingroup AFX")
{ {
if (argc == 3) if (argc == 3)
object->setTimeFactor(dAtof(argv[2])); object->setTimeFactor(argv[2].getFloat());
else else
{ {
F32 value = argv[3].getFloat();
if (dStricmp(argv[2], "overall") == 0) if (dStricmp(argv[2], "overall") == 0)
object->setTimeFactor(dAtof(argv[3])); object->setTimeFactor(dAtof(argv[3]));
else if (dStricmp(argv[2], "casting") == 0) else if (dStricmp(argv[2], "casting") == 0)
object->setTimeFactor(afxMagicSpell::CASTING_PHRASE, dAtof(argv[3])); object->setTimeFactor(afxMagicSpell::CASTING_PHRASE, value);
else if (dStricmp(argv[2], "launch") == 0) else if (dStricmp(argv[2], "launch") == 0)
object->setTimeFactor(afxMagicSpell::LAUNCH_PHRASE, dAtof(argv[3])); object->setTimeFactor(afxMagicSpell::LAUNCH_PHRASE, value);
else if (dStricmp(argv[2], "delivery") == 0) else if (dStricmp(argv[2], "delivery") == 0)
object->setTimeFactor(afxMagicSpell::DELIVERY_PHRASE, dAtof(argv[3])); object->setTimeFactor(afxMagicSpell::DELIVERY_PHRASE, value);
else if (dStricmp(argv[2], "impact") == 0) else if (dStricmp(argv[2], "impact") == 0)
object->setTimeFactor(afxMagicSpell::IMPACT_PHRASE, dAtof(argv[3])); object->setTimeFactor(afxMagicSpell::IMPACT_PHRASE, value);
else if (dStricmp(argv[2], "linger") == 0) else if (dStricmp(argv[2], "linger") == 0)
object->setTimeFactor(afxMagicSpell::LINGER_PHRASE, dAtof(argv[3])); object->setTimeFactor(afxMagicSpell::LINGER_PHRASE, value);
else else
Con::errorf("afxMagicSpell::setTimeFactor() -- unknown spell phrase [%s].", argv[2].getStringValue()); Con::errorf("afxMagicSpell::setTimeFactor() -- unknown spell phrase [%s].", argv[2].getString());
} }
} }

View file

@ -1070,7 +1070,7 @@ afxSelectron::start_selectron(SceneObject* picked, U8 subcode, SimObject* extra)
// CALL SCRIPT afxSelectronData::onPreactivate(%params, %extra) // CALL SCRIPT afxSelectronData::onPreactivate(%params, %extra)
const char* result = Con::executef(datablock, "onPreactivate", const char* result = Con::executef(datablock, "onPreactivate",
Con::getIntArg(param_holder->getId()), Con::getIntArg(param_holder->getId()),
(extra) ? Con::getIntArg(extra->getId()) : ""); (extra) ? Con::getIntArg(extra->getId()) : "").getString();
if (result && result[0] != '\0' && !dAtob(result)) if (result && result[0] != '\0' && !dAtob(result))
{ {
#if defined(TORQUE_DEBUG) #if defined(TORQUE_DEBUG)

View file

@ -874,7 +874,7 @@ DefineEngineStringlyVariadicFunction(echoThru, const char*, 2, 0, "(string passt
for (i = 2; i < argc; i++) for (i = 2; i < argc; i++)
dStrcat(ret, argv[i], len + 1); dStrcat(ret, argv[i], len + 1);
Con::printf("%s -- [%s]", ret, argv[1].getStringValue()); Con::printf("%s -- [%s]", ret, argv[1].getString());
ret[0] = 0; ret[0] = 0;
return argv[1]; return argv[1];
@ -894,7 +894,7 @@ DefineEngineStringlyVariadicFunction(warnThru, const char*, 2, 0, "(string passt
for(i = 2; i < argc; i++) for(i = 2; i < argc; i++)
dStrcat(ret, argv[i], len + 1); dStrcat(ret, argv[i], len + 1);
Con::warnf("%s -- [%s]", ret, argv[1].getStringValue()); Con::warnf("%s -- [%s]", ret, argv[1].getString());
ret[0] = 0; ret[0] = 0;
return argv[1]; return argv[1];
@ -914,7 +914,7 @@ DefineEngineStringlyVariadicFunction(errorThru, const char*, 2, 0, "(string pass
for(i = 2; i < argc; i++) for(i = 2; i < argc; i++)
dStrcat(ret, argv[i], len + 1); dStrcat(ret, argv[i], len + 1);
Con::errorf("%s -- [%s]", ret, argv[1].getStringValue()); Con::errorf("%s -- [%s]", ret, argv[1].getString());
ret[0] = 0; ret[0] = 0;
return argv[1]; return argv[1];

View file

@ -45,7 +45,6 @@
#include "console/debugOutputConsumer.h" #include "console/debugOutputConsumer.h"
#include "console/consoleTypes.h" #include "console/consoleTypes.h"
#include "console/engineAPI.h" #include "console/engineAPI.h"
#include "console/codeInterpreter.h"
#include "gfx/bitmap/gBitmap.h" #include "gfx/bitmap/gBitmap.h"
#include "gfx/gFont.h" #include "gfx/gFont.h"
@ -229,9 +228,6 @@ void StandardMainLoop::init()
ManagedSingleton< ThreadManager >::createSingleton(); ManagedSingleton< ThreadManager >::createSingleton();
FrameAllocator::init(TORQUE_FRAME_SIZE); // See comments in torqueConfig.h FrameAllocator::init(TORQUE_FRAME_SIZE); // See comments in torqueConfig.h
// Initialize the TorqueScript interpreter.
CodeInterpreter::init();
// Yell if we can't initialize the network. // Yell if we can't initialize the network.
if(!Net::init()) if(!Net::init())
{ {
@ -637,6 +633,7 @@ bool StandardMainLoop::doMainLoop()
ThreadPool::processMainThreadWorkItems(); ThreadPool::processMainThreadWorkItems();
Sampler::endFrame(); Sampler::endFrame();
ConsoleValue::resetConversionBuffer();
PROFILE_END_NAMED(MainLoop); PROFILE_END_NAMED(MainLoop);
} }

View file

@ -254,7 +254,7 @@ DefineEngineStringlyVariadicFunction( commandToServer, void, 2, RemoteCommandEve
NetConnection *conn = NetConnection::getConnectionToServer(); NetConnection *conn = NetConnection::getConnectionToServer();
if(!conn) if(!conn)
return; return;
StringStackWrapper args(argc - 1, argv + 1); ConsoleValueToStringArrayWrapper args(argc - 1, argv + 1);
RemoteCommandEvent::sendRemoteCommand(conn, args.count(), args); RemoteCommandEvent::sendRemoteCommand(conn, args.count(), args);
} }
@ -292,7 +292,7 @@ DefineEngineStringlyVariadicFunction( commandToClient, void, 3, RemoteCommandEve
NetConnection *conn; NetConnection *conn;
if(!Sim::findObject(argv[1], conn)) if(!Sim::findObject(argv[1], conn))
return; return;
StringStackWrapper args(argc - 2, argv + 2); ConsoleValueToStringArrayWrapper args(argc - 2, argv + 2);
RemoteCommandEvent::sendRemoteCommand(conn, args.count(), args); RemoteCommandEvent::sendRemoteCommand(conn, args.count(), args);
} }

View file

@ -236,13 +236,13 @@ TCPObject::~TCPObject()
} }
} }
bool TCPObject::processArguments(S32 argc, ConsoleValueRef *argv) bool TCPObject::processArguments(S32 argc, ConsoleValue *argv)
{ {
if(argc == 0) if(argc == 0)
return true; return true;
else if(argc == 1) else if(argc == 1)
{ {
addToTable(NetSocket::fromHandle(dAtoi(argv[0]))); addToTable(NetSocket::fromHandle(argv[0].getInt()));
return true; return true;
} }
return false; return false;

View file

@ -83,7 +83,7 @@ public:
void disconnect(); void disconnect();
State getState() { return mState; } State getState() { return mState; }
bool processArguments(S32 argc, ConsoleValueRef *argv); bool processArguments(S32 argc, ConsoleValue *argv);
void send(const U8 *buffer, U32 bufferLen); void send(const U8 *buffer, U32 bufferLen);
///Send an entire file over tcp ///Send an entire file over tcp

View file

@ -55,7 +55,7 @@ bool CInterface::_isMethod(const char* className, const char* methodName) const
if (mIsMethodCallback) if (mIsMethodCallback)
return mIsMethodCallback(className, methodName); return mIsMethodCallback(className, methodName);
return NULL; return false;
} }
const char* CInterface::_CallFunction(const char* nameSpace, const char* name, const char **argv, int argc, bool *result) const const char* CInterface::_CallFunction(const char* nameSpace, const char* name, const char **argv, int argc, bool *result) const

View file

@ -456,6 +456,8 @@ expr
{ $$ = (ExprNode*)VarNode::alloc( $1.lineNumber, $1.value, NULL); } { $$ = (ExprNode*)VarNode::alloc( $1.lineNumber, $1.value, NULL); }
| VAR '[' aidx_expr ']' | VAR '[' aidx_expr ']'
{ $$ = (ExprNode*)VarNode::alloc( $1.lineNumber, $1.value, $3 ); } { $$ = (ExprNode*)VarNode::alloc( $1.lineNumber, $1.value, $3 ); }
;
/*
| rwDEFINE '(' var_list_decl ')' '{' statement_list '}' | rwDEFINE '(' var_list_decl ')' '{' statement_list '}'
{ {
const U32 bufLen = 64; const U32 bufLen = 64;
@ -471,7 +473,7 @@ expr
$$ = StrConstNode::alloc( $1.lineNumber, (UTF8*)fName, false ); $$ = StrConstNode::alloc( $1.lineNumber, (UTF8*)fName, false );
} }
; */
slot_acc slot_acc
: expr '.' IDENT : expr '.' IDENT
@ -551,9 +553,12 @@ funcall_expr
{ $$ = FuncCallExprNode::alloc( $1.lineNumber, $3.value, $1.value, $5, false); } { $$ = FuncCallExprNode::alloc( $1.lineNumber, $3.value, $1.value, $5, false); }
| expr '.' IDENT '(' expr_list_decl ')' | expr '.' IDENT '(' expr_list_decl ')'
{ $1->append($5); $$ = FuncCallExprNode::alloc( $1->dbgLineNumber, $3.value, NULL, $1, true); } { $1->append($5); $$ = FuncCallExprNode::alloc( $1->dbgLineNumber, $3.value, NULL, $1, true); }
;
/*
| expr '(' expr_list_decl ')' | expr '(' expr_list_decl ')'
{ $$ = FuncPointerCallExprNode::alloc( $1->dbgLineNumber, $1, $3); } { $$ = FuncPointerCallExprNode::alloc( $1->dbgLineNumber, $1, $3); }
; ;
*/
assert_expr assert_expr
: rwASSERT '(' expr ')' : rwASSERT '(' expr ')'

File diff suppressed because it is too large Load diff

View file

@ -213,6 +213,7 @@ HEXDIGIT [a-fA-F0-9]
"true" { CMDlval.i = MakeToken< int >( 1, lineIndex ); return INTCONST; } "true" { CMDlval.i = MakeToken< int >( 1, lineIndex ); return INTCONST; }
"false" { CMDlval.i = MakeToken< int >( 0, lineIndex ); return INTCONST; } "false" { CMDlval.i = MakeToken< int >( 0, lineIndex ); return INTCONST; }
{VAR} { return(Sc_ScanVar()); } {VAR} { return(Sc_ScanVar()); }
{ID} { return Sc_ScanIdent(); } {ID} { return Sc_ScanIdent(); }
0[xX]{HEXDIGIT}+ return(Sc_ScanHex()); 0[xX]{HEXDIGIT}+ return(Sc_ScanHex());
{INTEGER} { CMDtext[CMDleng] = 0; CMDlval.i = MakeToken< int >( dAtoi(CMDtext), lineIndex ); return INTCONST; } {INTEGER} { CMDtext[CMDleng] = 0; CMDlval.i = MakeToken< int >( dAtoi(CMDtext), lineIndex ); return INTCONST; }

View file

@ -27,7 +27,7 @@ class ICallMethod
{ {
public: public:
virtual const char* callMethod( S32 argc, const char* methodName, ... ) = 0; virtual const char* callMethod( S32 argc, const char* methodName, ... ) = 0;
virtual const char* callMethodArgList( U32 argc, ConsoleValueRef argv[], bool callThis = true ) = 0; virtual const char* callMethodArgList( U32 argc, ConsoleValue argv[], bool callThis = true ) = 0;
}; };
#endif #endif

View file

@ -159,7 +159,7 @@ SimXMLDocument::~SimXMLDocument()
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Included for completeness. // Included for completeness.
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
bool SimXMLDocument::processArguments(S32 argc, ConsoleValueRef *argv) bool SimXMLDocument::processArguments(S32 argc, ConsoleValue *argv)
{ {
return argc == 0; return argc == 0;
} }

View file

@ -56,7 +56,7 @@ class SimXMLDocument: public SimObject
// tie in to the script language. The .cc file has more in depth // tie in to the script language. The .cc file has more in depth
// comments on these. // comments on these.
//----------------------------------------------------------------------- //-----------------------------------------------------------------------
bool processArguments(S32 argc, ConsoleValueRef *argv); bool processArguments(S32 argc, ConsoleValue *argv);
bool onAdd(); bool onAdd();
void onRemove(); void onRemove();
static void initPersistFields(); static void initPersistFields();

View file

@ -39,8 +39,15 @@ enum TypeReq
TypeReqNone, TypeReqNone,
TypeReqUInt, TypeReqUInt,
TypeReqFloat, TypeReqFloat,
TypeReqString, TypeReqString
TypeReqVar };
enum ExprNodeName
{
NameExprNode,
NameFloatNode,
NameIntNode,
NameVarNode
}; };
/// Representation of a node for the scripting language parser. /// Representation of a node for the scripting language parser.
@ -52,7 +59,7 @@ enum TypeReq
/// each representing a different language construct. /// each representing a different language construct.
struct StmtNode struct StmtNode
{ {
StmtNode *mNext; ///< Next entry in parse tree. StmtNode* next; ///< Next entry in parse tree.
StmtNode(); StmtNode();
virtual ~StmtNode() {} virtual ~StmtNode() {}
@ -61,8 +68,8 @@ struct StmtNode
/// @{ /// @{
/// ///
void append(StmtNode *next); void append(StmtNode* next);
StmtNode *getNext() const { return mNext; } StmtNode* getNext() const { return next; }
/// @} /// @}
@ -79,93 +86,95 @@ struct StmtNode
/// @name Breaking /// @name Breaking
/// @{ /// @{
void addBreakLine(CodeStream &codeStream); void addBreakLine(CodeStream& codeStream);
/// @} /// @}
/// @name Compilation /// @name Compilation
/// @{ /// @{
virtual U32 compileStmt(CodeStream &codeStream, U32 ip) = 0; virtual U32 compileStmt(CodeStream& codeStream, U32 ip) = 0;
virtual void setPackage(StringTableEntry packageName); virtual void setPackage(StringTableEntry packageName);
/// @} /// @}
}; };
/// Helper macro /// Helper macro
#ifndef DEBUG_AST_NODES #ifndef DEBUG_AST_NODES
# define DBG_STMT_TYPE(s) virtual String dbgStmtType() const { return String(#s); } # define DBG_STMT_TYPE(s) virtual const char* dbgStmtType() const { return "#s"; }
#else #else
# define DBG_STMT_TYPE(s) # define DBG_STMT_TYPE(s)
#endif #endif
struct BreakStmtNode : StmtNode struct BreakStmtNode : StmtNode
{ {
static BreakStmtNode *alloc(S32 lineNumber); static BreakStmtNode* alloc(S32 lineNumber);
U32 compileStmt(CodeStream &codeStream, U32 ip); U32 compileStmt(CodeStream& codeStream, U32 ip);
DBG_STMT_TYPE(BreakStmtNode); DBG_STMT_TYPE(BreakStmtNode);
}; };
struct ContinueStmtNode : StmtNode struct ContinueStmtNode : StmtNode
{ {
static ContinueStmtNode *alloc(S32 lineNumber); static ContinueStmtNode* alloc(S32 lineNumber);
U32 compileStmt(CodeStream &codeStream, U32 ip); U32 compileStmt(CodeStream& codeStream, U32 ip);
DBG_STMT_TYPE(ContinueStmtNode); DBG_STMT_TYPE(ContinueStmtNode);
}; };
/// A mathematical expression. /// A mathematical expression.
struct ExprNode : StmtNode struct ExprNode : StmtNode
{ {
ExprNode* optimizedNode;
U32 compileStmt(CodeStream &codeStream, U32 ip); U32 compileStmt(CodeStream& codeStream, U32 ip);
virtual U32 compile(CodeStream &codeStream, U32 ip, TypeReq type) = 0; virtual U32 compile(CodeStream& codeStream, U32 ip, TypeReq type) = 0;
virtual TypeReq getPreferredType() = 0; virtual TypeReq getPreferredType() = 0;
virtual ExprNodeName getExprNodeNameEnum() const { return NameExprNode; }
}; };
struct ReturnStmtNode : StmtNode struct ReturnStmtNode : StmtNode
{ {
ExprNode *expr; ExprNode* expr;
static ReturnStmtNode *alloc(S32 lineNumber, ExprNode *expr); static ReturnStmtNode* alloc(S32 lineNumber, ExprNode* expr);
U32 compileStmt(CodeStream &codeStream, U32 ip); U32 compileStmt(CodeStream& codeStream, U32 ip);
DBG_STMT_TYPE(ReturnStmtNode); DBG_STMT_TYPE(ReturnStmtNode);
}; };
struct IfStmtNode : StmtNode struct IfStmtNode : StmtNode
{ {
ExprNode *testExpr; ExprNode* testExpr;
StmtNode *ifBlock, *elseBlock; StmtNode* ifBlock, * elseBlock;
U32 endifOffset; U32 endifOffset;
U32 elseOffset; U32 elseOffset;
bool integer; bool integer;
bool propagate; bool propagate;
static IfStmtNode *alloc(S32 lineNumber, ExprNode *testExpr, StmtNode *ifBlock, StmtNode *elseBlock, bool propagateThrough); static IfStmtNode* alloc(S32 lineNumber, ExprNode* testExpr, StmtNode* ifBlock, StmtNode* elseBlock, bool propagateThrough);
void propagateSwitchExpr(ExprNode *left, bool string); void propagateSwitchExpr(ExprNode* left, bool string);
ExprNode *getSwitchOR(ExprNode *left, ExprNode *list, bool string); ExprNode* getSwitchOR(ExprNode* left, ExprNode* list, bool string);
U32 compileStmt(CodeStream &codeStream, U32 ip); U32 compileStmt(CodeStream& codeStream, U32 ip);
DBG_STMT_TYPE(IfStmtNode); DBG_STMT_TYPE(IfStmtNode);
}; };
struct LoopStmtNode : StmtNode struct LoopStmtNode : StmtNode
{ {
ExprNode *testExpr; ExprNode* testExpr;
ExprNode *initExpr; ExprNode* initExpr;
ExprNode *endLoopExpr; ExprNode* endLoopExpr;
StmtNode *loopBlock; StmtNode* loopBlock;
bool isDoLoop; bool isDoLoop;
U32 breakOffset; U32 breakOffset;
U32 continueOffset; U32 continueOffset;
U32 loopBlockStartOffset; U32 loopBlockStartOffset;
bool integer; bool integer;
static LoopStmtNode *alloc(S32 lineNumber, ExprNode *testExpr, ExprNode *initExpr, ExprNode *endLoopExpr, StmtNode *loopBlock, bool isDoLoop); static LoopStmtNode* alloc(S32 lineNumber, ExprNode* testExpr, ExprNode* initExpr, ExprNode* endLoopExpr, StmtNode* loopBlock, bool isDoLoop);
U32 compileStmt(CodeStream &codeStream, U32 ip); U32 compileStmt(CodeStream& codeStream, U32 ip);
DBG_STMT_TYPE(LoopStmtNode); DBG_STMT_TYPE(LoopStmtNode);
}; };
@ -189,35 +198,38 @@ struct IterStmtNode : StmtNode
static IterStmtNode* alloc(S32 lineNumber, StringTableEntry varName, ExprNode* containerExpr, StmtNode* body, bool isStringIter); static IterStmtNode* alloc(S32 lineNumber, StringTableEntry varName, ExprNode* containerExpr, StmtNode* body, bool isStringIter);
U32 compileStmt(CodeStream &codeStream, U32 ip); U32 compileStmt(CodeStream& codeStream, U32 ip);
}; };
/// A binary mathematical expression (ie, left op right). /// A binary mathematical expression (ie, left op right).
struct BinaryExprNode : ExprNode struct BinaryExprNode : ExprNode
{ {
S32 op; S32 op;
ExprNode *left; ExprNode* left;
ExprNode *right; ExprNode* right;
}; };
struct FloatBinaryExprNode : BinaryExprNode struct FloatBinaryExprNode : BinaryExprNode
{ {
static FloatBinaryExprNode *alloc(S32 lineNumber, S32 op, ExprNode *left, ExprNode *right); static FloatBinaryExprNode* alloc(S32 lineNumber, S32 op, ExprNode* left, ExprNode* right);
U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
bool optimize();
U32 compile(CodeStream &codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType(); TypeReq getPreferredType();
DBG_STMT_TYPE(FloatBinaryExprNode); DBG_STMT_TYPE(FloatBinaryExprNode);
}; };
struct ConditionalExprNode : ExprNode struct ConditionalExprNode : ExprNode
{ {
ExprNode *testExpr; ExprNode* testExpr;
ExprNode *trueExpr; ExprNode* trueExpr;
ExprNode *falseExpr; ExprNode* falseExpr;
bool integer; bool integer;
static ConditionalExprNode *alloc(S32 lineNumber, ExprNode *testExpr, ExprNode *trueExpr, ExprNode *falseExpr); static ConditionalExprNode* alloc(S32 lineNumber, ExprNode* testExpr, ExprNode* trueExpr, ExprNode* falseExpr);
virtual U32 compile(CodeStream &codeStream, U32 ip, TypeReq type); virtual U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
virtual TypeReq getPreferredType(); virtual TypeReq getPreferredType();
DBG_STMT_TYPE(ConditionalExprNode); DBG_STMT_TYPE(ConditionalExprNode);
}; };
@ -227,11 +239,13 @@ struct IntBinaryExprNode : BinaryExprNode
TypeReq subType; TypeReq subType;
U32 operand; U32 operand;
static IntBinaryExprNode *alloc(S32 lineNumber, S32 op, ExprNode *left, ExprNode *right); static IntBinaryExprNode* alloc(S32 lineNumber, S32 op, ExprNode* left, ExprNode* right);
void getSubTypeOperand(); void getSubTypeOperand();
U32 compile(CodeStream &codeStream, U32 ip, TypeReq type); bool optimize();
U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType(); TypeReq getPreferredType();
DBG_STMT_TYPE(IntBinaryExprNode); DBG_STMT_TYPE(IntBinaryExprNode);
}; };
@ -239,9 +253,9 @@ struct IntBinaryExprNode : BinaryExprNode
struct StreqExprNode : BinaryExprNode struct StreqExprNode : BinaryExprNode
{ {
bool eq; bool eq;
static StreqExprNode *alloc(S32 lineNumber, ExprNode *left, ExprNode *right, bool eq); static StreqExprNode* alloc(S32 lineNumber, ExprNode* left, ExprNode* right, bool eq);
U32 compile(CodeStream &codeStream, U32 ip, TypeReq type); U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType(); TypeReq getPreferredType();
DBG_STMT_TYPE(StreqExprNode); DBG_STMT_TYPE(StreqExprNode);
}; };
@ -249,19 +263,19 @@ struct StreqExprNode : BinaryExprNode
struct StrcatExprNode : BinaryExprNode struct StrcatExprNode : BinaryExprNode
{ {
S32 appendChar; S32 appendChar;
static StrcatExprNode *alloc(S32 lineNumber, ExprNode *left, ExprNode *right, S32 appendChar); static StrcatExprNode* alloc(S32 lineNumber, ExprNode* left, ExprNode* right, S32 appendChar);
U32 compile(CodeStream &codeStream, U32 ip, TypeReq type); U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType(); TypeReq getPreferredType();
DBG_STMT_TYPE(StrcatExprNode); DBG_STMT_TYPE(StrcatExprNode);
}; };
struct CommaCatExprNode : BinaryExprNode struct CommaCatExprNode : BinaryExprNode
{ {
static CommaCatExprNode *alloc(S32 lineNumber, ExprNode *left, ExprNode *right); static CommaCatExprNode* alloc(S32 lineNumber, ExprNode* left, ExprNode* right);
U32 compile(CodeStream &codeStream, U32 ip, TypeReq type); U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType(); TypeReq getPreferredType();
DBG_STMT_TYPE(CommaCatExprNode); DBG_STMT_TYPE(CommaCatExprNode);
}; };
@ -269,12 +283,12 @@ struct CommaCatExprNode : BinaryExprNode
struct IntUnaryExprNode : ExprNode struct IntUnaryExprNode : ExprNode
{ {
S32 op; S32 op;
ExprNode *expr; ExprNode* expr;
bool integer; bool integer;
static IntUnaryExprNode *alloc(S32 lineNumber, S32 op, ExprNode *expr); static IntUnaryExprNode* alloc(S32 lineNumber, S32 op, ExprNode* expr);
U32 compile(CodeStream &codeStream, U32 ip, TypeReq type); U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType(); TypeReq getPreferredType();
DBG_STMT_TYPE(IntUnaryExprNode); DBG_STMT_TYPE(IntUnaryExprNode);
}; };
@ -282,11 +296,11 @@ struct IntUnaryExprNode : ExprNode
struct FloatUnaryExprNode : ExprNode struct FloatUnaryExprNode : ExprNode
{ {
S32 op; S32 op;
ExprNode *expr; ExprNode* expr;
static FloatUnaryExprNode *alloc(S32 lineNumber, S32 op, ExprNode *expr); static FloatUnaryExprNode* alloc(S32 lineNumber, S32 op, ExprNode* expr);
U32 compile(CodeStream &codeStream, U32 ip, TypeReq type); U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType(); TypeReq getPreferredType();
DBG_STMT_TYPE(FloatUnaryExprNode); DBG_STMT_TYPE(FloatUnaryExprNode);
}; };
@ -294,12 +308,13 @@ struct FloatUnaryExprNode : ExprNode
struct VarNode : ExprNode struct VarNode : ExprNode
{ {
StringTableEntry varName; StringTableEntry varName;
ExprNode *arrayIndex; ExprNode* arrayIndex;
static VarNode *alloc(S32 lineNumber, StringTableEntry varName, ExprNode *arrayIndex); static VarNode* alloc(S32 lineNumber, StringTableEntry varName, ExprNode* arrayIndex);
U32 compile(CodeStream &codeStream, U32 ip, TypeReq type); U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType(); TypeReq getPreferredType();
virtual ExprNodeName getExprNodeNameEnum() const { return NameVarNode; }
DBG_STMT_TYPE(VarNode); DBG_STMT_TYPE(VarNode);
}; };
@ -308,10 +323,11 @@ struct IntNode : ExprNode
S32 value; S32 value;
U32 index; // if it's converted to float/string U32 index; // if it's converted to float/string
static IntNode *alloc(S32 lineNumber, S32 value); static IntNode* alloc(S32 lineNumber, S32 value);
U32 compile(CodeStream &codeStream, U32 ip, TypeReq type); U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType(); TypeReq getPreferredType();
virtual ExprNodeName getExprNodeNameEnum() const { return NameIntNode; }
DBG_STMT_TYPE(IntNode); DBG_STMT_TYPE(IntNode);
}; };
@ -320,24 +336,25 @@ struct FloatNode : ExprNode
F64 value; F64 value;
U32 index; U32 index;
static FloatNode *alloc(S32 lineNumber, F64 value); static FloatNode* alloc(S32 lineNumber, F64 value);
U32 compile(CodeStream &codeStream, U32 ip, TypeReq type); U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType(); TypeReq getPreferredType();
virtual ExprNodeName getExprNodeNameEnum() const { return NameFloatNode; }
DBG_STMT_TYPE(FloatNode); DBG_STMT_TYPE(FloatNode);
}; };
struct StrConstNode : ExprNode struct StrConstNode : ExprNode
{ {
char *str; char* str;
F64 fVal; F64 fVal;
U32 index; U32 index;
bool tag; bool tag;
bool doc; // Specifies that this string is a documentation block. bool doc; // Specifies that this string is a documentation block.
static StrConstNode *alloc(S32 lineNumber, char *str, bool tag, bool doc = false); static StrConstNode* alloc(S32 lineNumber, char* str, bool tag, bool doc = false);
U32 compile(CodeStream &codeStream, U32 ip, TypeReq type); U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType(); TypeReq getPreferredType();
DBG_STMT_TYPE(StrConstNode); DBG_STMT_TYPE(StrConstNode);
}; };
@ -348,9 +365,9 @@ struct ConstantNode : ExprNode
F64 fVal; F64 fVal;
U32 index; U32 index;
static ConstantNode *alloc(S32 lineNumber, StringTableEntry value); static ConstantNode* alloc(S32 lineNumber, StringTableEntry value);
U32 compile(CodeStream &codeStream, U32 ip, TypeReq type); U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType(); TypeReq getPreferredType();
DBG_STMT_TYPE(ConstantNode); DBG_STMT_TYPE(ConstantNode);
}; };
@ -358,13 +375,13 @@ struct ConstantNode : ExprNode
struct AssignExprNode : ExprNode struct AssignExprNode : ExprNode
{ {
StringTableEntry varName; StringTableEntry varName;
ExprNode *expr; ExprNode* expr;
ExprNode *arrayIndex; ExprNode* arrayIndex;
TypeReq subType; TypeReq subType;
static AssignExprNode *alloc(S32 lineNumber, StringTableEntry varName, ExprNode *arrayIndex, ExprNode *expr); static AssignExprNode* alloc(S32 lineNumber, StringTableEntry varName, ExprNode* arrayIndex, ExprNode* expr);
U32 compile(CodeStream &codeStream, U32 ip, TypeReq type); U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType(); TypeReq getPreferredType();
DBG_STMT_TYPE(AssignExprNode); DBG_STMT_TYPE(AssignExprNode);
}; };
@ -373,22 +390,22 @@ struct AssignDecl
{ {
S32 lineNumber; S32 lineNumber;
S32 token; S32 token;
ExprNode *expr; ExprNode* expr;
bool integer; bool integer;
}; };
struct AssignOpExprNode : ExprNode struct AssignOpExprNode : ExprNode
{ {
StringTableEntry varName; StringTableEntry varName;
ExprNode *expr; ExprNode* expr;
ExprNode *arrayIndex; ExprNode* arrayIndex;
S32 op; S32 op;
U32 operand; U32 operand;
TypeReq subType; TypeReq subType;
static AssignOpExprNode *alloc(S32 lineNumber, StringTableEntry varName, ExprNode *arrayIndex, ExprNode *expr, S32 op); static AssignOpExprNode* alloc(S32 lineNumber, StringTableEntry varName, ExprNode* arrayIndex, ExprNode* expr, S32 op);
U32 compile(CodeStream &codeStream, U32 ip, TypeReq type); U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType(); TypeReq getPreferredType();
DBG_STMT_TYPE(AssignOpExprNode); DBG_STMT_TYPE(AssignOpExprNode);
}; };
@ -396,22 +413,22 @@ struct AssignOpExprNode : ExprNode
struct TTagSetStmtNode : StmtNode struct TTagSetStmtNode : StmtNode
{ {
StringTableEntry tag; StringTableEntry tag;
ExprNode *valueExpr; ExprNode* valueExpr;
ExprNode *stringExpr; ExprNode* stringExpr;
static TTagSetStmtNode *alloc(S32 lineNumber, StringTableEntry tag, ExprNode *valueExpr, ExprNode *stringExpr); static TTagSetStmtNode* alloc(S32 lineNumber, StringTableEntry tag, ExprNode* valueExpr, ExprNode* stringExpr);
U32 compileStmt(CodeStream &codeStream, U32 ip); U32 compileStmt(CodeStream& codeStream, U32 ip);
DBG_STMT_TYPE(TTagSetStmtNode); DBG_STMT_TYPE(TTagSetStmtNode);
}; };
struct TTagDerefNode : ExprNode struct TTagDerefNode : ExprNode
{ {
ExprNode *expr; ExprNode* expr;
static TTagDerefNode *alloc(S32 lineNumber, ExprNode *expr); static TTagDerefNode* alloc(S32 lineNumber, ExprNode* expr);
U32 compile(CodeStream &codeStream, U32 ip, TypeReq type); U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType(); TypeReq getPreferredType();
DBG_STMT_TYPE(TTagDerefNode); DBG_STMT_TYPE(TTagDerefNode);
}; };
@ -420,9 +437,9 @@ struct TTagExprNode : ExprNode
{ {
StringTableEntry tag; StringTableEntry tag;
static TTagExprNode *alloc(S32 lineNumber, StringTableEntry tag); static TTagExprNode* alloc(S32 lineNumber, StringTableEntry tag);
U32 compile(CodeStream &codeStream, U32 ip, TypeReq type); U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType(); TypeReq getPreferredType();
DBG_STMT_TYPE(TTagExprNode); DBG_STMT_TYPE(TTagExprNode);
}; };
@ -431,42 +448,31 @@ struct FuncCallExprNode : ExprNode
{ {
StringTableEntry funcName; StringTableEntry funcName;
StringTableEntry nameSpace; StringTableEntry nameSpace;
ExprNode *args; ExprNode* args;
U32 callType; U32 callType;
enum { enum {
FunctionCall, FunctionCall,
StaticCall,
MethodCall, MethodCall,
ParentCall ParentCall
}; };
static FuncCallExprNode *alloc(S32 lineNumber, StringTableEntry funcName, StringTableEntry nameSpace, ExprNode *args, bool dot); static FuncCallExprNode* alloc(S32 lineNumber, StringTableEntry funcName, StringTableEntry nameSpace, ExprNode* args, bool dot);
U32 compile(CodeStream &codeStream, U32 ip, TypeReq type); U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType(); TypeReq getPreferredType();
DBG_STMT_TYPE(FuncCallExprNode); DBG_STMT_TYPE(FuncCallExprNode);
}; };
struct FuncPointerCallExprNode : ExprNode
{
ExprNode *funcPointer;
ExprNode *args;
static FuncPointerCallExprNode *alloc(S32 lineNumber, ExprNode *stmt, ExprNode *args);
U32 compile(CodeStream &codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType();
DBG_STMT_TYPE(FuncPointerCallExprNode);
};
struct AssertCallExprNode : ExprNode struct AssertCallExprNode : ExprNode
{ {
ExprNode *testExpr; ExprNode* testExpr;
const char *message; const char* message;
U32 messageIndex; U32 messageIndex;
static AssertCallExprNode *alloc(S32 lineNumber, ExprNode *testExpr, const char *message); static AssertCallExprNode* alloc(S32 lineNumber, ExprNode* testExpr, const char* message);
U32 compile(CodeStream &codeStream, U32 ip, TypeReq type); U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType(); TypeReq getPreferredType();
DBG_STMT_TYPE(AssertCallExprNode); DBG_STMT_TYPE(AssertCallExprNode);
}; };
@ -474,19 +480,19 @@ struct AssertCallExprNode : ExprNode
struct SlotDecl struct SlotDecl
{ {
S32 lineNumber; S32 lineNumber;
ExprNode *object; ExprNode* object;
StringTableEntry slotName; StringTableEntry slotName;
ExprNode *array; ExprNode* array;
}; };
struct SlotAccessNode : ExprNode struct SlotAccessNode : ExprNode
{ {
ExprNode *objectExpr, *arrayExpr; ExprNode* objectExpr, * arrayExpr;
StringTableEntry slotName; StringTableEntry slotName;
static SlotAccessNode *alloc(S32 lineNumber, ExprNode *objectExpr, ExprNode *arrayExpr, StringTableEntry slotName); static SlotAccessNode* alloc(S32 lineNumber, ExprNode* objectExpr, ExprNode* arrayExpr, StringTableEntry slotName);
U32 compile(CodeStream &codeStream, U32 ip, TypeReq type); U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType(); TypeReq getPreferredType();
DBG_STMT_TYPE(SlotAccessNode); DBG_STMT_TYPE(SlotAccessNode);
}; };
@ -494,101 +500,99 @@ struct SlotAccessNode : ExprNode
struct InternalSlotDecl struct InternalSlotDecl
{ {
S32 lineNumber; S32 lineNumber;
ExprNode *object; ExprNode* object;
ExprNode *slotExpr; ExprNode* slotExpr;
bool recurse; bool recurse;
}; };
struct InternalSlotAccessNode : ExprNode struct InternalSlotAccessNode : ExprNode
{ {
ExprNode *objectExpr, *slotExpr; ExprNode* objectExpr, * slotExpr;
bool recurse; bool recurse;
static InternalSlotAccessNode *alloc(S32 lineNumber, ExprNode *objectExpr, ExprNode *slotExpr, bool recurse); static InternalSlotAccessNode* alloc(S32 lineNumber, ExprNode* objectExpr, ExprNode* slotExpr, bool recurse);
U32 compile(CodeStream &codeStream, U32 ip, TypeReq type); U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType(); TypeReq getPreferredType();
DBG_STMT_TYPE(InternalSlotAccessNode); DBG_STMT_TYPE(InternalSlotAccessNode);
}; };
struct SlotAssignNode : ExprNode struct SlotAssignNode : ExprNode
{ {
ExprNode *objectExpr, *arrayExpr; ExprNode* objectExpr, * arrayExpr;
StringTableEntry slotName; StringTableEntry slotName;
ExprNode *valueExpr; ExprNode* valueExpr;
U32 typeID; U32 typeID;
static SlotAssignNode *alloc(S32 lineNumber, ExprNode *objectExpr, ExprNode *arrayExpr, StringTableEntry slotName, ExprNode *valueExpr, U32 typeID = -1); static SlotAssignNode* alloc(S32 lineNumber, ExprNode* objectExpr, ExprNode* arrayExpr, StringTableEntry slotName, ExprNode* valueExpr, U32 typeID = -1);
U32 compile(CodeStream &codeStream, U32 ip, TypeReq type); U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType(); TypeReq getPreferredType();
DBG_STMT_TYPE(SlotAssignNode); DBG_STMT_TYPE(SlotAssignNode);
}; };
struct SlotAssignOpNode : ExprNode struct SlotAssignOpNode : ExprNode
{ {
ExprNode *objectExpr, *arrayExpr; ExprNode* objectExpr, * arrayExpr;
StringTableEntry slotName; StringTableEntry slotName;
S32 op; S32 op;
ExprNode *valueExpr; ExprNode* valueExpr;
U32 operand; U32 operand;
TypeReq subType; TypeReq subType;
static SlotAssignOpNode *alloc(S32 lineNumber, ExprNode *objectExpr, StringTableEntry slotName, ExprNode *arrayExpr, S32 op, ExprNode *valueExpr); static SlotAssignOpNode* alloc(S32 lineNumber, ExprNode* objectExpr, StringTableEntry slotName, ExprNode* arrayExpr, S32 op, ExprNode* valueExpr);
U32 compile(CodeStream &codeStream, U32 ip, TypeReq type); U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType(); TypeReq getPreferredType();
DBG_STMT_TYPE(SlotAssignOpNode); DBG_STMT_TYPE(SlotAssignOpNode);
}; };
struct ObjectDeclNode : ExprNode struct ObjectDeclNode : ExprNode
{ {
ExprNode *classNameExpr; ExprNode* classNameExpr;
StringTableEntry parentObject; StringTableEntry parentObject;
ExprNode *objectNameExpr; ExprNode* objectNameExpr;
ExprNode *argList; ExprNode* argList;
SlotAssignNode *slotDecls; SlotAssignNode* slotDecls;
ObjectDeclNode *subObjects; ObjectDeclNode* subObjects;
bool isDatablock; bool isDatablock;
U32 failOffset; U32 failOffset;
bool isClassNameInternal; bool isClassNameInternal;
bool isSingleton; bool isSingleton;
static ObjectDeclNode *alloc(S32 lineNumber, ExprNode *classNameExpr, ExprNode *objectNameExpr, ExprNode *argList, StringTableEntry parentObject, SlotAssignNode *slotDecls, ObjectDeclNode *subObjects, bool isDatablock, bool classNameInternal, bool isSingleton); static ObjectDeclNode* alloc(S32 lineNumber, ExprNode* classNameExpr, ExprNode* objectNameExpr, ExprNode* argList, StringTableEntry parentObject, SlotAssignNode* slotDecls, ObjectDeclNode* subObjects, bool isDatablock, bool classNameInternal, bool isSingleton);
U32 precompileSubObject(bool); U32 precompileSubObject(bool);
U32 compile(CodeStream &codeStream, U32 ip, TypeReq type); U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
U32 compileSubObject(CodeStream &codeStream, U32 ip, bool); U32 compileSubObject(CodeStream& codeStream, U32 ip, bool);
TypeReq getPreferredType(); TypeReq getPreferredType();
DBG_STMT_TYPE(ObjectDeclNode); DBG_STMT_TYPE(ObjectDeclNode);
}; };
struct ObjectBlockDecl struct ObjectBlockDecl
{ {
SlotAssignNode *slots; SlotAssignNode* slots;
ObjectDeclNode *decls; ObjectDeclNode* decls;
}; };
struct FunctionDeclStmtNode : StmtNode struct FunctionDeclStmtNode : StmtNode
{ {
StringTableEntry fnName; StringTableEntry fnName;
VarNode *args; VarNode* args;
StmtNode *stmts; StmtNode* stmts;
StringTableEntry nameSpace; StringTableEntry nameSpace;
StringTableEntry package; StringTableEntry package;
U32 endOffset; U32 endOffset;
U32 argc; U32 argc;
static FunctionDeclStmtNode *alloc(S32 lineNumber, StringTableEntry fnName, StringTableEntry nameSpace, VarNode *args, StmtNode *stmts); static FunctionDeclStmtNode* alloc(S32 lineNumber, StringTableEntry fnName, StringTableEntry nameSpace, VarNode* args, StmtNode* stmts);
U32 compileStmt(CodeStream &codeStream, U32 ip); U32 compileStmt(CodeStream& codeStream, U32 ip);
void setPackage(StringTableEntry packageName); void setPackage(StringTableEntry packageName);
DBG_STMT_TYPE(FunctionDeclStmtNode); DBG_STMT_TYPE(FunctionDeclStmtNode);
}; };
extern StmtNode *gStatementList; extern StmtNode* gStatementList;
extern StmtNode *gAnonFunctionList;
extern U32 gAnonFunctionID;
extern ExprEvalState gEvalState; extern ExprEvalState gEvalState;
#endif #endif

View file

@ -1,5 +1,5 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC // Copyright (c) 2013 GarageGames, LLC
// //
// Permission is hereby granted, free of charge, to any person obtaining a copy // Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to // of this software and associated documentation files (the "Software"), to
@ -20,7 +20,6 @@
// IN THE SOFTWARE. // IN THE SOFTWARE.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include "platform/platform.h"
#include "console/console.h" #include "console/console.h"
#include "console/compiler.h" #include "console/compiler.h"
#include "console/consoleInternal.h" #include "console/consoleInternal.h"
@ -38,25 +37,25 @@ using namespace Compiler;
//------------------------------------------------------------ //------------------------------------------------------------
BreakStmtNode *BreakStmtNode::alloc(S32 lineNumber) BreakStmtNode* BreakStmtNode::alloc(S32 lineNumber)
{ {
BreakStmtNode *ret = (BreakStmtNode *)consoleAlloc(sizeof(BreakStmtNode)); BreakStmtNode* ret = (BreakStmtNode*)consoleAlloc(sizeof(BreakStmtNode));
constructInPlace(ret); constructInPlace(ret);
ret->dbgLineNumber = lineNumber; ret->dbgLineNumber = lineNumber;
return ret; return ret;
} }
ContinueStmtNode *ContinueStmtNode::alloc(S32 lineNumber) ContinueStmtNode* ContinueStmtNode::alloc(S32 lineNumber)
{ {
ContinueStmtNode *ret = (ContinueStmtNode *)consoleAlloc(sizeof(ContinueStmtNode)); ContinueStmtNode* ret = (ContinueStmtNode*)consoleAlloc(sizeof(ContinueStmtNode));
constructInPlace(ret); constructInPlace(ret);
ret->dbgLineNumber = lineNumber; ret->dbgLineNumber = lineNumber;
return ret; return ret;
} }
ReturnStmtNode *ReturnStmtNode::alloc(S32 lineNumber, ExprNode *expr) ReturnStmtNode* ReturnStmtNode::alloc(S32 lineNumber, ExprNode* expr)
{ {
ReturnStmtNode *ret = (ReturnStmtNode *)consoleAlloc(sizeof(ReturnStmtNode)); ReturnStmtNode* ret = (ReturnStmtNode*)consoleAlloc(sizeof(ReturnStmtNode));
constructInPlace(ret); constructInPlace(ret);
ret->expr = expr; ret->expr = expr;
ret->dbgLineNumber = lineNumber; ret->dbgLineNumber = lineNumber;
@ -64,9 +63,9 @@ ReturnStmtNode *ReturnStmtNode::alloc(S32 lineNumber, ExprNode *expr)
return ret; return ret;
} }
IfStmtNode *IfStmtNode::alloc(S32 lineNumber, ExprNode *testExpr, StmtNode *ifBlock, StmtNode *elseBlock, bool propagate) IfStmtNode* IfStmtNode::alloc(S32 lineNumber, ExprNode* testExpr, StmtNode* ifBlock, StmtNode* elseBlock, bool propagate)
{ {
IfStmtNode *ret = (IfStmtNode *)consoleAlloc(sizeof(IfStmtNode)); IfStmtNode* ret = (IfStmtNode*)consoleAlloc(sizeof(IfStmtNode));
constructInPlace(ret); constructInPlace(ret);
ret->dbgLineNumber = lineNumber; ret->dbgLineNumber = lineNumber;
@ -78,9 +77,9 @@ IfStmtNode *IfStmtNode::alloc(S32 lineNumber, ExprNode *testExpr, StmtNode *ifBl
return ret; return ret;
} }
LoopStmtNode *LoopStmtNode::alloc(S32 lineNumber, ExprNode *initExpr, ExprNode *testExpr, ExprNode *endLoopExpr, StmtNode *loopBlock, bool isDoLoop) LoopStmtNode* LoopStmtNode::alloc(S32 lineNumber, ExprNode* initExpr, ExprNode* testExpr, ExprNode* endLoopExpr, StmtNode* loopBlock, bool isDoLoop)
{ {
LoopStmtNode *ret = (LoopStmtNode *)consoleAlloc(sizeof(LoopStmtNode)); LoopStmtNode* ret = (LoopStmtNode*)consoleAlloc(sizeof(LoopStmtNode));
constructInPlace(ret); constructInPlace(ret);
ret->dbgLineNumber = lineNumber; ret->dbgLineNumber = lineNumber;
ret->testExpr = testExpr; ret->testExpr = testExpr;
@ -111,11 +110,12 @@ IterStmtNode* IterStmtNode::alloc(S32 lineNumber, StringTableEntry varName, Expr
return ret; return ret;
} }
FloatBinaryExprNode *FloatBinaryExprNode::alloc(S32 lineNumber, S32 op, ExprNode *left, ExprNode *right) FloatBinaryExprNode* FloatBinaryExprNode::alloc(S32 lineNumber, S32 op, ExprNode* left, ExprNode* right)
{ {
FloatBinaryExprNode *ret = (FloatBinaryExprNode *)consoleAlloc(sizeof(FloatBinaryExprNode)); FloatBinaryExprNode* ret = (FloatBinaryExprNode*)consoleAlloc(sizeof(FloatBinaryExprNode));
constructInPlace(ret); constructInPlace(ret);
ret->dbgLineNumber = lineNumber; ret->dbgLineNumber = lineNumber;
ret->optimizedNode = NULL;
ret->op = op; ret->op = op;
ret->left = left; ret->left = left;
@ -124,11 +124,12 @@ FloatBinaryExprNode *FloatBinaryExprNode::alloc(S32 lineNumber, S32 op, ExprNode
return ret; return ret;
} }
IntBinaryExprNode *IntBinaryExprNode::alloc(S32 lineNumber, S32 op, ExprNode *left, ExprNode *right) IntBinaryExprNode* IntBinaryExprNode::alloc(S32 lineNumber, S32 op, ExprNode* left, ExprNode* right)
{ {
IntBinaryExprNode *ret = (IntBinaryExprNode *)consoleAlloc(sizeof(IntBinaryExprNode)); IntBinaryExprNode* ret = (IntBinaryExprNode*)consoleAlloc(sizeof(IntBinaryExprNode));
constructInPlace(ret); constructInPlace(ret);
ret->dbgLineNumber = lineNumber; ret->dbgLineNumber = lineNumber;
ret->optimizedNode = NULL;
ret->op = op; ret->op = op;
ret->left = left; ret->left = left;
@ -137,11 +138,12 @@ IntBinaryExprNode *IntBinaryExprNode::alloc(S32 lineNumber, S32 op, ExprNode *le
return ret; return ret;
} }
StreqExprNode *StreqExprNode::alloc(S32 lineNumber, ExprNode *left, ExprNode *right, bool eq) StreqExprNode* StreqExprNode::alloc(S32 lineNumber, ExprNode* left, ExprNode* right, bool eq)
{ {
StreqExprNode *ret = (StreqExprNode *)consoleAlloc(sizeof(StreqExprNode)); StreqExprNode* ret = (StreqExprNode*)consoleAlloc(sizeof(StreqExprNode));
constructInPlace(ret); constructInPlace(ret);
ret->dbgLineNumber = lineNumber; ret->dbgLineNumber = lineNumber;
ret->optimizedNode = NULL;
ret->left = left; ret->left = left;
ret->right = right; ret->right = right;
ret->eq = eq; ret->eq = eq;
@ -149,11 +151,12 @@ StreqExprNode *StreqExprNode::alloc(S32 lineNumber, ExprNode *left, ExprNode *ri
return ret; return ret;
} }
StrcatExprNode *StrcatExprNode::alloc(S32 lineNumber, ExprNode *left, ExprNode *right, S32 appendChar) StrcatExprNode* StrcatExprNode::alloc(S32 lineNumber, ExprNode* left, ExprNode* right, int appendChar)
{ {
StrcatExprNode *ret = (StrcatExprNode *)consoleAlloc(sizeof(StrcatExprNode)); StrcatExprNode* ret = (StrcatExprNode*)consoleAlloc(sizeof(StrcatExprNode));
constructInPlace(ret); constructInPlace(ret);
ret->dbgLineNumber = lineNumber; ret->dbgLineNumber = lineNumber;
ret->optimizedNode = NULL;
ret->left = left; ret->left = left;
ret->right = right; ret->right = right;
ret->appendChar = appendChar; ret->appendChar = appendChar;
@ -161,61 +164,67 @@ StrcatExprNode *StrcatExprNode::alloc(S32 lineNumber, ExprNode *left, ExprNode *
return ret; return ret;
} }
CommaCatExprNode *CommaCatExprNode::alloc(S32 lineNumber, ExprNode *left, ExprNode *right) CommaCatExprNode* CommaCatExprNode::alloc(S32 lineNumber, ExprNode* left, ExprNode* right)
{ {
CommaCatExprNode *ret = (CommaCatExprNode *)consoleAlloc(sizeof(CommaCatExprNode)); CommaCatExprNode* ret = (CommaCatExprNode*)consoleAlloc(sizeof(CommaCatExprNode));
constructInPlace(ret); constructInPlace(ret);
ret->dbgLineNumber = lineNumber; ret->dbgLineNumber = lineNumber;
ret->optimizedNode = NULL;
ret->left = left; ret->left = left;
ret->right = right; ret->right = right;
return ret; return ret;
} }
IntUnaryExprNode *IntUnaryExprNode::alloc(S32 lineNumber, S32 op, ExprNode *expr) IntUnaryExprNode* IntUnaryExprNode::alloc(S32 lineNumber, S32 op, ExprNode* expr)
{ {
IntUnaryExprNode *ret = (IntUnaryExprNode *)consoleAlloc(sizeof(IntUnaryExprNode)); IntUnaryExprNode* ret = (IntUnaryExprNode*)consoleAlloc(sizeof(IntUnaryExprNode));
constructInPlace(ret); constructInPlace(ret);
ret->dbgLineNumber = lineNumber; ret->dbgLineNumber = lineNumber;
ret->optimizedNode = NULL;
ret->op = op; ret->op = op;
ret->expr = expr; ret->expr = expr;
return ret; return ret;
} }
FloatUnaryExprNode *FloatUnaryExprNode::alloc(S32 lineNumber, S32 op, ExprNode *expr) FloatUnaryExprNode* FloatUnaryExprNode::alloc(S32 lineNumber, S32 op, ExprNode* expr)
{ {
FloatUnaryExprNode *ret = (FloatUnaryExprNode *)consoleAlloc(sizeof(FloatUnaryExprNode)); FloatUnaryExprNode* ret = (FloatUnaryExprNode*)consoleAlloc(sizeof(FloatUnaryExprNode));
constructInPlace(ret); constructInPlace(ret);
ret->dbgLineNumber = lineNumber; ret->dbgLineNumber = lineNumber;
ret->optimizedNode = NULL;
ret->op = op; ret->op = op;
ret->expr = expr; ret->expr = expr;
return ret; return ret;
} }
VarNode *VarNode::alloc(S32 lineNumber, StringTableEntry varName, ExprNode *arrayIndex) VarNode* VarNode::alloc(S32 lineNumber, StringTableEntry varName, ExprNode* arrayIndex)
{ {
VarNode *ret = (VarNode *)consoleAlloc(sizeof(VarNode)); VarNode* ret = (VarNode*)consoleAlloc(sizeof(VarNode));
constructInPlace(ret); constructInPlace(ret);
ret->dbgLineNumber = lineNumber; ret->dbgLineNumber = lineNumber;
ret->optimizedNode = NULL;
ret->varName = varName; ret->varName = varName;
ret->arrayIndex = arrayIndex; ret->arrayIndex = arrayIndex;
return ret; return ret;
} }
IntNode *IntNode::alloc(S32 lineNumber, S32 value) IntNode* IntNode::alloc(S32 lineNumber, S32 value)
{ {
IntNode *ret = (IntNode *)consoleAlloc(sizeof(IntNode)); IntNode* ret = (IntNode*)consoleAlloc(sizeof(IntNode));
constructInPlace(ret); constructInPlace(ret);
ret->dbgLineNumber = lineNumber; ret->dbgLineNumber = lineNumber;
ret->optimizedNode = NULL;
ret->value = value; ret->value = value;
return ret; return ret;
} }
ConditionalExprNode *ConditionalExprNode::alloc(S32 lineNumber, ExprNode *testExpr, ExprNode *trueExpr, ExprNode *falseExpr) ConditionalExprNode* ConditionalExprNode::alloc(S32 lineNumber, ExprNode* testExpr, ExprNode* trueExpr, ExprNode* falseExpr)
{ {
ConditionalExprNode *ret = (ConditionalExprNode *)consoleAlloc(sizeof(ConditionalExprNode)); ConditionalExprNode* ret = (ConditionalExprNode*)consoleAlloc(sizeof(ConditionalExprNode));
constructInPlace(ret); constructInPlace(ret);
ret->dbgLineNumber = lineNumber; ret->dbgLineNumber = lineNumber;
ret->optimizedNode = NULL;
ret->testExpr = testExpr; ret->testExpr = testExpr;
ret->trueExpr = trueExpr; ret->trueExpr = trueExpr;
ret->falseExpr = falseExpr; ret->falseExpr = falseExpr;
@ -223,44 +232,50 @@ ConditionalExprNode *ConditionalExprNode::alloc(S32 lineNumber, ExprNode *testEx
return ret; return ret;
} }
FloatNode *FloatNode::alloc(S32 lineNumber, F64 value) FloatNode* FloatNode::alloc(S32 lineNumber, F64 value)
{ {
FloatNode *ret = (FloatNode *)consoleAlloc(sizeof(FloatNode)); FloatNode* ret = (FloatNode*)consoleAlloc(sizeof(FloatNode));
constructInPlace(ret); constructInPlace(ret);
ret->dbgLineNumber = lineNumber; ret->dbgLineNumber = lineNumber;
ret->optimizedNode = NULL;
ret->value = value; ret->value = value;
return ret; return ret;
} }
StrConstNode *StrConstNode::alloc(S32 lineNumber, char *str, bool tag, bool doc) StrConstNode* StrConstNode::alloc(S32 lineNumber, char* str, bool tag, bool doc)
{ {
StrConstNode *ret = (StrConstNode *)consoleAlloc(sizeof(StrConstNode)); StrConstNode* ret = (StrConstNode*)consoleAlloc(sizeof(StrConstNode));
constructInPlace(ret); constructInPlace(ret);
S32 len = dStrlen(str);
ret->dbgLineNumber = lineNumber; ret->dbgLineNumber = lineNumber;
dsize_t retStrLen = dStrlen(str) + 1; ret->optimizedNode = NULL;
ret->str = (char *)consoleAlloc(retStrLen); ret->str = (char*)consoleAlloc(len + 1);
ret->tag = tag; ret->tag = tag;
ret->doc = doc; ret->doc = doc;
dStrcpy(ret->str, str, retStrLen); dStrcpy(ret->str, str, len + 1);
ret->str[len] = '\0';
return ret; return ret;
} }
ConstantNode *ConstantNode::alloc(S32 lineNumber, StringTableEntry value) ConstantNode* ConstantNode::alloc(S32 lineNumber, StringTableEntry value)
{ {
ConstantNode *ret = (ConstantNode *)consoleAlloc(sizeof(ConstantNode)); ConstantNode* ret = (ConstantNode*)consoleAlloc(sizeof(ConstantNode));
constructInPlace(ret); constructInPlace(ret);
ret->dbgLineNumber = lineNumber; ret->dbgLineNumber = lineNumber;
ret->optimizedNode = NULL;
ret->value = value; ret->value = value;
return ret; return ret;
} }
AssignExprNode *AssignExprNode::alloc(S32 lineNumber, StringTableEntry varName, ExprNode *arrayIndex, ExprNode *expr) AssignExprNode* AssignExprNode::alloc(S32 lineNumber, StringTableEntry varName, ExprNode* arrayIndex, ExprNode* expr)
{ {
AssignExprNode *ret = (AssignExprNode *)consoleAlloc(sizeof(AssignExprNode)); AssignExprNode* ret = (AssignExprNode*)consoleAlloc(sizeof(AssignExprNode));
constructInPlace(ret); constructInPlace(ret);
ret->dbgLineNumber = lineNumber; ret->dbgLineNumber = lineNumber;
ret->optimizedNode = NULL;
ret->varName = varName; ret->varName = varName;
ret->expr = expr; ret->expr = expr;
ret->arrayIndex = arrayIndex; ret->arrayIndex = arrayIndex;
@ -268,11 +283,12 @@ AssignExprNode *AssignExprNode::alloc(S32 lineNumber, StringTableEntry varName,
return ret; return ret;
} }
AssignOpExprNode *AssignOpExprNode::alloc(S32 lineNumber, StringTableEntry varName, ExprNode *arrayIndex, ExprNode *expr, S32 op) AssignOpExprNode* AssignOpExprNode::alloc(S32 lineNumber, StringTableEntry varName, ExprNode* arrayIndex, ExprNode* expr, S32 op)
{ {
AssignOpExprNode *ret = (AssignOpExprNode *)consoleAlloc(sizeof(AssignOpExprNode)); AssignOpExprNode* ret = (AssignOpExprNode*)consoleAlloc(sizeof(AssignOpExprNode));
constructInPlace(ret); constructInPlace(ret);
ret->dbgLineNumber = lineNumber; ret->dbgLineNumber = lineNumber;
ret->optimizedNode = NULL;
ret->varName = varName; ret->varName = varName;
ret->expr = expr; ret->expr = expr;
ret->arrayIndex = arrayIndex; ret->arrayIndex = arrayIndex;
@ -280,9 +296,9 @@ AssignOpExprNode *AssignOpExprNode::alloc(S32 lineNumber, StringTableEntry varNa
return ret; return ret;
} }
TTagSetStmtNode *TTagSetStmtNode::alloc(S32 lineNumber, StringTableEntry tag, ExprNode *valueExpr, ExprNode *stringExpr) TTagSetStmtNode* TTagSetStmtNode::alloc(S32 lineNumber, StringTableEntry tag, ExprNode* valueExpr, ExprNode* stringExpr)
{ {
TTagSetStmtNode *ret = (TTagSetStmtNode *)consoleAlloc(sizeof(TTagSetStmtNode)); TTagSetStmtNode* ret = (TTagSetStmtNode*)consoleAlloc(sizeof(TTagSetStmtNode));
constructInPlace(ret); constructInPlace(ret);
ret->dbgLineNumber = lineNumber; ret->dbgLineNumber = lineNumber;
ret->tag = tag; ret->tag = tag;
@ -291,59 +307,54 @@ TTagSetStmtNode *TTagSetStmtNode::alloc(S32 lineNumber, StringTableEntry tag, Ex
return ret; return ret;
} }
TTagDerefNode *TTagDerefNode::alloc(S32 lineNumber, ExprNode *expr) TTagDerefNode* TTagDerefNode::alloc(S32 lineNumber, ExprNode* expr)
{ {
TTagDerefNode *ret = (TTagDerefNode *)consoleAlloc(sizeof(TTagDerefNode)); TTagDerefNode* ret = (TTagDerefNode*)consoleAlloc(sizeof(TTagDerefNode));
constructInPlace(ret); constructInPlace(ret);
ret->dbgLineNumber = lineNumber; ret->dbgLineNumber = lineNumber;
ret->optimizedNode = NULL;
ret->expr = expr; ret->expr = expr;
return ret; return ret;
} }
TTagExprNode *TTagExprNode::alloc(S32 lineNumber, StringTableEntry tag) TTagExprNode* TTagExprNode::alloc(S32 lineNumber, StringTableEntry tag)
{ {
TTagExprNode *ret = (TTagExprNode *)consoleAlloc(sizeof(TTagExprNode)); TTagExprNode* ret = (TTagExprNode*)consoleAlloc(sizeof(TTagExprNode));
constructInPlace(ret); constructInPlace(ret);
ret->dbgLineNumber = lineNumber; ret->dbgLineNumber = lineNumber;
ret->optimizedNode = NULL;
ret->tag = tag; ret->tag = tag;
return ret; return ret;
} }
FuncCallExprNode *FuncCallExprNode::alloc(S32 lineNumber, StringTableEntry funcName, StringTableEntry nameSpace, ExprNode *args, bool dot) FuncCallExprNode* FuncCallExprNode::alloc(S32 lineNumber, StringTableEntry funcName, StringTableEntry nameSpace, ExprNode* args, bool dot)
{ {
FuncCallExprNode *ret = (FuncCallExprNode *)consoleAlloc(sizeof(FuncCallExprNode)); FuncCallExprNode* ret = (FuncCallExprNode*)consoleAlloc(sizeof(FuncCallExprNode));
constructInPlace(ret); constructInPlace(ret);
ret->dbgLineNumber = lineNumber; ret->dbgLineNumber = lineNumber;
ret->optimizedNode = NULL;
ret->funcName = funcName; ret->funcName = funcName;
ret->nameSpace = nameSpace; ret->nameSpace = nameSpace;
ret->args = args; ret->args = args;
if (dot) if (dot)
ret->callType = MethodCall; ret->callType = MethodCall;
else else if (nameSpace != NULL)
{ {
if (nameSpace && !dStricmp(nameSpace, "Parent")) if (dStricmp(nameSpace, "Parent") == 0)
ret->callType = ParentCall; ret->callType = ParentCall;
else else
ret->callType = FunctionCall; ret->callType = StaticCall;
} }
else
ret->callType = FunctionCall;
return ret; return ret;
} }
FuncPointerCallExprNode *FuncPointerCallExprNode::alloc(S32 lineNumber, ExprNode *funcPointer, ExprNode *args) AssertCallExprNode* AssertCallExprNode::alloc(S32 lineNumber, ExprNode* testExpr, const char* message)
{
FuncPointerCallExprNode *ret = (FuncPointerCallExprNode *)consoleAlloc(sizeof(FuncPointerCallExprNode));
constructInPlace(ret);
ret->dbgLineNumber = lineNumber;
ret->funcPointer = funcPointer;
ret->args = args;
return ret;
}
AssertCallExprNode *AssertCallExprNode::alloc(S32 lineNumber, ExprNode *testExpr, const char *message)
{ {
#ifdef TORQUE_ENABLE_SCRIPTASSERTS #ifdef TORQUE_ENABLE_SCRIPTASSERTS
AssertCallExprNode *ret = (AssertCallExprNode *)consoleAlloc(sizeof(FuncCallExprNode)); AssertCallExprNode* ret = (AssertCallExprNode*)consoleAlloc(sizeof(FuncCallExprNode));
constructInPlace(ret); constructInPlace(ret);
ret->dbgLineNumber = lineNumber; ret->dbgLineNumber = lineNumber;
ret->testExpr = testExpr; ret->testExpr = testExpr;
@ -357,10 +368,11 @@ AssertCallExprNode *AssertCallExprNode::alloc(S32 lineNumber, ExprNode *testExpr
#endif #endif
} }
SlotAccessNode *SlotAccessNode::alloc(S32 lineNumber, ExprNode *objectExpr, ExprNode *arrayExpr, StringTableEntry slotName) SlotAccessNode* SlotAccessNode::alloc(S32 lineNumber, ExprNode* objectExpr, ExprNode* arrayExpr, StringTableEntry slotName)
{ {
SlotAccessNode *ret = (SlotAccessNode *)consoleAlloc(sizeof(SlotAccessNode)); SlotAccessNode* ret = (SlotAccessNode*)consoleAlloc(sizeof(SlotAccessNode));
constructInPlace(ret); constructInPlace(ret);
ret->optimizedNode = NULL;
ret->dbgLineNumber = lineNumber; ret->dbgLineNumber = lineNumber;
ret->objectExpr = objectExpr; ret->objectExpr = objectExpr;
ret->arrayExpr = arrayExpr; ret->arrayExpr = arrayExpr;
@ -368,22 +380,24 @@ SlotAccessNode *SlotAccessNode::alloc(S32 lineNumber, ExprNode *objectExpr, Expr
return ret; return ret;
} }
InternalSlotAccessNode *InternalSlotAccessNode::alloc(S32 lineNumber, ExprNode *objectExpr, ExprNode *slotExpr, bool recurse) InternalSlotAccessNode* InternalSlotAccessNode::alloc(S32 lineNumber, ExprNode* objectExpr, ExprNode* slotExpr, bool recurse)
{ {
InternalSlotAccessNode *ret = (InternalSlotAccessNode *)consoleAlloc(sizeof(InternalSlotAccessNode)); InternalSlotAccessNode* ret = (InternalSlotAccessNode*)consoleAlloc(sizeof(InternalSlotAccessNode));
constructInPlace(ret); constructInPlace(ret);
ret->dbgLineNumber = lineNumber; ret->dbgLineNumber = lineNumber;
ret->optimizedNode = NULL;
ret->objectExpr = objectExpr; ret->objectExpr = objectExpr;
ret->slotExpr = slotExpr; ret->slotExpr = slotExpr;
ret->recurse = recurse; ret->recurse = recurse;
return ret; return ret;
} }
SlotAssignNode *SlotAssignNode::alloc(S32 lineNumber, ExprNode *objectExpr, ExprNode *arrayExpr, StringTableEntry slotName, ExprNode *valueExpr, U32 typeID /* = -1 */) SlotAssignNode* SlotAssignNode::alloc(S32 lineNumber, ExprNode* objectExpr, ExprNode* arrayExpr, StringTableEntry slotName, ExprNode* valueExpr, U32 typeID /* = -1 */)
{ {
SlotAssignNode *ret = (SlotAssignNode *)consoleAlloc(sizeof(SlotAssignNode)); SlotAssignNode* ret = (SlotAssignNode*)consoleAlloc(sizeof(SlotAssignNode));
constructInPlace(ret); constructInPlace(ret);
ret->dbgLineNumber = lineNumber; ret->dbgLineNumber = lineNumber;
ret->optimizedNode = NULL;
ret->objectExpr = objectExpr; ret->objectExpr = objectExpr;
ret->arrayExpr = arrayExpr; ret->arrayExpr = arrayExpr;
ret->slotName = slotName; ret->slotName = slotName;
@ -392,11 +406,12 @@ SlotAssignNode *SlotAssignNode::alloc(S32 lineNumber, ExprNode *objectExpr, Expr
return ret; return ret;
} }
SlotAssignOpNode *SlotAssignOpNode::alloc(S32 lineNumber, ExprNode *objectExpr, StringTableEntry slotName, ExprNode *arrayExpr, S32 op, ExprNode *valueExpr) SlotAssignOpNode* SlotAssignOpNode::alloc(S32 lineNumber, ExprNode* objectExpr, StringTableEntry slotName, ExprNode* arrayExpr, S32 op, ExprNode* valueExpr)
{ {
SlotAssignOpNode *ret = (SlotAssignOpNode *)consoleAlloc(sizeof(SlotAssignOpNode)); SlotAssignOpNode* ret = (SlotAssignOpNode*)consoleAlloc(sizeof(SlotAssignOpNode));
constructInPlace(ret); constructInPlace(ret);
ret->dbgLineNumber = lineNumber; ret->dbgLineNumber = lineNumber;
ret->optimizedNode = NULL;
ret->objectExpr = objectExpr; ret->objectExpr = objectExpr;
ret->arrayExpr = arrayExpr; ret->arrayExpr = arrayExpr;
ret->slotName = slotName; ret->slotName = slotName;
@ -405,11 +420,12 @@ SlotAssignOpNode *SlotAssignOpNode::alloc(S32 lineNumber, ExprNode *objectExpr,
return ret; return ret;
} }
ObjectDeclNode *ObjectDeclNode::alloc(S32 lineNumber, ExprNode *classNameExpr, ExprNode *objectNameExpr, ExprNode *argList, StringTableEntry parentObject, SlotAssignNode *slotDecls, ObjectDeclNode *subObjects, bool isDatablock, bool classNameInternal, bool isSingleton) ObjectDeclNode* ObjectDeclNode::alloc(S32 lineNumber, ExprNode* classNameExpr, ExprNode* objectNameExpr, ExprNode* argList, StringTableEntry parentObject, SlotAssignNode* slotDecls, ObjectDeclNode* subObjects, bool isDatablock, bool classNameInternal, bool isSingleton)
{ {
ObjectDeclNode *ret = (ObjectDeclNode *)consoleAlloc(sizeof(ObjectDeclNode)); ObjectDeclNode* ret = (ObjectDeclNode*)consoleAlloc(sizeof(ObjectDeclNode));
constructInPlace(ret); constructInPlace(ret);
ret->dbgLineNumber = lineNumber; ret->dbgLineNumber = lineNumber;
ret->optimizedNode = NULL;
ret->classNameExpr = classNameExpr; ret->classNameExpr = classNameExpr;
ret->objectNameExpr = objectNameExpr; ret->objectNameExpr = objectNameExpr;
ret->argList = argList; ret->argList = argList;
@ -422,13 +438,13 @@ ObjectDeclNode *ObjectDeclNode::alloc(S32 lineNumber, ExprNode *classNameExpr, E
if (parentObject) if (parentObject)
ret->parentObject = parentObject; ret->parentObject = parentObject;
else else
ret->parentObject = StringTable->EmptyString(); ret->parentObject = StringTable->insert("");
return ret; return ret;
} }
FunctionDeclStmtNode *FunctionDeclStmtNode::alloc(S32 lineNumber, StringTableEntry fnName, StringTableEntry nameSpace, VarNode *args, StmtNode *stmts) FunctionDeclStmtNode* FunctionDeclStmtNode::alloc(S32 lineNumber, StringTableEntry fnName, StringTableEntry nameSpace, VarNode* args, StmtNode* stmts)
{ {
FunctionDeclStmtNode *ret = (FunctionDeclStmtNode *)consoleAlloc(sizeof(FunctionDeclStmtNode)); FunctionDeclStmtNode* ret = (FunctionDeclStmtNode*)consoleAlloc(sizeof(FunctionDeclStmtNode));
constructInPlace(ret); constructInPlace(ret);
ret->dbgLineNumber = lineNumber; ret->dbgLineNumber = lineNumber;
ret->fnName = fnName; ret->fnName = fnName;

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -23,19 +23,36 @@
#ifndef _CODEBLOCK_H_ #ifndef _CODEBLOCK_H_
#define _CODEBLOCK_H_ #define _CODEBLOCK_H_
#include <vector>
#include <unordered_map>
struct CompilerLocalVariableToRegisterMappingTable
{
struct RemappingTable
{
std::vector<StringTableEntry> varList;
};
std::unordered_map<StringTableEntry, RemappingTable> localVarToRegister;
void add(StringTableEntry functionName, StringTableEntry namespaceName, StringTableEntry varName);
S32 lookup(StringTableEntry namespaceName, StringTableEntry functionName, StringTableEntry varName);
CompilerLocalVariableToRegisterMappingTable copy();
void reset();
void write(Stream& stream);
};
#include "console/compiler.h" #include "console/compiler.h"
#include "console/consoleParser.h" #include "console/consoleParser.h"
class Stream; class Stream;
class ConsoleValue; class ConsoleValue;
class ConsoleValueRef;
/// Core TorqueScript code management class. /// Core TorqueScript code management class.
/// ///
/// This class represents a block of code, usually mapped directly to a file. /// This class represents a block of code, usually mapped directly to a file.
class CodeBlock class CodeBlock
{ {
friend class CodeInterpreter;
private: private:
static CodeBlock* smCodeBlockList; static CodeBlock* smCodeBlockList;
static CodeBlock* smCurrentCodeBlock; static CodeBlock* smCurrentCodeBlock;
@ -78,6 +95,8 @@ public:
U32 codeSize; U32 codeSize;
U32 *code; U32 *code;
CompilerLocalVariableToRegisterMappingTable variableRegisterTable;
U32 refCount; U32 refCount;
U32 lineBreakPairCount; U32 lineBreakPairCount;
U32 *lineBreakPairs; U32 *lineBreakPairs;
@ -130,7 +149,7 @@ public:
/// with, zero being the top of the stack. If the the index is /// with, zero being the top of the stack. If the the index is
/// -1 a new frame is created. If the index is out of range the /// -1 a new frame is created. If the index is out of range the
/// top stack frame is used. /// top stack frame is used.
ConsoleValueRef compileExec(StringTableEntry fileName, const char *script, ConsoleValue compileExec(StringTableEntry fileName, const char *script,
bool noCalls, S32 setFrame = -1); bool noCalls, S32 setFrame = -1);
/// Executes the existing code in the CodeBlock. The return string is any /// Executes the existing code in the CodeBlock. The return string is any
@ -148,8 +167,8 @@ public:
/// -1 a new frame is created. If the index is out of range the /// -1 a new frame is created. If the index is out of range the
/// top stack frame is used. /// top stack frame is used.
/// @param packageName The code package name or null. /// @param packageName The code package name or null.
ConsoleValueRef exec(U32 offset, const char *fnName, Namespace *ns, U32 argc, ConsoleValue exec(U32 offset, const char *fnName, Namespace *ns, U32 argc,
ConsoleValueRef *argv, bool noCalls, StringTableEntry packageName, ConsoleValue *argv, bool noCalls, StringTableEntry packageName,
S32 setFrame = -1); S32 setFrame = -1);
}; };

File diff suppressed because it is too large Load diff

View file

@ -1,262 +0,0 @@
//-----------------------------------------------------------------------------
// 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 _CODEINTERPRETER_H_
#define _CODEINTERPRETER_H_
#include "console/codeBlock.h"
#include "console/console.h"
#include "console/consoleInternal.h"
/// Frame data for a foreach/foreach$ loop.
struct IterStackRecord
{
/// If true, this is a foreach$ loop; if not, it's a foreach loop.
bool mIsStringIter;
/// The iterator variable.
Dictionary::Entry* mVariable;
/// Information for an object iterator loop.
struct ObjectPos
{
/// The set being iterated over.
SimSet* mSet;
/// Current index in the set.
U32 mIndex;
};
/// Information for a string iterator loop.
struct StringPos
{
/// The raw string data on the string stack.
StringStackPtr mString;
/// Current parsing position.
U32 mIndex;
};
union
{
ObjectPos mObj;
StringPos mStr;
} mData;
};
enum OPCodeReturn
{
exitCode = -1,
success = 0,
breakContinue = 1
};
class CodeInterpreter
{
public:
CodeInterpreter(CodeBlock *cb);
~CodeInterpreter();
ConsoleValueRef exec(U32 ip,
StringTableEntry functionName,
Namespace *thisNamespace,
U32 argc,
ConsoleValueRef *argv,
bool noCalls,
StringTableEntry packageName,
S32 setFrame);
static void init();
// Methods
private:
void parseArgs(U32 &ip);
/// Group op codes
/// @{
OPCodeReturn op_func_decl(U32 &ip);
OPCodeReturn op_create_object(U32 &ip);
OPCodeReturn op_add_object(U32 &ip);
OPCodeReturn op_end_object(U32 &ip);
OPCodeReturn op_finish_object(U32 &ip);
OPCodeReturn op_jmpiffnot(U32 &ip);
OPCodeReturn op_jmpifnot(U32 &ip);
OPCodeReturn op_jmpiff(U32 &ip);
OPCodeReturn op_jmpif(U32 &ip);
OPCodeReturn op_jmpifnot_np(U32 &ip);
OPCodeReturn op_jmpif_np(U32 &ip);
OPCodeReturn op_jmp(U32 &ip);
OPCodeReturn op_return_void(U32 &ip);
OPCodeReturn op_return(U32 &ip);
OPCodeReturn op_return_flt(U32 &ip);
OPCodeReturn op_return_uint(U32 &ip);
OPCodeReturn op_cmpeq(U32 &ip);
OPCodeReturn op_cmpgr(U32 &ip);
OPCodeReturn op_cmpge(U32 &ip);
OPCodeReturn op_cmplt(U32 &ip);
OPCodeReturn op_cmple(U32 &ip);
OPCodeReturn op_cmpne(U32 &ip);
OPCodeReturn op_xor(U32 &ip);
OPCodeReturn op_mod(U32 &ip);
OPCodeReturn op_bitand(U32 &ip);
OPCodeReturn op_bitor(U32 &ip);
OPCodeReturn op_not(U32 &ip);
OPCodeReturn op_notf(U32 &ip);
OPCodeReturn op_onescomplement(U32 &ip);
OPCodeReturn op_shr(U32 &ip);
OPCodeReturn op_shl(U32 &ip);
OPCodeReturn op_and(U32 &ip);
OPCodeReturn op_or(U32 &ip);
OPCodeReturn op_add(U32 &ip);
OPCodeReturn op_sub(U32 &ip);
OPCodeReturn op_mul(U32 &ip);
OPCodeReturn op_div(U32 &ip);
OPCodeReturn op_neg(U32 &ip);
OPCodeReturn op_inc(U32 &ip);
OPCodeReturn op_dec(U32 &ip);
OPCodeReturn op_setcurvar(U32 &ip);
OPCodeReturn op_setcurvar_create(U32 &ip);
OPCodeReturn op_setcurvar_array(U32 &ip);
OPCodeReturn op_setcurvar_array_varlookup(U32 &ip);
OPCodeReturn op_setcurvar_array_create(U32 &ip);
OPCodeReturn op_setcurvar_array_create_varlookup(U32 &ip);
OPCodeReturn op_loadvar_uint(U32 &ip);
OPCodeReturn op_loadvar_flt(U32 &ip);
OPCodeReturn op_loadvar_str(U32 &ip);
OPCodeReturn op_loadvar_var(U32 &ip);
OPCodeReturn op_savevar_uint(U32 &ip);
OPCodeReturn op_savevar_flt(U32 &ip);
OPCodeReturn op_savevar_str(U32 &ip);
OPCodeReturn op_savevar_var(U32 &ip);
OPCodeReturn op_setcurobject(U32 &ip);
OPCodeReturn op_setcurobject_internal(U32 &ip);
OPCodeReturn op_setcurobject_new(U32 &ip);
OPCodeReturn op_setcurfield(U32 &ip);
OPCodeReturn op_setcurfield_array(U32 &ip);
OPCodeReturn op_setcurfield_type(U32 &ip);
OPCodeReturn op_setcurfield_this(U32 &ip);
OPCodeReturn op_setcurfield_array_var(U32 &ip);
OPCodeReturn op_loadfield_uint(U32 &ip);
OPCodeReturn op_loadfield_flt(U32 &ip);
OPCodeReturn op_loadfield_str(U32 &ip);
OPCodeReturn op_savefield_uint(U32 &ip);
OPCodeReturn op_savefield_flt(U32 &ip);
OPCodeReturn op_savefield_str(U32 &ip);
OPCodeReturn op_str_to_uint(U32 &ip);
OPCodeReturn op_str_to_flt(U32 &ip);
OPCodeReturn op_str_to_none(U32 &ip);
OPCodeReturn op_flt_to_uint(U32 &ip);
OPCodeReturn op_flt_to_str(U32 &ip);
OPCodeReturn op_flt_to_none(U32 &ip);
OPCodeReturn op_uint_to_flt(U32 &ip);
OPCodeReturn op_uint_to_str(U32 &ip);
OPCodeReturn op_uint_to_none(U32 &ip);
OPCodeReturn op_copyvar_to_none(U32 &ip);
OPCodeReturn op_loadimmed_uint(U32 &ip);
OPCodeReturn op_loadimmed_flt(U32 &ip);
OPCodeReturn op_tag_to_str(U32 &ip);
OPCodeReturn op_loadimmed_str(U32 &ip);
OPCodeReturn op_docblock_str(U32 &ip);
OPCodeReturn op_loadimmed_ident(U32 &ip);
OPCodeReturn op_callfunc_resolve(U32 &ip);
OPCodeReturn op_callfunc(U32 &ip);
OPCodeReturn op_callfunc_pointer(U32 &ip);
OPCodeReturn op_callfunc_this(U32 &ip);
OPCodeReturn op_advance_str(U32 &ip);
OPCodeReturn op_advance_str_appendchar(U32 &ip);
OPCodeReturn op_advance_str_comma(U32 &ip);
OPCodeReturn op_advance_str_nul(U32 &ip);
OPCodeReturn op_rewind_str(U32 &ip);
OPCodeReturn op_terminate_rewind_str(U32 &ip);
OPCodeReturn op_compare_str(U32 &ip);
OPCodeReturn op_push(U32 &ip);
OPCodeReturn op_push_uint(U32 &ip);
OPCodeReturn op_push_flt(U32 &ip);
OPCodeReturn op_push_var(U32 &ip);
OPCodeReturn op_push_this(U32 &ip);
OPCodeReturn op_push_frame(U32 &ip);
OPCodeReturn op_assert(U32 &ip);
OPCodeReturn op_break(U32 &ip);
OPCodeReturn op_iter_begin_str(U32 &ip);
OPCodeReturn op_iter_begin(U32 &ip);
OPCodeReturn op_iter(U32 &ip);
OPCodeReturn op_iter_end(U32 &ip);
OPCodeReturn op_invalid(U32 &ip);
/// @}
private:
CodeBlock *mCodeBlock;
/// Group exec arguments.
struct
{
StringTableEntry functionName;
Namespace *thisNamespace;
U32 argc;
ConsoleValueRef *argv;
bool noCalls;
StringTableEntry packageName;
S32 setFrame;
} mExec;
U32 mIterDepth;
F64 *mCurFloatTable;
char *mCurStringTable;
StringTableEntry mThisFunctionName;
bool mPopFrame;
// Add local object creation stack [7/9/2007 Black]
static const U32 objectCreationStackSize = 32;
U32 mObjectCreationStackIndex;
struct
{
SimObject *newObject;
U32 failJump;
} mObjectCreationStack[objectCreationStackSize];
SimObject *mCurrentNewObject;
U32 mFailJump;
StringTableEntry mPrevField;
StringTableEntry mCurField;
SimObject *mPrevObject;
SimObject *mCurObject;
SimObject *mSaveObject;
SimObject *mThisObject;
Namespace::Entry *mNSEntry;
StringTableEntry mCurFNDocBlock;
StringTableEntry mCurNSDocBlock;
U32 mCallArgc;
ConsoleValueRef *mCallArgv;
CodeBlock *mSaveCodeBlock;
// note: anything returned is pushed to CSTK and will be invalidated on the next exec()
ConsoleValueRef mReturnValue;
U32 mCurrentInstruction;
static const S32 nsDocLength = 128;
char mNSDocBlockClass[nsDocLength];
};
#endif

File diff suppressed because it is too large Load diff

View file

@ -60,6 +60,7 @@ namespace Compiler
CompilerFloatTable *gCurrentFloatTable, gGlobalFloatTable, gFunctionFloatTable; CompilerFloatTable *gCurrentFloatTable, gGlobalFloatTable, gFunctionFloatTable;
DataChunker gConsoleAllocator; DataChunker gConsoleAllocator;
CompilerIdentTable gIdentTable; CompilerIdentTable gIdentTable;
CompilerLocalVariableToRegisterMappingTable gFunctionVariableMappingTable;
//------------------------------------------------------------ //------------------------------------------------------------
@ -92,6 +93,8 @@ namespace Compiler
CompilerStringTable &getGlobalStringTable() { return gGlobalStringTable; } CompilerStringTable &getGlobalStringTable() { return gGlobalStringTable; }
CompilerStringTable &getFunctionStringTable() { return gFunctionStringTable; } CompilerStringTable &getFunctionStringTable() { return gFunctionStringTable; }
CompilerLocalVariableToRegisterMappingTable& getFunctionVariableMappingTable() { return gFunctionVariableMappingTable; }
void setCurrentStringTable(CompilerStringTable* cst) { gCurrentStringTable = cst; } void setCurrentStringTable(CompilerStringTable* cst) { gCurrentStringTable = cst; }
CompilerFloatTable *getCurrentFloatTable() { return gCurrentFloatTable; } CompilerFloatTable *getCurrentFloatTable() { return gCurrentFloatTable; }
@ -117,6 +120,7 @@ namespace Compiler
getFunctionFloatTable().reset(); getFunctionFloatTable().reset();
getFunctionStringTable().reset(); getFunctionStringTable().reset();
getIdentTable().reset(); getIdentTable().reset();
getFunctionVariableMappingTable().reset();
} }
void *consoleAlloc(U32 size) { return gConsoleAllocator.alloc(size); } void *consoleAlloc(U32 size) { return gConsoleAllocator.alloc(size); }
@ -208,6 +212,66 @@ void CompilerStringTable::write(Stream &st)
//------------------------------------------------------------ //------------------------------------------------------------
void CompilerLocalVariableToRegisterMappingTable::add(StringTableEntry functionName, StringTableEntry namespaceName, StringTableEntry varName)
{
StringTableEntry funcLookupTableName = StringTable->insert(avar("%s::%s", namespaceName, functionName));
localVarToRegister[funcLookupTableName].varList.push_back(varName);;
}
S32 CompilerLocalVariableToRegisterMappingTable::lookup(StringTableEntry namespaceName, StringTableEntry functionName, StringTableEntry varName)
{
StringTableEntry funcLookupTableName = StringTable->insert(avar("%s::%s", namespaceName, functionName));
auto functionPosition = localVarToRegister.find(funcLookupTableName);
if (functionPosition != localVarToRegister.end())
{
const auto& table = localVarToRegister[funcLookupTableName].varList;
auto varPosition = std::find(table.begin(), table.end(), varName);
if (varPosition != table.end())
{
return std::distance(table.begin(), varPosition);
}
}
Con::errorf("Unable to find local variable %s in function name %s", varName, funcLookupTableName);
return -1;
}
CompilerLocalVariableToRegisterMappingTable CompilerLocalVariableToRegisterMappingTable::copy()
{
// Trivilly copyable as its all plain old data and using STL containers... (We want a deep copy though!)
CompilerLocalVariableToRegisterMappingTable table;
table.localVarToRegister = localVarToRegister;
return table;
}
void CompilerLocalVariableToRegisterMappingTable::reset()
{
localVarToRegister.clear();
}
void CompilerLocalVariableToRegisterMappingTable::write(Stream& stream)
{
stream.write((U32)localVarToRegister.size());
for (const auto& pair : localVarToRegister)
{
StringTableEntry functionName = pair.first;
stream.writeString(functionName);
const auto& localVariableTableForFunction = localVarToRegister[functionName].varList;
stream.write((U32)localVariableTableForFunction.size());
for (const StringTableEntry& varName : localVariableTableForFunction)
{
stream.writeString(varName);
}
}
}
//------------------------------------------------------------
U32 CompilerFloatTable::add(F64 value) U32 CompilerFloatTable::add(F64 value)
{ {
Entry **walk; Entry **walk;

View file

@ -44,6 +44,8 @@ class DataChunker;
#include "core/util/tVector.h" #include "core/util/tVector.h"
#endif #endif
//------------------------------------------------------------
namespace Compiler namespace Compiler
{ {
/// The opcodes for the TorqueScript VM. /// The opcodes for the TorqueScript VM.
@ -69,6 +71,7 @@ namespace Compiler
OP_RETURN_FLT, OP_RETURN_FLT,
OP_RETURN_UINT, OP_RETURN_UINT,
OP_CMPEQ, OP_CMPEQ,
OP_CMPGR, OP_CMPGR,
OP_CMPGE, OP_CMPGE,
@ -93,26 +96,28 @@ namespace Compiler
OP_MUL, OP_MUL,
OP_DIV, OP_DIV,
OP_NEG, OP_NEG,
OP_INC, OP_INC,
OP_DEC,
OP_SETCURVAR, OP_SETCURVAR,
OP_SETCURVAR_CREATE, OP_SETCURVAR_CREATE,
OP_SETCURVAR_ARRAY, OP_SETCURVAR_ARRAY,
OP_SETCURVAR_ARRAY_VARLOOKUP,
OP_SETCURVAR_ARRAY_CREATE, OP_SETCURVAR_ARRAY_CREATE,
OP_SETCURVAR_ARRAY_CREATE_VARLOOKUP,
OP_LOADVAR_UINT,// 40 OP_LOADVAR_UINT,// 40
OP_LOADVAR_FLT, OP_LOADVAR_FLT,
OP_LOADVAR_STR, OP_LOADVAR_STR,
OP_LOADVAR_VAR,
OP_SAVEVAR_UINT, OP_SAVEVAR_UINT,
OP_SAVEVAR_FLT, OP_SAVEVAR_FLT,
OP_SAVEVAR_STR, OP_SAVEVAR_STR,
OP_SAVEVAR_VAR,
OP_LOAD_LOCAL_VAR_UINT,
OP_LOAD_LOCAL_VAR_FLT,
OP_LOAD_LOCAL_VAR_STR,
OP_SAVE_LOCAL_VAR_UINT,
OP_SAVE_LOCAL_VAR_FLT,
OP_SAVE_LOCAL_VAR_STR,
OP_SETCUROBJECT, OP_SETCUROBJECT,
OP_SETCUROBJECT_NEW, OP_SETCUROBJECT_NEW,
@ -121,8 +126,6 @@ namespace Compiler
OP_SETCURFIELD, OP_SETCURFIELD,
OP_SETCURFIELD_ARRAY, // 50 OP_SETCURFIELD_ARRAY, // 50
OP_SETCURFIELD_TYPE, OP_SETCURFIELD_TYPE,
OP_SETCURFIELD_ARRAY_VAR,
OP_SETCURFIELD_THIS,
OP_LOADFIELD_UINT, OP_LOADFIELD_UINT,
OP_LOADFIELD_FLT, OP_LOADFIELD_FLT,
@ -132,43 +135,25 @@ namespace Compiler
OP_SAVEFIELD_FLT, OP_SAVEFIELD_FLT,
OP_SAVEFIELD_STR, OP_SAVEFIELD_STR,
OP_STR_TO_UINT, OP_POP_STK,
OP_STR_TO_FLT,
OP_STR_TO_NONE, // 60
OP_FLT_TO_UINT,
OP_FLT_TO_STR,
OP_FLT_TO_NONE,
OP_UINT_TO_FLT,
OP_UINT_TO_STR,
OP_UINT_TO_NONE,
OP_COPYVAR_TO_NONE,
OP_LOADIMMED_UINT, OP_LOADIMMED_UINT,
OP_LOADIMMED_FLT, OP_LOADIMMED_FLT,
OP_TAG_TO_STR, OP_TAG_TO_STR,
OP_LOADIMMED_STR, // 70 OP_LOADIMMED_STR, // 70
OP_DOCBLOCK_STR, OP_DOCBLOCK_STR, // 76
OP_LOADIMMED_IDENT, OP_LOADIMMED_IDENT,
OP_CALLFUNC_RESOLVE,
OP_CALLFUNC, OP_CALLFUNC,
OP_CALLFUNC_POINTER,
OP_CALLFUNC_THIS,
OP_ADVANCE_STR,
OP_ADVANCE_STR_APPENDCHAR, OP_ADVANCE_STR_APPENDCHAR,
OP_ADVANCE_STR_COMMA,
OP_ADVANCE_STR_NUL,
OP_REWIND_STR, OP_REWIND_STR,
OP_TERMINATE_REWIND_STR, // 80 OP_TERMINATE_REWIND_STR,
OP_COMPARE_STR, OP_COMPARE_STR,
OP_PUSH, // String OP_PUSH,
OP_PUSH_UINT, // Integer OP_PUSH_FRAME,
OP_PUSH_FLT, // Float
OP_PUSH_VAR, // Variable
OP_PUSH_THIS, // This pointer
OP_PUSH_FRAME, // Frame
OP_ASSERT, OP_ASSERT,
OP_BREAK, OP_BREAK,
@ -269,6 +254,7 @@ namespace Compiler
CompilerStringTable *getCurrentStringTable(); CompilerStringTable *getCurrentStringTable();
CompilerStringTable &getGlobalStringTable(); CompilerStringTable &getGlobalStringTable();
CompilerStringTable &getFunctionStringTable(); CompilerStringTable &getFunctionStringTable();
CompilerLocalVariableToRegisterMappingTable& getFunctionVariableMappingTable();
void setCurrentStringTable(CompilerStringTable* cst); void setCurrentStringTable(CompilerStringTable* cst);

View file

@ -41,9 +41,40 @@
#include "platform/threads/mutex.h" #include "platform/threads/mutex.h"
#include "core/util/journal/journal.h" #include "core/util/journal/journal.h"
#include "cinterface/cinterface.h" #include "cinterface/cinterface.h"
#include "console/consoleValueStack.h"
extern StringStack STR; extern StringStack STR;
extern ConsoleValueStack CSTK; extern ConsoleValueStack<4096> gCallStack;
Vector<ConsoleValue::ConversionBuffer> ConsoleValue::sConversionBuffer;
void ConsoleValue::init()
{
sConversionBuffer.reserve(8192);
}
void ConsoleValue::resetConversionBuffer()
{
sConversionBuffer.resetAndTreatAsScratchBuffer();
}
char* ConsoleValue::convertToBuffer() const
{
ConversionBuffer conversion;
if (type == ConsoleValueType::cvFloat)
dSprintf(conversion.buffer, ConversionBufferStride, "%.9g", f);
else
dSprintf(conversion.buffer, ConversionBufferStride, "%lld", i);
sConversionBuffer.push_back(std::move(conversion));
return sConversionBuffer.last().buffer;
}
const char* ConsoleValue::getConsoleData() const
{
return Con::getData(type, ct->dataPtr, 0, ct->enumTable);
}
ConsoleDocFragment* ConsoleDocFragment::smFirst; ConsoleDocFragment* ConsoleDocFragment::smFirst;
ExprEvalState gEvalState; ExprEvalState gEvalState;
@ -271,8 +302,6 @@ StringTableEntry gCurrentFile;
StringTableEntry gCurrentRoot; StringTableEntry gCurrentRoot;
/// @} /// @}
S32 gObjectCopyFailures = -1;
bool alwaysUseDebugOutput = true; bool alwaysUseDebugOutput = true;
bool useTimestamp = false; bool useTimestamp = false;
bool useRealTimestamp = false; bool useRealTimestamp = false;
@ -327,6 +356,7 @@ void init()
// Setup the console types. // Setup the console types.
ConsoleBaseType::initialize(); ConsoleBaseType::initialize();
ConsoleValue::init();
// And finally, the ACR... // And finally, the ACR...
AbstractClassRep::initialize(); AbstractClassRep::initialize();
@ -344,10 +374,6 @@ void init()
addVariable( "instantGroup", TypeRealString, &gInstantGroup, "The group that objects will be added to when they are created.\n" addVariable( "instantGroup", TypeRealString, &gInstantGroup, "The group that objects will be added to when they are created.\n"
"@ingroup Console\n"); "@ingroup Console\n");
addVariable("Con::objectCopyFailures", TypeS32, &gObjectCopyFailures, "If greater than zero then it counts the number of object creation "
"failures based on a missing copy object and does not report an error..\n"
"@ingroup Console\n");
// Current script file name and root // Current script file name and root
addVariable( "Con::File", TypeString, &gCurrentFile, "The currently executing script file.\n" addVariable( "Con::File", TypeString, &gCurrentFile, "The currently executing script file.\n"
"@ingroup FileSystem\n"); "@ingroup FileSystem\n");
@ -1474,7 +1500,7 @@ bool executeFile(const char* fileName, bool noCalls, bool journalScript)
return ret; return ret;
} }
ConsoleValueRef evaluate(const char* string, bool echo, const char *fileName) ConsoleValue evaluate(const char* string, bool echo, const char *fileName)
{ {
ConsoleStackFrameSaver stackSaver; ConsoleStackFrameSaver stackSaver;
stackSaver.save(); stackSaver.save();
@ -1491,11 +1517,11 @@ ConsoleValueRef evaluate(const char* string, bool echo, const char *fileName)
fileName = StringTable->insert(fileName); fileName = StringTable->insert(fileName);
CodeBlock *newCodeBlock = new CodeBlock(); CodeBlock *newCodeBlock = new CodeBlock();
return newCodeBlock->compileExec(fileName, string, false, fileName ? -1 : 0); return std::move(newCodeBlock->compileExec(fileName, string, false, fileName ? -1 : 0));
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
ConsoleValueRef evaluatef(const char* string, ...) ConsoleValue evaluatef(const char* string, ...)
{ {
ConsoleStackFrameSaver stackSaver; ConsoleStackFrameSaver stackSaver;
stackSaver.save(); stackSaver.save();
@ -1512,36 +1538,41 @@ ConsoleValueRef evaluatef(const char* string, ...)
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Internal execute for global function which does not save the stack // Internal execute for global function which does not save the stack
ConsoleValueRef _internalExecute(S32 argc, ConsoleValueRef argv[]) ConsoleValue _internalExecute(S32 argc, ConsoleValue argv[])
{ {
StringTableEntry funcName = StringTable->insert(argv[0].getString());
const char** argv_str = static_cast<const char**>(malloc((argc - 1) * sizeof(char *))); const char** argv_str = static_cast<const char**>(malloc((argc - 1) * sizeof(char *)));
for (int i = 0; i < argc - 1; i++) for (int i = 0; i < argc - 1; i++)
{ {
argv_str[i] = argv[i + 1]; argv_str[i] = argv[i + 1].getString();
} }
bool result; bool result;
const char* methodRes = CInterface::CallFunction(NULL, argv[0], argv_str, argc - 1, &result); const char* methodRes = CInterface::CallFunction(NULL, funcName, argv_str, argc - 1, &result);
free(argv_str); free(argv_str);
if (result) if (result)
{ {
return ConsoleValueRef::fromValue(CSTK.pushString(methodRes)); ConsoleValue ret;
ret.setString(methodRes);
return std::move(ret);
} }
Namespace::Entry *ent; Namespace::Entry *ent;
StringTableEntry funcName = StringTable->insert(argv[0]);
ent = Namespace::global()->lookup(funcName); ent = Namespace::global()->lookup(funcName);
if(!ent) if(!ent)
{ {
warnf(ConsoleLogEntry::Script, "%s: Unknown command.", (const char*)argv[0]); warnf(ConsoleLogEntry::Script, "%s: Unknown command.", funcName);
STR.clearFunctionOffset(); STR.clearFunctionOffset();
return ConsoleValueRef(); return std::move(ConsoleValue());
} }
return ent->execute(argc, argv, &gEvalState);
return std::move(ent->execute(argc, argv, &gEvalState));
} }
ConsoleValueRef execute(S32 argc, ConsoleValueRef argv[]) ConsoleValue execute(S32 argc, ConsoleValue argv[])
{ {
#ifdef TORQUE_MULTITHREAD #ifdef TORQUE_MULTITHREAD
if(isMainThread()) if(isMainThread())
@ -1563,23 +1594,23 @@ ConsoleValueRef execute(S32 argc, ConsoleValueRef argv[])
#endif #endif
} }
ConsoleValueRef execute(S32 argc, const char *argv[]) ConsoleValue execute(S32 argc, const char *argv[])
{ {
ConsoleStackFrameSaver stackSaver; ConsoleStackFrameSaver stackSaver;
stackSaver.save(); stackSaver.save();
StringStackConsoleWrapper args(argc, argv); StringArrayToConsoleValueWrapper args(argc, argv);
return execute(args.count(), args); return std::move(execute(args.count(), args));
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Internal execute for object method which does not save the stack // Internal execute for object method which does not save the stack
ConsoleValueRef _internalExecute(SimObject *object, S32 argc, ConsoleValueRef argv[], bool thisCallOnly) static ConsoleValue _internalExecute(SimObject *object, S32 argc, ConsoleValue argv[], bool thisCallOnly)
{ {
if(argc < 2) if(argc < 2)
{ {
STR.clearFunctionOffset(); STR.clearFunctionOffset();
return ConsoleValueRef(); return std::move(ConsoleValue());
} }
// [neo, 10/05/2007 - #3010] // [neo, 10/05/2007 - #3010]
@ -1590,35 +1621,36 @@ ConsoleValueRef _internalExecute(SimObject *object, S32 argc, ConsoleValueRef ar
ICallMethod *com = dynamic_cast<ICallMethod *>(object); ICallMethod *com = dynamic_cast<ICallMethod *>(object);
if(com) if(com)
{ {
STR.pushFrame(); gCallStack.pushFrame(0);
CSTK.pushFrame();
com->callMethodArgList(argc, argv, false); com->callMethodArgList(argc, argv, false);
STR.popFrame(); gCallStack.popFrame();
CSTK.popFrame();
} }
} }
StringTableEntry funcName = StringTable->insert(argv[0].getString());
const char** argv_str = static_cast<const char**>(malloc((argc - 2) * sizeof(char *))); const char** argv_str = static_cast<const char**>(malloc((argc - 2) * sizeof(char *)));
for (int i = 0; i < argc - 2; i++) for (int i = 0; i < argc - 2; i++)
{ {
argv_str[i] = argv[i + 2]; argv_str[i] = argv[i + 2].getString();
} }
bool result; bool result;
const char* methodRes = CInterface::CallMethod(object, argv[0], argv_str, argc - 2, &result); const char* methodRes = CInterface::CallMethod(object, funcName, argv_str, argc - 2, &result);
free(argv_str); free(argv_str);
if (result) if (result)
{ {
return ConsoleValueRef::fromValue(CSTK.pushString(methodRes)); ConsoleValue val;
val.setString(methodRes);
return val;
} }
if(object->getNamespace()) if(object->getNamespace())
{ {
U32 ident = object->getId(); U32 ident = object->getId();
ConsoleValueRef oldIdent(argv[1]); const char* oldIdent = dStrdup(argv[1].getString());
StringTableEntry funcName = StringTable->insert(argv[0]);
Namespace::Entry *ent = object->getNamespace()->lookup(funcName); Namespace::Entry *ent = object->getNamespace()->lookup(funcName);
if(ent == NULL) if(ent == NULL)
@ -1626,37 +1658,35 @@ ConsoleValueRef _internalExecute(SimObject *object, S32 argc, ConsoleValueRef ar
//warnf(ConsoleLogEntry::Script, "%s: undefined for object '%s' - id %d", funcName, object->getName(), object->getId()); //warnf(ConsoleLogEntry::Script, "%s: undefined for object '%s' - id %d", funcName, object->getName(), object->getId());
STR.clearFunctionOffset(); STR.clearFunctionOffset();
return ConsoleValueRef(); return std::move(ConsoleValue());
} }
// Twiddle %this argument // Twiddle %this argument
ConsoleValue func_ident; argv[1].setInt(ident);
func_ident.setIntValue((S32)ident);
argv[1] = ConsoleValueRef::fromValue(&func_ident);
SimObject *save = gEvalState.thisObject; SimObject *save = gEvalState.thisObject;
gEvalState.thisObject = object; gEvalState.thisObject = object;
ConsoleValueRef ret = ent->execute(argc, argv, &gEvalState); ConsoleValue ret = std::move(ent->execute(argc, argv, &gEvalState));
gEvalState.thisObject = save; gEvalState.thisObject = save;
// Twiddle it back // Twiddle it back
argv[1] = oldIdent; argv[1].setString(oldIdent);
dFree(oldIdent);
return ret; return ret;
} }
warnf(ConsoleLogEntry::Script, "Con::execute - %d has no namespace: %s", object->getId(), (const char*)argv[0]); warnf(ConsoleLogEntry::Script, "Con::execute - %d has no namespace: %s", object->getId(), funcName);
STR.clearFunctionOffset(); STR.clearFunctionOffset();
return ConsoleValueRef(); return std::move(ConsoleValue());
} }
ConsoleValue execute(SimObject *object, S32 argc, ConsoleValue argv[], bool thisCallOnly)
ConsoleValueRef execute(SimObject *object, S32 argc, ConsoleValueRef argv[], bool thisCallOnly)
{ {
if(argc < 2) if(argc < 2)
{ {
STR.clearFunctionOffset(); STR.clearFunctionOffset();
return ConsoleValueRef(); return std::move(ConsoleValue());
} }
ConsoleStackFrameSaver stackSaver; ConsoleStackFrameSaver stackSaver;
@ -1666,7 +1696,7 @@ ConsoleValueRef execute(SimObject *object, S32 argc, ConsoleValueRef argv[], boo
{ {
if (isMainThread()) if (isMainThread())
{ {
return _internalExecute(object, argc, argv, thisCallOnly); return std::move(_internalExecute(object, argc, argv, thisCallOnly));
} }
else else
{ {
@ -1676,34 +1706,34 @@ ConsoleValueRef execute(SimObject *object, S32 argc, ConsoleValueRef argv[], boo
} }
} }
warnf(ConsoleLogEntry::Script, "Con::execute - %d has no namespace: %s", object->getId(), (const char*)argv[0]); warnf(ConsoleLogEntry::Script, "Con::execute - %d has no namespace: %s", object->getId(), argv[0].getString());
STR.clearFunctionOffset(); STR.clearFunctionOffset();
return ConsoleValueRef(); return std::move(ConsoleValue());
} }
ConsoleValueRef execute(SimObject *object, S32 argc, const char *argv[], bool thisCallOnly) ConsoleValue execute(SimObject *object, S32 argc, const char *argv[], bool thisCallOnly)
{ {
ConsoleStackFrameSaver stackSaver; ConsoleStackFrameSaver stackSaver;
stackSaver.save(); stackSaver.save();
StringStackConsoleWrapper args(argc, argv); StringArrayToConsoleValueWrapper args(argc, argv);
return execute(object, args.count(), args, thisCallOnly); return std::move(execute(object, args.count(), args, thisCallOnly));
} }
inline ConsoleValueRef _executef(SimObject *obj, S32 checkArgc, S32 argc, ConsoleValueRef *argv) inline ConsoleValue _executef(SimObject *obj, S32 checkArgc, S32 argc, ConsoleValue *argv)
{ {
const U32 maxArg = 12; const U32 maxArg = 12;
AssertWarn(checkArgc == argc, "Incorrect arg count passed to Con::executef(SimObject*)"); AssertFatal(checkArgc == argc, "Incorrect arg count passed to Con::executef(SimObject*)");
AssertFatal(argc <= maxArg - 1, "Too many args passed to Con::_executef(SimObject*). Please update the function to handle more."); AssertFatal(argc <= maxArg - 1, "Too many args passed to Con::_executef(SimObject*). Please update the function to handle more.");
return execute(obj, argc, argv); return std::move(execute(obj, argc, argv));
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
inline ConsoleValueRef _executef(S32 checkArgc, S32 argc, ConsoleValueRef *argv) inline ConsoleValue _executef(S32 checkArgc, S32 argc, ConsoleValue *argv)
{ {
const U32 maxArg = 10; const U32 maxArg = 10;
AssertFatal(checkArgc == argc, "Incorrect arg count passed to Con::executef()"); AssertFatal(checkArgc == argc, "Incorrect arg count passed to Con::executef()");
AssertFatal(argc <= maxArg, "Too many args passed to Con::_executef(). Please update the function to handle more."); AssertFatal(argc <= maxArg, "Too many args passed to Con::_executef(). Please update the function to handle more.");
return execute(argc, argv); return std::move(execute(argc, argv));
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -1901,15 +1931,9 @@ StringTableEntry getModNameFromPath(const char *path)
void postConsoleInput( RawData data ) void postConsoleInput( RawData data )
{ {
// Schedule this to happen at the next time event. // Schedule this to happen at the next time event.
ConsoleValue values[2]; ConsoleValue argv[2];
ConsoleValueRef argv[2]; argv[0].setString("eval");
argv[1].setString(reinterpret_cast<const char*>(data.data));
values[0].init();
values[0].setStringValue("eval");
values[1].init();
values[1].setStringValue((const char*)data.data);
argv[0].value = &values[0];
argv[1].value = &values[1];
Sim::postCurrentEvent(Sim::getRootGroup(), new SimConsoleEvent(2, argv, false)); Sim::postCurrentEvent(Sim::getRootGroup(), new SimConsoleEvent(2, argv, false));
} }
@ -2524,70 +2548,20 @@ DefineEngineFunction( logWarning, void, ( const char* message ),,
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
extern ConsoleValueStack CSTK; ConsoleValueToStringArrayWrapper::ConsoleValueToStringArrayWrapper(int targc, ConsoleValue *targv)
ConsoleValueRef::ConsoleValueRef(const ConsoleValueRef &ref)
{
value = ref.value;
}
ConsoleValueRef& ConsoleValueRef::operator=(const ConsoleValueRef &newValue)
{
value = newValue.value;
return *this;
}
ConsoleValueRef& ConsoleValueRef::operator=(const char *newValue)
{
AssertFatal(value, "value should not be NULL");
value->setStringValue(newValue);
return *this;
}
ConsoleValueRef& ConsoleValueRef::operator=(S32 newValue)
{
AssertFatal(value, "value should not be NULL");
value->setIntValue(newValue);
return *this;
}
ConsoleValueRef& ConsoleValueRef::operator=(U32 newValue)
{
AssertFatal(value, "value should not be NULL");
value->setIntValue(newValue);
return *this;
}
ConsoleValueRef& ConsoleValueRef::operator=(F32 newValue)
{
AssertFatal(value, "value should not be NULL");
value->setFloatValue(newValue);
return *this;
}
ConsoleValueRef& ConsoleValueRef::operator=(F64 newValue)
{
AssertFatal(value, "value should not be NULL");
value->setFloatValue(newValue);
return *this;
}
//------------------------------------------------------------------------------
StringStackWrapper::StringStackWrapper(int targc, ConsoleValueRef targv[])
{ {
argv = new const char*[targc]; argv = new const char*[targc];
argc = targc; argc = targc;
for (int i=0; i<targc; i++) for (S32 i = 0; i < targc; i++)
{ {
argv[i] = dStrdup(targv[i]); argv[i] = dStrdup(targv[i].getString());
} }
} }
StringStackWrapper::~StringStackWrapper() ConsoleValueToStringArrayWrapper::~ConsoleValueToStringArrayWrapper()
{ {
for (int i=0; i<argc; i++) for (S32 i = 0; i< argc; i++)
{ {
dFree(argv[i]); dFree(argv[i]);
} }
@ -2595,201 +2569,58 @@ StringStackWrapper::~StringStackWrapper()
} }
StringStackConsoleWrapper::StringStackConsoleWrapper(int targc, const char** targ) StringArrayToConsoleValueWrapper::StringArrayToConsoleValueWrapper(int targc, const char** targv)
{ {
argv = new ConsoleValueRef[targc]; argv = new ConsoleValue[targc]();
argvValue = new ConsoleValue[targc];
argc = targc; argc = targc;
for (int i=0; i<targc; i++) { for (int i=0; i<targc; i++)
argvValue[i].init(); {
argv[i].value = &argvValue[i]; argv[i].setString(targv[i]);
argvValue[i].setStackStringValue(targ[i]);
} }
} }
StringStackConsoleWrapper::~StringStackConsoleWrapper() StringArrayToConsoleValueWrapper::~StringArrayToConsoleValueWrapper()
{ {
for (int i=0; i<argc; i++)
{
argv[i] = 0;
}
delete[] argv; delete[] argv;
delete[] argvValue;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
S32 ConsoleValue::getSignedIntValue() ConsoleValue _BaseEngineConsoleCallbackHelper::_exec()
{ {
if(type <= TypeInternalString)
return (S32)fval;
else
return dAtoi(Con::getData(type, dataPtr, 0, enumTable));
}
U32 ConsoleValue::getIntValue()
{
if(type <= TypeInternalString)
return ival;
else
return dAtoi(Con::getData(type, dataPtr, 0, enumTable));
}
F32 ConsoleValue::getFloatValue()
{
if(type <= TypeInternalString)
return fval;
else
return dAtof(Con::getData(type, dataPtr, 0, enumTable));
}
const char *ConsoleValue::getStringValue()
{
if(type == TypeInternalString || type == TypeInternalStackString)
return sval;
else if (type == TypeInternalStringStackPtr)
return STR.mBuffer + (uintptr_t)sval;
else
{
// We need a string representation, so lets create one
const char *internalValue = NULL;
if(type == TypeInternalFloat)
internalValue = Con::getData(TypeF32, &fval, 0);
else if(type == TypeInternalInt)
internalValue = Con::getData(TypeS32, &ival, 0);
else
return Con::getData(type, dataPtr, 0, enumTable); // We can't save sval here since it is the same as dataPtr
if (!internalValue)
return "";
U32 stringLen = dStrlen(internalValue);
U32 newLen = ((stringLen + 1) + 15) & ~15; // pad upto next cache line
if (bufferLen == 0)
sval = (char *) dMalloc(newLen);
else if(newLen > bufferLen)
sval = (char *) dRealloc(sval, newLen);
dStrcpy(sval, internalValue, newLen);
bufferLen = newLen;
return sval;
}
}
StringStackPtr ConsoleValue::getStringStackPtr()
{
if (type == TypeInternalStringStackPtr)
return (uintptr_t)sval;
else
return (uintptr_t)-1;
}
bool ConsoleValue::getBoolValue()
{
if(type == TypeInternalString || type == TypeInternalStackString || type == TypeInternalStringStackPtr)
return dAtob(getStringValue());
if(type == TypeInternalFloat)
return fval > 0;
else if(type == TypeInternalInt)
return ival > 0;
else {
const char *value = Con::getData(type, dataPtr, 0, enumTable);
return dAtob(value);
}
}
void ConsoleValue::setIntValue(S32 val)
{
setFloatValue(val);
}
void ConsoleValue::setIntValue(U32 val)
{
if(type <= TypeInternalString)
{
fval = (F32)val;
ival = val;
if(bufferLen > 0)
{
dFree(sval);
bufferLen = 0;
}
sval = typeValueEmpty;
type = TypeInternalInt;
}
else
{
const char *dptr = Con::getData(TypeS32, &val, 0);
Con::setData(type, dataPtr, 0, 1, &dptr, enumTable);
}
}
void ConsoleValue::setBoolValue(bool val)
{
return setIntValue(val ? 1 : 0);
}
void ConsoleValue::setFloatValue(F32 val)
{
if(type <= TypeInternalString)
{
fval = val;
ival = static_cast<U32>(val);
if(bufferLen > 0)
{
dFree(sval);
bufferLen = 0;
}
sval = typeValueEmpty;
type = TypeInternalFloat;
}
else
{
const char *dptr = Con::getData(TypeF32, &val, 0);
Con::setData(type, dataPtr, 0, 1, &dptr, enumTable);
}
}
//------------------------------------------------------------------------------
ConsoleValueRef _BaseEngineConsoleCallbackHelper::_exec()
{
ConsoleValueRef returnValue;
if( mThis ) if( mThis )
{ {
// Cannot invoke callback until object has been registered // Cannot invoke callback until object has been registered
if (mThis->isProperlyAdded()) { if (mThis->isProperlyAdded())
returnValue = Con::_internalExecute( mThis, mArgc, mArgv, false ); {
} else { ConsoleValue returnValue = Con::_internalExecute( mThis, mArgc, mArgv, false );
STR.clearFunctionOffset(); mArgc = mInitialArgc; // reset
returnValue = ConsoleValueRef(); return std::move(returnValue);
} }
}
else
returnValue = Con::_internalExecute( mArgc, mArgv );
STR.clearFunctionOffset();
mArgc = mInitialArgc; // reset
return std::move(ConsoleValue());
}
ConsoleValue returnValue = std::move(Con::_internalExecute( mArgc, mArgv ));
mArgc = mInitialArgc; // reset args mArgc = mInitialArgc; // reset args
return returnValue; return std::move(returnValue);
} }
ConsoleValueRef _BaseEngineConsoleCallbackHelper::_execLater(SimConsoleThreadExecEvent *evt) ConsoleValue _BaseEngineConsoleCallbackHelper::_execLater(SimConsoleThreadExecEvent *evt)
{ {
mArgc = mInitialArgc; // reset args mArgc = mInitialArgc; // reset args
Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime()); Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
return evt->getCB().waitForResult(); return std::move(evt->getCB().waitForResult());
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void ConsoleStackFrameSaver::save() void ConsoleStackFrameSaver::save()
{ {
CSTK.pushFrame(); gCallStack.pushFrame(0);
STR.pushFrame();
mSaved = true; mSaved = true;
} }
@ -2797,7 +2628,6 @@ void ConsoleStackFrameSaver::restore()
{ {
if (mSaved) if (mSaved)
{ {
CSTK.popFrame(); gCallStack.popFrame();
STR.popFrame();
} }
} }

View file

@ -36,6 +36,7 @@
#include "core/util/str.h" #include "core/util/str.h"
#include "core/util/journal/journaledSignal.h" #include "core/util/journal/journaledSignal.h"
#include "core/stringTable.h"
class SimObject; class SimObject;
class Namespace; class Namespace;
@ -117,188 +118,313 @@ struct ConsoleLogEntry
typedef const char *StringTableEntry; typedef const char *StringTableEntry;
extern char *typeValueEmpty; extern char *typeValueEmpty;
enum ConsoleValueType
{
cvInteger = -4,
cvFloat = -3,
cvString = -2,
cvSTEntry = -1,
cvConsoleValueType = 0
};
struct ConsoleValueConsoleType
{
void* dataPtr;
EnumTable* enumTable;
};
class ConsoleValue class ConsoleValue
{ {
public: union
enum
{ {
TypeInternalInt = -5, F64 f;
TypeInternalFloat = -4, S64 i;
TypeInternalStringStackPtr = -3, char* s;
TypeInternalStackString = -2, void* data;
TypeInternalString = -1, ConsoleValueConsoleType* ct;
}; };
S32 type; S32 type;
public: enum Constants
// 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 ConversionBufferStride = 32
{
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;
};
}; };
U32 getIntValue(); struct ConversionBuffer
S32 getSignedIntValue();
F32 getFloatValue();
const char *getStringValue();
StringStackPtr getStringStackPtr();
bool getBoolValue();
void setIntValue(U32 val);
void setIntValue(S32 val);
void setFloatValue(F32 val);
void setStringValue(const char *value);
void setStackStringValue(const char *value);
void setStringStackPtrValue(StringStackPtr ptr);
void setBoolValue(bool val);
void init()
{ {
ival = 0; char buffer[ConversionBufferStride];
fval = 0; };
sval = typeValueEmpty;
bufferLen = 0; static Vector<ConversionBuffer> sConversionBuffer;
type = TypeInternalString;
char* convertToBuffer() const;
TORQUE_FORCEINLINE bool hasAllocatedData() const
{
return (type == ConsoleValueType::cvString || isConsoleType()) && data != NULL;
} }
void cleanup() const char* getConsoleData() const;
TORQUE_FORCEINLINE void cleanupData()
{ {
if ((type <= TypeInternalString) && (bufferLen > 0)) if (hasAllocatedData())
{ {
dFree(sval); dFree(data);
bufferLen = 0; data = NULL;
} }
sval = typeValueEmpty;
type = ConsoleValue::TypeInternalString;
ival = 0;
fval = 0;
} }
ConsoleValue() { init(); };
~ConsoleValue() { cleanup(); };
};
// Proxy class for console variables TORQUE_FORCEINLINE void _move(ConsoleValue&& ref) noexcept
// Can point to existing console variables, {
// or act like a free floating value. type = ref.type;
class ConsoleValueRef
{ switch (ref.type)
{
case cvInteger:
i = ref.i;
break;
case cvFloat:
f = ref.f;
break;
case cvSTEntry:
TORQUE_CASE_FALLTHROUGH;
case cvString:
s = ref.s;
break;
default:
data = ref.data;
break;
}
ref.data = NULL;
ref.setEmptyString();
}
public: public:
ConsoleValue *value; ConsoleValue()
{
type = ConsoleValueType::cvSTEntry;
s = const_cast<char*>(StringTable->EmptyString());
}
ConsoleValueRef() : value(0) { ; } ConsoleValue(ConsoleValue&& ref) noexcept
~ConsoleValueRef() { ; } {
_move(std::move(ref));
}
ConsoleValueRef(const ConsoleValueRef &ref); TORQUE_FORCEINLINE ConsoleValue& operator=(ConsoleValue&& ref) noexcept
{
_move(std::move(ref));
return *this;
}
static ConsoleValueRef fromValue(ConsoleValue *value) { ConsoleValueRef ref; ref.value = value; return ref; } ConsoleValue(const ConsoleValue&) = delete;
ConsoleValue& operator=(const ConsoleValue&) = delete;
const char *getStringValue() { return value ? value->getStringValue() : ""; } TORQUE_FORCEINLINE ~ConsoleValue()
StringStackPtr getStringStackPtrValue() { return value ? value->getStringStackPtr() : 0; } {
cleanupData();
}
inline U32 getIntValue() { return value ? value->getIntValue() : 0; } TORQUE_FORCEINLINE void reset()
inline S32 getSignedIntValue() { return value ? value->getSignedIntValue() : 0; } {
inline F32 getFloatValue() { return value ? value->getFloatValue() : 0.0f; } setEmptyString();
inline bool getBoolValue() { return value ? value->getBoolValue() : false; } }
inline operator const char*() { return getStringValue(); } TORQUE_FORCEINLINE F64 getFloat() const
inline operator String() { return String(getStringValue()); } {
inline operator U32() { return getIntValue(); } if (type == ConsoleValueType::cvFloat)
inline operator S32() { return getSignedIntValue(); } return f;
inline operator F32() { return getFloatValue(); } if (type == ConsoleValueType::cvInteger)
inline operator bool() { return getBoolValue(); } return i;
if (isStringType())
return dAtof(s);
return dAtof(getConsoleData());
}
inline bool isStringStackPtr() { return value ? value->type == ConsoleValue::TypeInternalStringStackPtr : false; } TORQUE_FORCEINLINE S64 getInt() const
inline bool isString() { return value ? value->type >= ConsoleValue::TypeInternalStringStackPtr : true; } {
inline bool isInt() { return value ? value->type == ConsoleValue::TypeInternalInt : false; } if (type == ConsoleValueType::cvInteger)
inline bool isFloat() { return value ? value->type == ConsoleValue::TypeInternalFloat : false; } return i;
inline S32 getType() { return value ? value->type : -1; } if (type == ConsoleValueType::cvFloat)
return f;
if (isStringType())
return dAtoi(s);
return dAtoi(getConsoleData());
}
// Note: operators replace value TORQUE_FORCEINLINE const char* getString() const
ConsoleValueRef& operator=(const ConsoleValueRef &other); {
ConsoleValueRef& operator=(const char *newValue); if (isStringType())
ConsoleValueRef& operator=(U32 newValue); return s;
ConsoleValueRef& operator=(S32 newValue); if (isNumberType())
ConsoleValueRef& operator=(F32 newValue); return convertToBuffer();
ConsoleValueRef& operator=(F64 newValue); return getConsoleData();
}
TORQUE_FORCEINLINE operator const char* () const
{
return getString();
}
TORQUE_FORCEINLINE bool getBool() const
{
if (type == ConsoleValueType::cvInteger)
return (bool)i;
if (type == ConsoleValueType::cvFloat)
return (bool)f;
if (isStringType())
return dAtob(s);
return dAtob(getConsoleData());
}
TORQUE_FORCEINLINE void setFloat(const F64 val)
{
cleanupData();
type = ConsoleValueType::cvFloat;
f = val;
}
TORQUE_FORCEINLINE void setInt(const S64 val)
{
cleanupData();
type = ConsoleValueType::cvInteger;
i = val;
}
TORQUE_FORCEINLINE void setString(const char* val)
{
setString(val, val != NULL ? dStrlen(val) : 0);
}
TORQUE_FORCEINLINE void setString(const char* val, S32 len)
{
if (len == 0)
{
setEmptyString();
return;
}
cleanupData();
type = ConsoleValueType::cvString;
s = (char*)dMalloc(static_cast<dsize_t>(len) + 1);
s[len] = '\0';
dStrcpy(s, val, static_cast<dsize_t>(len) + 1);
}
TORQUE_FORCEINLINE void setStringRef(const char* ref, S32 len)
{
cleanupData();
type = ConsoleValueType::cvString;
s = const_cast<char*>(ref);
}
TORQUE_FORCEINLINE void setBool(const bool val)
{
cleanupData();
type = ConsoleValueType::cvInteger;
i = (int)val;
}
TORQUE_FORCEINLINE void setStringTableEntry(StringTableEntry val)
{
cleanupData();
type = ConsoleValueType::cvSTEntry;
s = const_cast<char*>(val);
}
TORQUE_FORCEINLINE void setEmptyString()
{
setStringTableEntry(StringTable->EmptyString());
}
TORQUE_FORCEINLINE void setConsoleData(S32 consoleType, void* dataPtr, const EnumTable* enumTable)
{
cleanupData();
type = ConsoleValueType::cvSTEntry;
ct = new ConsoleValueConsoleType{ dataPtr, const_cast<EnumTable*>(enumTable) };
}
TORQUE_FORCEINLINE S32 getType() const
{
return type;
}
TORQUE_FORCEINLINE bool isStringType() const
{
return type == ConsoleValueType::cvString || type == ConsoleValueType::cvSTEntry;
}
TORQUE_FORCEINLINE bool isNumberType() const
{
return type == ConsoleValueType::cvFloat || type == ConsoleValueType::cvInteger;
}
TORQUE_FORCEINLINE bool isConsoleType() const
{
return type >= ConsoleValueType::cvConsoleValueType;
}
TORQUE_FORCEINLINE void setFastFloat(F64 flt)
{
type = ConsoleValueType::cvFloat;
f = flt;
}
TORQUE_FORCEINLINE F64 getFastFloat() const
{
return f;
}
TORQUE_FORCEINLINE void setFastInt(S64 flt)
{
type = ConsoleValueType::cvInteger;
i = flt;
}
TORQUE_FORCEINLINE S64 getFastInt() const
{
return i;
}
static void init();
static void resetConversionBuffer();
}; };
// Overrides to allow ConsoleValueRefs to be directly converted to S32&F32
inline S32 dAtoi(ConsoleValueRef &ref)
{
return ref.getSignedIntValue();
}
inline F32 dAtof(ConsoleValueRef &ref)
{
return ref.getFloatValue();
}
inline bool dAtob(ConsoleValue &ref)
{
return ref.getBoolValue();
}
// Transparently converts ConsoleValue[] to const char** // Transparently converts ConsoleValue[] to const char**
class StringStackWrapper class ConsoleValueToStringArrayWrapper
{ {
public: public:
const char **argv; const char **argv;
int argc; S32 argc;
StringStackWrapper(int targc, ConsoleValueRef targv[]); ConsoleValueToStringArrayWrapper(int targc, ConsoleValue* targv);
~StringStackWrapper(); ~ConsoleValueToStringArrayWrapper();
const char* operator[](int idx) { return argv[idx]; } const char* operator[](S32 idx) { return argv[idx]; }
operator const char**() { return argv; } operator const char**() { return argv; }
int count() { return argc; } S32 count() { return argc; }
}; };
// Transparently converts const char** to ConsoleValue // Transparently converts const char** to ConsoleValue
class StringStackConsoleWrapper class StringArrayToConsoleValueWrapper
{ {
public: public:
ConsoleValue *argvValue; ConsoleValue *argv;
ConsoleValueRef *argv; S32 argc;
int argc;
StringStackConsoleWrapper(int targc, const char **targv); StringArrayToConsoleValueWrapper(int targc, const char **targv);
~StringStackConsoleWrapper(); ~StringArrayToConsoleValueWrapper();
ConsoleValueRef& operator[](int idx) { return argv[idx]; } ConsoleValue& operator[](int idx) { return argv[idx]; }
operator ConsoleValueRef*() { return argv; } operator ConsoleValue*() { return argv; }
int count() { return argc; } S32 count() { return argc; }
}; };
/// @defgroup console_callbacks Scripting Engine Callbacks /// @defgroup console_callbacks Scripting Engine Callbacks
@ -319,11 +445,11 @@ public:
/// @{ /// @{
/// ///
typedef const char * (*StringCallback)(SimObject *obj, S32 argc, ConsoleValueRef argv[]); typedef const char * (*StringCallback)(SimObject *obj, S32 argc, ConsoleValue argv[]);
typedef S32(*IntCallback)(SimObject *obj, S32 argc, ConsoleValueRef argv[]); typedef S32(*IntCallback)(SimObject *obj, S32 argc, ConsoleValue argv[]);
typedef F32(*FloatCallback)(SimObject *obj, S32 argc, ConsoleValueRef argv[]); typedef F32(*FloatCallback)(SimObject *obj, S32 argc, ConsoleValue argv[]);
typedef void(*VoidCallback)(SimObject *obj, S32 argc, ConsoleValueRef argv[]); // We have it return a value so things don't break.. typedef void(*VoidCallback)(SimObject *obj, S32 argc, ConsoleValue argv[]); // We have it return a value so things don't break..
typedef bool(*BoolCallback)(SimObject *obj, S32 argc, ConsoleValueRef argv[]); typedef bool(*BoolCallback)(SimObject *obj, S32 argc, ConsoleValue argv[]);
typedef void(*ConsumerCallback)(U32 level, const char *consoleLine); typedef void(*ConsumerCallback)(U32 level, const char *consoleLine);
/// @} /// @}
@ -376,7 +502,8 @@ namespace Con
/// 10/14/14 - jamesu - 47->48 Added opcodes to reduce reliance on strings in function calls /// 10/14/14 - jamesu - 47->48 Added opcodes to reduce reliance on strings in function calls
/// 10/07/17 - JTH - 48->49 Added opcode for function pointers and revamp of interpreter /// 10/07/17 - JTH - 48->49 Added opcode for function pointers and revamp of interpreter
/// from switch to function calls. /// from switch to function calls.
DSOVersion = 49, /// 09/04/21 - JTH - 49->50 Rewrite of interpreter
DSOVersion = 50,
MaxLineLength = 512, ///< Maximum length of a line of console input. MaxLineLength = 512, ///< Maximum length of a line of console input.
MaxDataTypes = 256 ///< Maximum number of registered data types. MaxDataTypes = 256 ///< Maximum number of registered data types.
@ -786,8 +913,8 @@ namespace Con
/// char* result = execute(2, argv); /// char* result = execute(2, argv);
/// @endcode /// @endcode
/// NOTE: this function restores the console stack on return. /// NOTE: this function restores the console stack on return.
ConsoleValueRef execute(S32 argc, const char* argv[]); ConsoleValue execute(S32 argc, const char* argv[]);
ConsoleValueRef execute(S32 argc, ConsoleValueRef argv[]); ConsoleValue execute(S32 argc, ConsoleValue argv[]);
/// Call a Torque Script member function of a SimObject from C/C++ code. /// Call a Torque Script member function of a SimObject from C/C++ code.
/// @param object Object on which to execute the method call. /// @param object Object on which to execute the method call.
@ -802,8 +929,8 @@ namespace Con
/// char* result = execute(mysimobject, 3, argv); /// char* result = execute(mysimobject, 3, argv);
/// @endcode /// @endcode
/// NOTE: this function restores the console stack on return. /// NOTE: this function restores the console stack on return.
ConsoleValueRef execute(SimObject *object, S32 argc, const char* argv[], bool thisCallOnly = false); ConsoleValue execute(SimObject *object, S32 argc, const char* argv[], bool thisCallOnly = false);
ConsoleValueRef execute(SimObject *object, S32 argc, ConsoleValueRef argv[], bool thisCallOnly = false); ConsoleValue execute(SimObject *object, S32 argc, ConsoleValue argv[], bool thisCallOnly = false);
/// Executes a script file and compiles it for use in script. /// Executes a script file and compiles it for use in script.
/// ///
@ -821,13 +948,13 @@ namespace Con
/// @param echo Should we echo the string to the console? /// @param echo Should we echo the string to the console?
/// @param fileName Indicate what file this code is coming from; used in error reporting and such. /// @param fileName Indicate what file this code is coming from; used in error reporting and such.
/// NOTE: This function restores the console stack on return. /// NOTE: This function restores the console stack on return.
ConsoleValueRef evaluate(const char* string, bool echo = false, const char *fileName = NULL); ConsoleValue evaluate(const char* string, bool echo = false, const char *fileName = NULL);
/// Evaluate an arbitrary line of script. /// Evaluate an arbitrary line of script.
/// ///
/// This wraps dVsprintf(), so you can substitute parameters into the code being executed. /// This wraps dVsprintf(), so you can substitute parameters into the code being executed.
/// NOTE: This function restores the console stack on return. /// NOTE: This function restores the console stack on return.
ConsoleValueRef evaluatef(const char* string, ...); ConsoleValue evaluatef(const char* string, ...);
/// @} /// @}
@ -915,10 +1042,10 @@ namespace Con
/// @see _EngineConsoleExecCallbackHelper /// @see _EngineConsoleExecCallbackHelper
/// ///
template<typename R, typename ...ArgTs> template<typename R, typename ...ArgTs>
ConsoleValueRef executef(R r, ArgTs ...argTs) ConsoleValue executef(R r, ArgTs ...argTs)
{ {
_EngineConsoleExecCallbackHelper<R> callback(r); _EngineConsoleExecCallbackHelper<R> callback(r);
return callback.template call<ConsoleValueRef>(argTs...); return std::move(callback.template call<ConsoleValue>(argTs...));
} }
/// } /// }
}; };
@ -1192,9 +1319,9 @@ public:
static ConsoleConstructor cfg_ConsoleFunctionGroup_##groupName##_GroupBegin(NULL,#groupName,usage) static ConsoleConstructor cfg_ConsoleFunctionGroup_##groupName##_GroupBegin(NULL,#groupName,usage)
# define ConsoleToolFunction(name,returnType,minArgs,maxArgs,usage1) \ # define ConsoleToolFunction(name,returnType,minArgs,maxArgs,usage1) \
returnType ctf_##name(SimObject *, S32, ConsoleValueRef *argv); \ returnType ctf_##name(SimObject *, S32, ConsoleValue *argv); \
ConsoleConstructor cc_##name##_obj(NULL,#name,ctf_##name,usage1,minArgs,maxArgs, true); \ ConsoleConstructor cc_##name##_obj(NULL,#name,ctf_##name,usage1,minArgs,maxArgs, true); \
returnType ctf_##name(SimObject *, S32 argc, ConsoleValueRef *argv) returnType ctf_##name(SimObject *, S32 argc, ConsoleValue *argv)
# define ConsoleFunctionGroupEnd(groupName) \ # define ConsoleFunctionGroupEnd(groupName) \
static ConsoleConstructor cfg_##groupName##_GroupEnd(NULL,#groupName,NULL) static ConsoleConstructor cfg_##groupName##_GroupEnd(NULL,#groupName,NULL)
@ -1227,23 +1354,23 @@ public:
// These are identical to what's above, we just want to null out the usage strings. // These are identical to what's above, we just want to null out the usage strings.
# define ConsoleFunction(name,returnType,minArgs,maxArgs,usage1) \ # define ConsoleFunction(name,returnType,minArgs,maxArgs,usage1) \
static returnType c##name(SimObject *, S32, ConsoleValueRef*); \ static returnType c##name(SimObject *, S32, ConsoleValue*); \
static ConsoleConstructor g##name##obj(NULL,#name,c##name,"",minArgs,maxArgs);\ static ConsoleConstructor g##name##obj(NULL,#name,c##name,"",minArgs,maxArgs);\
static returnType c##name(SimObject *, S32 argc, ConsoleValueRef *argv) static returnType c##name(SimObject *, S32 argc, ConsoleValue *argv)
# define ConsoleToolFunction(name,returnType,minArgs,maxArgs,usage1) \ # define ConsoleToolFunction(name,returnType,minArgs,maxArgs,usage1) \
static returnType c##name(SimObject *, S32, ConsoleValueRef*); \ static returnType c##name(SimObject *, S32, ConsoleValue*); \
static ConsoleConstructor g##name##obj(NULL,#name,c##name,"",minArgs,maxArgs, true);\ static ConsoleConstructor g##name##obj(NULL,#name,c##name,"",minArgs,maxArgs, true);\
static returnType c##name(SimObject *, S32 argc, ConsoleValueRef *argv) static returnType c##name(SimObject *, S32 argc, ConsoleValue *argv)
# define ConsoleMethod(className,name,returnType,minArgs,maxArgs,usage1) \ # define ConsoleMethod(className,name,returnType,minArgs,maxArgs,usage1) \
static inline returnType c##className##name(className *, S32, ConsoleValueRef *argv); \ static inline returnType c##className##name(className *, S32, ConsoleValue *argv); \
static returnType c##className##name##caster(SimObject *object, S32 argc, ConsoleValueRef *argv) { \ static returnType c##className##name##caster(SimObject *object, S32 argc, ConsoleValue *argv) { \
conmethod_return_##returnType ) c##className##name(static_cast<className*>(object),argc,argv); \ conmethod_return_##returnType ) c##className##name(static_cast<className*>(object),argc,argv); \
}; \ }; \
static ConsoleConstructor \ static ConsoleConstructor \
className##name##obj(#className,#name,c##className##name##caster,"",minArgs,maxArgs); \ className##name##obj(#className,#name,c##className##name##caster,"",minArgs,maxArgs); \
static inline returnType c##className##name(className *object, S32 argc, ConsoleValueRef *argv) static inline returnType c##className##name(className *object, S32 argc, ConsoleValue *argv)
#define ConsoleDoc( text ) #define ConsoleDoc( text )

View file

@ -2286,7 +2286,8 @@ DefineEngineStringlyVariadicFunction( call, const char *, 2, 0, "( string functi
"@endtsexample\n\n" "@endtsexample\n\n"
"@ingroup Scripting" ) "@ingroup Scripting" )
{ {
return Con::execute( argc - 1, argv + 1 ); ConsoleValue returnValue = Con::execute(argc - 1, argv + 1);
return Con::getReturnBuffer(returnValue.getString());
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -2410,7 +2411,9 @@ DefineEngineFunction( exec, bool, ( const char* fileName, bool noCalls, bool jou
DefineEngineFunction( eval, const char*, ( const char* consoleString ), , "eval(consoleString)" ) DefineEngineFunction( eval, const char*, ( const char* consoleString ), , "eval(consoleString)" )
{ {
return Con::evaluate(consoleString, false, NULL); ConsoleValue returnValue = Con::evaluate(consoleString, false, NULL);
return Con::getReturnBuffer(returnValue.getString());
} }
DefineEngineFunction( getVariable, const char*, ( const char* varName ), , "(string varName)\n" DefineEngineFunction( getVariable, const char*, ( const char* varName ), , "(string varName)\n"

View file

@ -183,13 +183,13 @@ void Dictionary::exportVariables(const char *varString, const char *fileName, bo
for (s = sortList.begin(); s != sortList.end(); s++) for (s = sortList.begin(); s != sortList.end(); s++)
{ {
switch ((*s)->value.type) switch ((*s)->type)
{ {
case ConsoleValue::TypeInternalInt: case Entry::TypeInternalInt:
dSprintf(buffer, sizeof(buffer), "%s = %d;%s", (*s)->name, (*s)->value.ival, cat); dSprintf(buffer, sizeof(buffer), "%s = %d;%s", (*s)->name, (*s)->ival, cat);
break; break;
case ConsoleValue::TypeInternalFloat: case Entry::TypeInternalFloat:
dSprintf(buffer, sizeof(buffer), "%s = %g;%s", (*s)->name, (*s)->value.fval, cat); dSprintf(buffer, sizeof(buffer), "%s = %g;%s", (*s)->name, (*s)->fval, cat);
break; break;
default: default:
expandEscape(expandBuffer, (*s)->getStringValue()); expandEscape(expandBuffer, (*s)->getStringValue());
@ -243,13 +243,11 @@ void Dictionary::exportVariables(const char *varString, Vector<String> *names, V
if (values) if (values)
{ {
switch ((*s)->value.type) switch ((*s)->type)
{ {
case ConsoleValue::TypeInternalInt: case ConsoleValueType::cvInteger:
values->push_back(String::ToString((*s)->value.ival)); case ConsoleValueType::cvFloat:
break; values->push_back(String((*s)->getStringValue()));
case ConsoleValue::TypeInternalFloat:
values->push_back(String::ToString((*s)->value.fval));
break; break;
default: default:
expandEscape(expandBuffer, (*s)->getStringValue()); expandEscape(expandBuffer, (*s)->getStringValue());
@ -470,25 +468,94 @@ char *typeValueEmpty = "";
Dictionary::Entry::Entry(StringTableEntry in_name) Dictionary::Entry::Entry(StringTableEntry in_name)
{ {
name = in_name; name = in_name;
value.type = ConsoleValue::TypeInternalString; type = TypeInternalString;
notify = NULL; notify = NULL;
nextEntry = NULL; nextEntry = NULL;
mUsage = NULL; mUsage = NULL;
mIsConstant = false; mIsConstant = false;
mNext = NULL; mNext = NULL;
// NOTE: This is data inside a nameless
// union, so we don't need to init the rest. ival = 0;
value.init(); fval = 0;
sval = typeValueEmpty;
bufferLen = 0;
} }
Dictionary::Entry::~Entry() Dictionary::Entry::~Entry()
{ {
value.cleanup(); reset();
}
void Dictionary::Entry::reset()
{
name = NULL;
if (type <= TypeInternalString && sval != typeValueEmpty)
dFree(sval);
if (notify) if (notify)
delete notify; delete notify;
} }
void Dictionary::Entry::setStringValue(const char* value)
{
if (mIsConstant)
{
Con::errorf("Cannot assign value to constant '%s'.", name);
return;
}
if (type <= TypeInternalString)
{
// Let's not remove empty-string-valued global vars from the dict.
// If we remove them, then they won't be exported, and sometimes
// it could be necessary to export such a global. There are very
// few empty-string global vars so there's no performance-related
// need to remove them from the dict.
/*
if(!value[0] && name[0] == '$')
{
gEvalState.globalVars.remove(this);
return;
}
*/
U32 stringLen = dStrlen(value);
// If it's longer than 256 bytes, it's certainly not a number.
//
// (This decision may come back to haunt you. Shame on you if it
// does.)
if (stringLen < 256)
{
fval = dAtof(value);
ival = dAtoi(value);
}
else
{
fval = 0.f;
ival = 0;
}
type = TypeInternalString;
// may as well pad to the next cache line
U32 newLen = ((stringLen + 1) + 15) & ~15;
if (sval == typeValueEmpty)
sval = (char*)dMalloc(newLen);
else if (newLen > bufferLen)
sval = (char*)dRealloc(sval, newLen);
bufferLen = newLen;
dStrcpy(sval, value, newLen);
}
else
Con::setData(type, dataPtr, 0, 1, &value, enumTable);
// Fire off the notification if we have one.
if (notify)
notify->trigger();
}
const char *Dictionary::getVariable(StringTableEntry name, bool *entValid) const char *Dictionary::getVariable(StringTableEntry name, bool *entValid)
{ {
Entry *ent = lookup(name); Entry *ent = lookup(name);
@ -508,150 +575,6 @@ const char *Dictionary::getVariable(StringTableEntry name, bool *entValid)
return ""; return "";
} }
void ConsoleValue::setStringValue(const char * value)
{
if (value == NULL) value = typeValueEmpty;
if (type <= ConsoleValue::TypeInternalString)
{
// Let's not remove empty-string-valued global vars from the dict.
// If we remove them, then they won't be exported, and sometimes
// it could be necessary to export such a global. There are very
// few empty-string global vars so there's no performance-related
// need to remove them from the dict.
/*
if(!value[0] && name[0] == '$')
{
gEvalState.globalVars.remove(this);
return;
}
*/
if (value == typeValueEmpty)
{
if (bufferLen > 0)
{
dFree(sval);
bufferLen = 0;
}
sval = typeValueEmpty;
fval = 0.f;
ival = 0;
type = TypeInternalString;
return;
}
U32 stringLen = dStrlen(value);
// If it's longer than 256 bytes, it's certainly not a number.
//
// (This decision may come back to haunt you. Shame on you if it
// does.)
if (stringLen < 256)
{
fval = dAtof(value);
ival = dAtoi(value);
}
else
{
fval = 0.f;
ival = 0;
}
// may as well pad to the next cache line
U32 newLen = ((stringLen + 1) + 15) & ~15;
if (bufferLen == 0)
sval = (char *)dMalloc(newLen);
else if (newLen > bufferLen)
sval = (char *)dRealloc(sval, newLen);
type = TypeInternalString;
bufferLen = newLen;
dStrcpy(sval, value, newLen);
}
else
Con::setData(type, dataPtr, 0, 1, &value, enumTable);
}
void ConsoleValue::setStackStringValue(const char *value)
{
if (value == NULL) value = typeValueEmpty;
if (type <= ConsoleValue::TypeInternalString)
{
// sval might still be temporarily present so we need to check and free it
if (bufferLen > 0)
{
dFree(sval);
bufferLen = 0;
}
if (value == typeValueEmpty)
{
sval = typeValueEmpty;
fval = 0.f;
ival = 0;
type = TypeInternalString;
return;
}
U32 stringLen = dStrlen(value);
if (stringLen < 256)
{
fval = dAtof(value);
ival = dAtoi(value);
}
else
{
fval = 0.f;
ival = 0;
}
type = TypeInternalStackString;
sval = (char*)value;
bufferLen = 0;
}
else
Con::setData(type, dataPtr, 0, 1, &value, enumTable);
}
void ConsoleValue::setStringStackPtrValue(StringStackPtr ptrValue)
{
if (type <= ConsoleValue::TypeInternalString)
{
const char *value = StringStackPtrRef(ptrValue).getPtr(&STR);
if (bufferLen > 0)
{
dFree(sval);
bufferLen = 0;
}
U32 stringLen = dStrlen(value);
if (stringLen < 256)
{
fval = dAtof(value);
ival = dAtoi(value);
}
else
{
fval = 0.f;
ival = 0;
}
type = TypeInternalStringStackPtr;
sval = (char*)(value - STR.mBuffer);
bufferLen = 0;
}
else
{
const char *value = StringStackPtrRef(ptrValue).getPtr(&STR);
Con::setData(type, dataPtr, 0, 1, &value, enumTable);
}
}
S32 Dictionary::getIntVariable(StringTableEntry name, bool *entValid) S32 Dictionary::getIntVariable(StringTableEntry name, bool *entValid)
{ {
Entry *ent = lookup(name); Entry *ent = lookup(name);
@ -708,19 +631,17 @@ Dictionary::Entry* Dictionary::addVariable(const char *name,
Entry *ent = add(StringTable->insert(name)); Entry *ent = add(StringTable->insert(name));
if (ent->value.type <= ConsoleValue::TypeInternalString && if (ent->type <= Entry::TypeInternalString && ent->sval != typeValueEmpty)
ent->value.bufferLen > 0) dFree(ent->sval);
dFree(ent->value.sval);
ent->value.type = type;
ent->value.dataPtr = dataPtr;
ent->mUsage = usage; ent->mUsage = usage;
ent->type = type;
ent->dataPtr = dataPtr;
// Fetch enum table, if any. // Fetch enum table, if any.
ConsoleBaseType* conType = ConsoleBaseType::getType(type); ConsoleBaseType* conType = ConsoleBaseType::getType(type);
AssertFatal(conType, "Dictionary::addVariable - invalid console type"); AssertFatal(conType, "Dictionary::addVariable - invalid console type");
ent->value.enumTable = conType->getEnumTable(); ent->enumTable = conType->getEnumTable();
return ent; return ent;
} }
@ -760,7 +681,7 @@ void Dictionary::validate()
"Dictionary::validate() - Dictionary not owner of own hashtable!"); "Dictionary::validate() - Dictionary not owner of own hashtable!");
} }
void ExprEvalState::pushFrame(StringTableEntry frameName, Namespace *ns) void ExprEvalState::pushFrame(StringTableEntry frameName, Namespace *ns, S32 registerCount)
{ {
#ifdef DEBUG_SPEW #ifdef DEBUG_SPEW
validate(); validate();
@ -789,6 +710,12 @@ void ExprEvalState::pushFrame(StringTableEntry frameName, Namespace *ns)
AssertFatal(!newFrame.getCount(), "ExprEvalState::pushFrame - Dictionary not empty!"); AssertFatal(!newFrame.getCount(), "ExprEvalState::pushFrame - Dictionary not empty!");
ConsoleValue* consoleValArray = new ConsoleValue[registerCount]();
localStack.push_back(ConsoleValueFrame(consoleValArray, false));
currentRegisterArray = &localStack.last();
AssertFatal(mStackDepth == localStack.size(), avar("Stack sizes do not match. mStackDepth = %d, localStack = %d", mStackDepth, localStack.size()));
#ifdef DEBUG_SPEW #ifdef DEBUG_SPEW
validate(); validate();
#endif #endif
@ -809,6 +736,15 @@ void ExprEvalState::popFrame()
stack[mStackDepth]->reset(); stack[mStackDepth]->reset();
currentVariable = NULL; currentVariable = NULL;
const ConsoleValueFrame& frame = localStack.last();
localStack.pop_back();
if (!frame.isReference)
delete[] frame.values;
currentRegisterArray = localStack.size() ? &localStack.last() : NULL;
AssertFatal(mStackDepth == localStack.size(), avar("Stack sizes do not match. mStackDepth = %d, localStack = %d", mStackDepth, localStack.size()));
#ifdef DEBUG_SPEW #ifdef DEBUG_SPEW
validate(); validate();
#endif #endif
@ -816,7 +752,7 @@ void ExprEvalState::popFrame()
void ExprEvalState::pushFrameRef(S32 stackIndex) void ExprEvalState::pushFrameRef(S32 stackIndex)
{ {
AssertFatal(stackIndex >= 0 && stackIndex < stack.size(), "You must be asking for a valid frame!"); AssertFatal(stackIndex >= 0 && stackIndex < mStackDepth, "You must be asking for a valid frame!");
#ifdef DEBUG_SPEW #ifdef DEBUG_SPEW
validate(); validate();
@ -840,11 +776,30 @@ void ExprEvalState::pushFrameRef(S32 stackIndex)
mStackDepth++; mStackDepth++;
currentVariable = NULL; currentVariable = NULL;
ConsoleValue* values = localStack[stackIndex].values;
localStack.push_back(ConsoleValueFrame(values, true));
currentRegisterArray = &localStack.last();
AssertFatal(mStackDepth == localStack.size(), avar("Stack sizes do not match. mStackDepth = %d, localStack = %d", mStackDepth, localStack.size()));
#ifdef DEBUG_SPEW #ifdef DEBUG_SPEW
validate(); validate();
#endif #endif
} }
void ExprEvalState::pushDebugFrame(S32 stackIndex)
{
pushFrameRef(stackIndex);
Dictionary& newFrame = *(stack[mStackDepth - 1]);
// debugger needs to know this info...
newFrame.scopeName = stack[stackIndex]->scopeName;
newFrame.scopeNamespace = stack[stackIndex]->scopeNamespace;
newFrame.code = stack[stackIndex]->code;
newFrame.ip = stack[stackIndex]->ip;
}
ExprEvalState::ExprEvalState() ExprEvalState::ExprEvalState()
{ {
VECTOR_SET_ASSOCIATION(stack); VECTOR_SET_ASSOCIATION(stack);
@ -1413,7 +1368,7 @@ void Namespace::markGroup(const char* name, const char* usage)
extern S32 executeBlock(StmtNode *block, ExprEvalState *state); extern S32 executeBlock(StmtNode *block, ExprEvalState *state);
ConsoleValueRef Namespace::Entry::execute(S32 argc, ConsoleValueRef *argv, ExprEvalState *state) ConsoleValue Namespace::Entry::execute(S32 argc, ConsoleValue *argv, ExprEvalState *state)
{ {
STR.clearFunctionOffset(); STR.clearFunctionOffset();
@ -1421,11 +1376,11 @@ ConsoleValueRef Namespace::Entry::execute(S32 argc, ConsoleValueRef *argv, ExprE
{ {
if (mFunctionOffset) if (mFunctionOffset)
{ {
return mCode->exec(mFunctionOffset, argv[0], mNamespace, argc, argv, false, mPackage); return std::move(mCode->exec(mFunctionOffset, argv[0].getString(), mNamespace, argc, argv, false, mPackage));
} }
else else
{ {
return ConsoleValueRef(); return std::move(ConsoleValue());
} }
} }
@ -1435,7 +1390,7 @@ ConsoleValueRef Namespace::Entry::execute(S32 argc, ConsoleValueRef *argv, ExprE
if (mToolOnly && !Con::isCurrentScriptToolScript()) if (mToolOnly && !Con::isCurrentScriptToolScript())
{ {
Con::errorf(ConsoleLogEntry::Script, "%s::%s - attempting to call tools only function from outside of tools", mNamespace->mName, mFunctionName); Con::errorf(ConsoleLogEntry::Script, "%s::%s - attempting to call tools only function from outside of tools", mNamespace->mName, mFunctionName);
return ConsoleValueRef(); return std::move(ConsoleValue());
} }
#endif #endif
@ -1443,25 +1398,33 @@ ConsoleValueRef Namespace::Entry::execute(S32 argc, ConsoleValueRef *argv, ExprE
{ {
Con::warnf(ConsoleLogEntry::Script, "%s::%s - wrong number of arguments.", mNamespace->mName, mFunctionName); Con::warnf(ConsoleLogEntry::Script, "%s::%s - wrong number of arguments.", mNamespace->mName, mFunctionName);
Con::warnf(ConsoleLogEntry::Script, "usage: %s", mUsage); Con::warnf(ConsoleLogEntry::Script, "usage: %s", mUsage);
return ConsoleValueRef(); return std::move(ConsoleValue());
} }
ConsoleValue result;
switch (mType) switch (mType)
{ {
case StringCallbackType: case StringCallbackType:
return ConsoleValueRef::fromValue(CSTK.pushStackString(cb.mStringCallbackFunc(state->thisObject, argc, argv))); {
const char* str = cb.mStringCallbackFunc(state->thisObject, argc, argv);
result.setString(str);
break;
}
case IntCallbackType: case IntCallbackType:
return ConsoleValueRef::fromValue(CSTK.pushUINT((U32)cb.mIntCallbackFunc(state->thisObject, argc, argv))); result.setInt(cb.mIntCallbackFunc(state->thisObject, argc, argv));
break;
case FloatCallbackType: case FloatCallbackType:
return ConsoleValueRef::fromValue(CSTK.pushFLT((U32)cb.mFloatCallbackFunc(state->thisObject, argc, argv))); result.setFloat(cb.mFloatCallbackFunc(state->thisObject, argc, argv));
break;
case VoidCallbackType: case VoidCallbackType:
cb.mVoidCallbackFunc(state->thisObject, argc, argv); cb.mVoidCallbackFunc(state->thisObject, argc, argv);
return ConsoleValueRef(); break;
case BoolCallbackType: case BoolCallbackType:
return ConsoleValueRef::fromValue(CSTK.pushUINT((U32)cb.mBoolCallbackFunc(state->thisObject, argc, argv))); result.setBool(cb.mBoolCallbackFunc(state->thisObject, argc, argv));
break;
} }
return ConsoleValueRef(); return std::move(result);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------

View file

@ -150,7 +150,7 @@ public:
void clear(); void clear();
/// ///
ConsoleValueRef execute(S32 argc, ConsoleValueRef* argv, ExprEvalState* state); ConsoleValue execute(S32 argc, ConsoleValue* argv, ExprEvalState* state);
/// Return a one-line documentation text string for the function. /// Return a one-line documentation text string for the function.
String getBriefDescription(String* outRemainingDocText = NULL) const; String getBriefDescription(String* outRemainingDocText = NULL) const;
@ -274,17 +274,24 @@ public:
typedef VectorPtr<Namespace::Entry *>::iterator NamespaceEntryListIterator; typedef VectorPtr<Namespace::Entry *>::iterator NamespaceEntryListIterator;
class Dictionary class Dictionary
{ {
public: public:
struct Entry struct Entry
{ {
friend class Dictionary;
enum
{
TypeInternalInt = -3,
TypeInternalFloat = -2,
TypeInternalString = -1,
};
StringTableEntry name; StringTableEntry name;
ConsoleValue value;
Entry *nextEntry; Entry *nextEntry;
S32 type;
typedef Signal<void()> NotifySignal; typedef Signal<void()> NotifySignal;
@ -298,16 +305,56 @@ public:
/// Whether this is a constant that cannot be assigned to. /// Whether this is a constant that cannot be assigned to.
bool mIsConstant; bool mIsConstant;
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
public: public:
Entry() { Entry() {
name = NULL; name = NULL;
type = TypeInternalString;
notify = NULL; notify = NULL;
nextEntry = NULL; nextEntry = NULL;
mUsage = NULL; mUsage = NULL;
mIsConstant = false; mIsConstant = false;
mNext = NULL; mNext = NULL;
value.init();
ival = 0;
fval = 0;
sval = typeValueEmpty;
bufferLen = 0;
} }
Entry(StringTableEntry name); Entry(StringTableEntry name);
@ -315,26 +362,34 @@ public:
Entry *mNext; Entry *mNext;
void reset() { void reset();
name = NULL;
value.cleanup();
if (notify)
delete notify;
}
inline U32 getIntValue() inline U32 getIntValue()
{ {
return value.getIntValue(); if (type <= TypeInternalString)
return ival;
else
return dAtoi(Con::getData(type, dataPtr, 0, enumTable));
} }
inline F32 getFloatValue() inline F32 getFloatValue()
{ {
return value.getFloatValue(); if (type <= TypeInternalString)
return fval;
else
return dAtof(Con::getData(type, dataPtr, 0, enumTable));
} }
inline const char *getStringValue() inline const char *getStringValue()
{ {
return value.getStringValue(); 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);
} }
void setIntValue(U32 val) void setIntValue(U32 val)
@ -345,7 +400,22 @@ public:
return; return;
} }
value.setIntValue(val); 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);
}
// Fire off the notification if we have one. // Fire off the notification if we have one.
if (notify) if (notify)
@ -360,44 +430,29 @@ public:
return; return;
} }
value.setFloatValue(val); if (type <= TypeInternalString)
// Fire off the notification if we have one.
if (notify)
notify->trigger();
}
void setStringStackPtrValue(StringStackPtr newValue)
{
if (mIsConstant)
{ {
Con::errorf("Cannot assign value to constant '%s'.", name); fval = val;
return; 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);
} }
value.setStringStackPtrValue(newValue);
// Fire off the notification if we have one. // Fire off the notification if we have one.
if (notify) if (notify)
notify->trigger(); notify->trigger();
} }
void setStringValue(const char *newValue) void setStringValue(const char* value);
{
if (mIsConstant)
{
Con::errorf("Cannot assign value to constant '%s'.", name);
return;
}
value.setStringValue(newValue);
// Fire off the notification if we have one.
if (notify)
notify->trigger();
}
}; };
struct HashTableData struct HashTableData
@ -471,6 +526,21 @@ public:
void validate(); void validate();
}; };
struct ConsoleValueFrame
{
ConsoleValue* values;
bool isReference;
ConsoleValueFrame() : values(NULL), isReference(false)
{}
ConsoleValueFrame(ConsoleValue* vals, bool isRef)
{
values = vals;
isReference = isRef;
}
};
class ExprEvalState class ExprEvalState
{ {
public: public:
@ -499,6 +569,11 @@ public:
/// an interior pointer that will become invalid when the object changes address. /// an interior pointer that will become invalid when the object changes address.
Vector< Dictionary* > stack; Vector< Dictionary* > stack;
S32 getTopOfStack() { return (S32)mStackDepth; }
Vector< ConsoleValueFrame > localStack;
ConsoleValueFrame* currentRegisterArray; // contains array at to top of localStack
/// ///
Dictionary globalVars; Dictionary globalVars;
@ -511,16 +586,56 @@ public:
void setIntVariable(S32 val); void setIntVariable(S32 val);
void setFloatVariable(F64 val); void setFloatVariable(F64 val);
void setStringVariable(const char *str); void setStringVariable(const char *str);
void setStringStackPtrVariable(StringStackPtr str);
void setCopyVariable();
void pushFrame(StringTableEntry frameName, Namespace *ns); 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);
}
TORQUE_FORCEINLINE void moveConsoleValue(S32 reg, ConsoleValue val)
{
currentRegisterArray->values[reg] = std::move(val);
}
void pushFrame(StringTableEntry frameName, Namespace *ns, S32 regCount);
void popFrame(); void popFrame();
/// Puts a reference to an existing stack frame /// Puts a reference to an existing stack frame
/// on the top of the stack. /// on the top of the stack.
void pushFrameRef(S32 stackIndex); void pushFrameRef(S32 stackIndex);
void pushDebugFrame(S32 stackIndex);
U32 getStackDepth() const U32 getStackDepth() const
{ {
return mStackDepth; return mStackDepth;
@ -531,6 +646,11 @@ public:
return *(stack[mStackDepth - 1]); return *(stack[mStackDepth - 1]);
} }
Dictionary& getFrameAt(S32 depth)
{
return *(stack[depth]);
}
/// @} /// @}
/// Run integrity checks for debugging. /// Run integrity checks for debugging.

View file

@ -79,18 +79,18 @@ void ConsoleLogger::initPersistFields()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool ConsoleLogger::processArguments( S32 argc, ConsoleValueRef *argv ) bool ConsoleLogger::processArguments( S32 argc, ConsoleValue *argv )
{ {
if( argc == 0 ) if( argc == 0 )
return false; return false;
bool append = false; bool append = false;
if( argc == 2 ) if (argc == 2)
append = dAtob( argv[1] ); append = argv[1].getBool();
mAppend = append; mAppend = append;
mFilename = StringTable->insert( argv[0] ); mFilename = StringTable->insert( argv[0].getString() );
if( init() ) if( init() )
{ {

View file

@ -81,7 +81,7 @@ class ConsoleLogger : public SimObject
/// // Example script constructor usage. /// // Example script constructor usage.
/// %obj = new ConsoleLogger( objName, logFileName, [append = false] ); /// %obj = new ConsoleLogger( objName, logFileName, [append = false] );
/// @endcode /// @endcode
bool processArguments( S32 argc, ConsoleValueRef *argv ); bool processArguments( S32 argc, ConsoleValue *argv );
/// Default constructor, make sure to initalize /// Default constructor, make sure to initalize
ConsoleLogger(); ConsoleLogger();

View file

@ -0,0 +1,109 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2013 GarageGames, LLC
// Copyright (c) 2021 TGEMIT Authors & Contributors
//
// 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 _CONSOLE_CONSOLE_VALUE_STACK_H_
#define _CONSOLE_CONSOLE_VALUE_STACK_H_
template<S32 StackSize>
class ConsoleValueStack
{
constexpr static S32 allocatorSize = sizeof(ConsoleValue) * StackSize;
struct Frame
{
ConsoleValue* values;
S32 count;
S32 internalCounter;
};
Vector<Frame> stack;
char* memory;
S32 sp;
TORQUE_FORCEINLINE Frame alloc(S32 count)
{
AssertFatal(sp + count * sizeof(ConsoleValue) < allocatorSize, "ConsoleValueStack overflow");
ConsoleValue* ret = reinterpret_cast<ConsoleValue*>(memory + sp);
sp += count * sizeof(ConsoleValue);
return { ret, count, 1 };
}
TORQUE_FORCEINLINE void deAlloc(S32 count)
{
sp -= count * sizeof(ConsoleValue);
AssertFatal(sp >= 0, "Popped ConsoleValueStack too far, underflow");
}
public:
ConsoleValueStack()
{
memory = (char*)dMalloc(allocatorSize);
for (S32 i = 0; i < allocatorSize; i += sizeof(ConsoleValue))
{
constructInPlace<ConsoleValue>(reinterpret_cast<ConsoleValue*>(memory + i));
}
sp = 0;
}
~ConsoleValueStack()
{
dFree(memory);
}
TORQUE_FORCEINLINE void pushFrame(S32 count)
{
AssertISV(count >= 0, "Must be >= 0 when pushing stack frame");
// +1 for function name in argv[0]
const Frame& frame = alloc(count + 1);
stack.push_back(frame);
}
TORQUE_FORCEINLINE void popFrame()
{
AssertISV(stack.size() > 0, "Stack Underflow");
deAlloc(stack.last().count);
stack.pop_back();
}
TORQUE_FORCEINLINE void push(ConsoleValue&& val)
{
Frame& frame = stack.last();
frame.values[frame.internalCounter++] = std::move(val);
}
TORQUE_FORCEINLINE void argvc(StringTableEntry fn, S32& argc, ConsoleValue** argv)
{
Frame& frame = stack.last();
argc = frame.count;
// First param is always function name
frame.values[0].setStringTableEntry(fn);
*argv = frame.values;
}
};
#endif

View file

@ -148,55 +148,45 @@ inline const char* EngineMarshallData( U32 value )
/// Marshal data from native into client form stored directly in /// Marshal data from native into client form stored directly in
/// client function invocation vector. /// client function invocation vector.
template< typename T > template< typename T >
inline void EngineMarshallData( const T& arg, S32& argc, ConsoleValueRef *argv ) inline void EngineMarshallData( const T& arg, S32& argc, ConsoleValue *argv )
{ {
argv[ argc ] = castConsoleTypeToString( arg ); const char* str = castConsoleTypeToString(arg);;
argc ++; argv[ argc++ ].setString(str);
} }
inline void EngineMarshallData( bool arg, S32& argc, ConsoleValueRef *argv ) inline void EngineMarshallData( bool arg, S32& argc, ConsoleValue *argv )
{ {
if( arg ) argv[ argc++ ].setBool(arg);
argv[ argc ] = 1;
else
argv[ argc ] = 0;
argc ++;
} }
inline void EngineMarshallData( S32 arg, S32& argc, ConsoleValueRef *argv ) inline void EngineMarshallData( S32 arg, S32& argc, ConsoleValue *argv )
{ {
argv[ argc ] = arg; argv[ argc++ ].setInt(arg);
argc ++;
} }
inline void EngineMarshallData( U32 arg, S32& argc, ConsoleValueRef *argv ) inline void EngineMarshallData( U32 arg, S32& argc, ConsoleValue *argv )
{ {
EngineMarshallData( S32( arg ), argc, argv ); EngineMarshallData( S32( arg ), argc, argv );
} }
inline void EngineMarshallData( F32 arg, S32& argc, ConsoleValueRef *argv ) inline void EngineMarshallData( F32 arg, S32& argc, ConsoleValue *argv )
{ {
argv[ argc ] = arg; argv[ argc++ ].setFloat(arg);
argc ++;
} }
inline void EngineMarshallData( const char* arg, S32& argc, ConsoleValueRef *argv ) inline void EngineMarshallData( const char* arg, S32& argc, ConsoleValue *argv )
{ {
argv[ argc ] = arg; argv[ argc++ ].setString(arg);
argc ++;
} }
inline void EngineMarshallData( char* arg, S32& argc, ConsoleValueRef *argv ) inline void EngineMarshallData( char* arg, S32& argc, ConsoleValue *argv )
{ {
argv[ argc ] = arg; argv[ argc++ ].setString(arg);
argc ++;
} }
template< typename T > template< typename T >
inline void EngineMarshallData( T* object, S32& argc, ConsoleValueRef *argv ) inline void EngineMarshallData( T* object, S32& argc, ConsoleValue *argv )
{ {
argv[ argc ] = object ? object->getId() : 0; argv[ argc++ ].setInt(object ? object->getId() : 0);
argc ++;
} }
template< typename T > template< typename T >
inline void EngineMarshallData( const T* object, S32& argc, ConsoleValueRef *argv ) inline void EngineMarshallData( const T* object, S32& argc, ConsoleValue *argv )
{ {
argv[ argc ] = object ? object->getId() : 0; argv[ argc++ ].setInt(object ? object->getId() : 0);
argc ++;
} }
/// Unmarshal data from client form to engine form. /// Unmarshal data from client form to engine form.
@ -216,9 +206,9 @@ struct EngineUnmarshallData
template<> template<>
struct EngineUnmarshallData< S32 > struct EngineUnmarshallData< S32 >
{ {
S32 operator()( ConsoleValueRef &ref ) const S32 operator()( ConsoleValue &ref ) const
{ {
return (S32)ref; return (S32)ref.getInt();
} }
S32 operator()( const char* str ) const S32 operator()( const char* str ) const
@ -229,9 +219,9 @@ struct EngineUnmarshallData< S32 >
template<> template<>
struct EngineUnmarshallData< U32 > struct EngineUnmarshallData< U32 >
{ {
U32 operator()( ConsoleValueRef &ref ) const U32 operator()( ConsoleValue &ref ) const
{ {
return (U32)((S32)ref); return (U32)ref.getInt();
} }
U32 operator()( const char* str ) const U32 operator()( const char* str ) const
@ -242,9 +232,9 @@ struct EngineUnmarshallData< U32 >
template<> template<>
struct EngineUnmarshallData< F32 > struct EngineUnmarshallData< F32 >
{ {
F32 operator()( ConsoleValueRef &ref ) const F32 operator()( ConsoleValue &ref ) const
{ {
return (F32)ref; return (F32)ref.getFloat();
} }
F32 operator()( const char* str ) const F32 operator()( const char* str ) const
@ -255,9 +245,9 @@ struct EngineUnmarshallData< F32 >
template<> template<>
struct EngineUnmarshallData< U8 > struct EngineUnmarshallData< U8 >
{ {
U8 operator()( ConsoleValueRef &ref ) const U8 operator()( ConsoleValue &ref ) const
{ {
return (U8)((S32)ref); return (U8)((S32)ref.getInt());
} }
U8 operator()( const char* str ) const U8 operator()( const char* str ) const
@ -268,9 +258,9 @@ struct EngineUnmarshallData< U8 >
template<> template<>
struct EngineUnmarshallData< const char* > struct EngineUnmarshallData< const char* >
{ {
const char* operator()( ConsoleValueRef &ref ) const const char* operator()( ConsoleValue &ref ) const
{ {
return ref.getStringValue(); return ref.getString();
} }
const char* operator()( const char* str ) const const char* operator()( const char* str ) const
@ -281,9 +271,9 @@ struct EngineUnmarshallData< const char* >
template< typename T > template< typename T >
struct EngineUnmarshallData< T* > struct EngineUnmarshallData< T* >
{ {
T* operator()( ConsoleValueRef &ref ) const T* operator()( ConsoleValue &ref ) const
{ {
return dynamic_cast< T* >( Sim::findObject( ref.getStringValue() ) ); return dynamic_cast< T* >( Sim::findObject( ref ) );
} }
T* operator()( const char* str ) const T* operator()( const char* str ) const
@ -294,17 +284,17 @@ struct EngineUnmarshallData< T* >
template<> template<>
struct EngineUnmarshallData< void > struct EngineUnmarshallData< void >
{ {
void operator()( ConsoleValueRef& ) const {} void operator()( ConsoleValue& ) const {}
void operator()( const char* ) const {} void operator()( const char* ) const {}
}; };
template<> template<>
struct EngineUnmarshallData< ConsoleValueRef > struct EngineUnmarshallData< ConsoleValue >
{ {
ConsoleValueRef operator()( ConsoleValueRef ref ) const ConsoleValue operator()( ConsoleValue ref ) const
{ {
return ref; return std::move(ref);
} }
}; };
@ -548,7 +538,7 @@ namespace engineAPI{
static const S32 NUM_ARGS = sizeof...(ArgTs) + startArgc; static const S32 NUM_ARGS = sizeof...(ArgTs) + startArgc;
template<size_t index, size_t method_offset = 0, typename ...RealArgTs> template<size_t index, size_t method_offset = 0, typename ...RealArgTs>
static IthArgType<index> getRealArgValue(S32 argc, ConsoleValueRef *argv, const _EngineFunctionDefaultArguments< void(RealArgTs...) >& defaultArgs) static IthArgType<index> getRealArgValue(S32 argc, ConsoleValue *argv, const _EngineFunctionDefaultArguments< void(RealArgTs...) >& defaultArgs)
{ {
if((startArgc + index) < argc) if((startArgc + index) < argc)
{ {
@ -559,12 +549,12 @@ namespace engineAPI{
} }
template<size_t ...I> template<size_t ...I>
static R dispatchHelper(S32 argc, ConsoleValueRef *argv, FunctionType fn, const _EngineFunctionDefaultArguments< void(ArgTs...) >& defaultArgs, Seq<I...>){ static R dispatchHelper(S32 argc, ConsoleValue *argv, FunctionType fn, const _EngineFunctionDefaultArguments< void(ArgTs...) >& defaultArgs, Seq<I...>){
return fn(SelfType::getRealArgValue<I>(argc, argv, defaultArgs) ...); return fn(SelfType::getRealArgValue<I>(argc, argv, defaultArgs) ...);
} }
template<typename Frame, size_t ...I> template<typename Frame, size_t ...I>
static R dispatchHelper(S32 argc, ConsoleValueRef *argv, MethodType<Frame> fn, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, ArgTs...) >& defaultArgs, Seq<I...>){ static R dispatchHelper(S32 argc, ConsoleValue *argv, MethodType<Frame> fn, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, ArgTs...) >& defaultArgs, Seq<I...>){
return (frame->*fn)(SelfType::getRealArgValue<I,1>(argc, argv, defaultArgs) ...); return (frame->*fn)(SelfType::getRealArgValue<I,1>(argc, argv, defaultArgs) ...);
} }
@ -579,9 +569,9 @@ namespace engineAPI{
} }
}; };
template<> struct MarshallHelpers<ConsoleValueRef> { template<> struct MarshallHelpers<ConsoleValue> {
template<typename ...ArgTs> static void marshallEach(S32 &argc, ConsoleValueRef *argv, const ArgTs& ...args){} template<typename ...ArgTs> static void marshallEach(S32 &argc, ConsoleValue *argv, const ArgTs& ...args){}
template<typename H, typename ...Tail> static void marshallEach(S32 &argc, ConsoleValueRef *argv, const H& head, const Tail& ...tail){ template<typename H, typename ...Tail> static void marshallEach(S32 &argc, ConsoleValue *argv, const H& head, const Tail& ...tail){
EngineMarshallData(head, argc, argv); EngineMarshallData(head, argc, argv);
marshallEach(argc, argv, tail...); marshallEach(argc, argv, tail...);
} }
@ -604,12 +594,12 @@ public:
template<typename Frame> using MethodType = typename Helper::template MethodType<Frame>; template<typename Frame> using MethodType = typename Helper::template MethodType<Frame>;
static const S32 NUM_ARGS = Helper::NUM_ARGS; static const S32 NUM_ARGS = Helper::NUM_ARGS;
static ReturnType thunk( S32 argc, ConsoleValueRef *argv, FunctionType fn, const _EngineFunctionDefaultArguments< void(ArgTs...) >& defaultArgs) static ReturnType thunk( S32 argc, ConsoleValue *argv, FunctionType fn, const _EngineFunctionDefaultArguments< void(ArgTs...) >& defaultArgs)
{ {
return _EngineConsoleThunkReturnValue( Helper::dispatchHelper(argc, argv, fn, defaultArgs, SeqType())); return _EngineConsoleThunkReturnValue( Helper::dispatchHelper(argc, argv, fn, defaultArgs, SeqType()));
} }
template< typename Frame > template< typename Frame >
static ReturnType thunk( S32 argc, ConsoleValueRef *argv, MethodType<Frame> fn, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, ArgTs...) >& defaultArgs) static ReturnType thunk( S32 argc, ConsoleValue *argv, MethodType<Frame> fn, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, ArgTs...) >& defaultArgs)
{ {
return _EngineConsoleThunkReturnValue( Helper::dispatchHelper(argc, argv, fn, frame, defaultArgs, SeqType())); return _EngineConsoleThunkReturnValue( Helper::dispatchHelper(argc, argv, fn, frame, defaultArgs, SeqType()));
} }
@ -627,12 +617,12 @@ public:
template<typename Frame> using MethodType = typename Helper::template MethodType<Frame>; template<typename Frame> using MethodType = typename Helper::template MethodType<Frame>;
static const S32 NUM_ARGS = Helper::NUM_ARGS; static const S32 NUM_ARGS = Helper::NUM_ARGS;
static void thunk( S32 argc, ConsoleValueRef *argv, FunctionType fn, const _EngineFunctionDefaultArguments< void(ArgTs...) >& defaultArgs) static void thunk( S32 argc, ConsoleValue *argv, FunctionType fn, const _EngineFunctionDefaultArguments< void(ArgTs...) >& defaultArgs)
{ {
Helper::dispatchHelper(argc, argv, fn, defaultArgs, SeqType()); Helper::dispatchHelper(argc, argv, fn, defaultArgs, SeqType());
} }
template< typename Frame > template< typename Frame >
static void thunk( S32 argc, ConsoleValueRef *argv, MethodType<Frame> fn, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, ArgTs...) >& defaultArgs) static void thunk( S32 argc, ConsoleValue *argv, MethodType<Frame> fn, Frame* frame, const _EngineFunctionDefaultArguments< void( typename Frame::ObjectType*, ArgTs...) >& defaultArgs)
{ {
Helper::dispatchHelper(argc, argv, fn, frame, defaultArgs, SeqType()); Helper::dispatchHelper(argc, argv, fn, frame, defaultArgs, SeqType());
} }
@ -705,7 +695,7 @@ public:
( void* ) &fn ## name, \ ( void* ) &fn ## name, \
0 \ 0 \
); \ ); \
static _EngineConsoleThunkType< returnType >::ReturnType _ ## name ## caster( SimObject*, S32 argc, ConsoleValueRef *argv ) \ static _EngineConsoleThunkType< returnType >::ReturnType _ ## name ## caster( SimObject*, S32 argc, ConsoleValue *argv ) \
{ \ { \
return _EngineConsoleThunkType< returnType >::ReturnType( _EngineConsoleThunk< 1, returnType args >::thunk( \ return _EngineConsoleThunkType< returnType >::ReturnType( _EngineConsoleThunk< 1, returnType args >::thunk( \
argc, argv, &_fn ## name ## impl, _fn ## name ## DefaultArgs \ argc, argv, &_fn ## name ## impl, _fn ## name ## DefaultArgs \
@ -785,7 +775,7 @@ public:
( void* ) &fn ## className ## _ ## name, \ ( void* ) &fn ## className ## _ ## name, \
0 \ 0 \
); \ ); \
static _EngineConsoleThunkType< returnType >::ReturnType _ ## className ## name ## caster( SimObject* object, S32 argc, ConsoleValueRef *argv ) \ static _EngineConsoleThunkType< returnType >::ReturnType _ ## className ## name ## caster( SimObject* object, S32 argc, ConsoleValue *argv ) \
{ \ { \
_ ## className ## name ## frame frame; \ _ ## className ## name ## frame frame; \
frame.object = static_cast< className* >( object ); \ frame.object = static_cast< className* >( object ); \
@ -842,7 +832,7 @@ public:
( void* ) &fn ## className ## _ ## name, \ ( void* ) &fn ## className ## _ ## name, \
0 \ 0 \
); \ ); \
static _EngineConsoleThunkType< returnType >::ReturnType _ ## className ## name ## caster( SimObject*, S32 argc, ConsoleValueRef *argv )\ static _EngineConsoleThunkType< returnType >::ReturnType _ ## className ## name ## caster( SimObject*, S32 argc, ConsoleValue *argv )\
{ \ { \
return _EngineConsoleThunkType< returnType >::ReturnType( _EngineConsoleThunk< 1, returnType args >::thunk( \ return _EngineConsoleThunkType< returnType >::ReturnType( _EngineConsoleThunk< 1, returnType args >::thunk( \
argc, argv, &_fn ## className ## name ## impl, _fn ## className ## name ## DefaultArgs \ argc, argv, &_fn ## className ## name ## impl, _fn ## className ## name ## DefaultArgs \
@ -859,12 +849,12 @@ public:
static inline returnType _fn ## className ## name ## impl args static inline returnType _fn ## className ## name ## impl args
# define DefineEngineStringlyVariadicFunction(name,returnType,minArgs,maxArgs,usage) \ # define DefineEngineStringlyVariadicFunction(name,returnType,minArgs,maxArgs,usage) \
static inline returnType _fn ## name ## impl (SimObject *, S32 argc, ConsoleValueRef *argv); \ static inline returnType _fn ## name ## impl (SimObject *, S32 argc, ConsoleValue *argv); \
TORQUE_API EngineTypeTraits< returnType >::ReturnValueType fn ## name \ TORQUE_API EngineTypeTraits< returnType >::ReturnValueType fn ## name \
(Vector<const char*>* vec) \ (Vector<const char*>* vec) \
{ \ { \
_CHECK_ENGINE_INITIALIZED( name, returnType ); \ _CHECK_ENGINE_INITIALIZED( name, returnType ); \
StringStackConsoleWrapper args(vec->size(), vec->address()); \ StringArrayToConsoleValueWrapper args(vec->size(), vec->address()); \
return EngineTypeTraits< returnType >::ReturnValue( \ return EngineTypeTraits< returnType >::ReturnValue( \
_fn ## name ## impl(NULL, args.count(), args) \ _fn ## name ## impl(NULL, args.count(), args) \
); \ ); \
@ -882,20 +872,20 @@ public:
0 \ 0 \
); \ ); \
ConsoleConstructor cc_##name##_obj(NULL,#name,_fn ## name ## impl,usage,minArgs,maxArgs); \ ConsoleConstructor cc_##name##_obj(NULL,#name,_fn ## name ## impl,usage,minArgs,maxArgs); \
returnType _fn ## name ## impl(SimObject *, S32 argc, ConsoleValueRef *argv) returnType _fn ## name ## impl(SimObject *, S32 argc, ConsoleValue *argv)
# define DefineEngineStringlyVariadicMethod(className, name,returnType,minArgs,maxArgs,usage) \ # define DefineEngineStringlyVariadicMethod(className, name,returnType,minArgs,maxArgs,usage) \
struct _ ## className ## name ## frame \ struct _ ## className ## name ## frame \
{ \ { \
typedef className ObjectType; \ typedef className ObjectType; \
className* object; \ className* object; \
inline returnType _exec (S32 argc, ConsoleValueRef* argv) const; \ inline returnType _exec (S32 argc, ConsoleValue* argv) const; \
}; \ }; \
TORQUE_API EngineTypeTraits< returnType >::ReturnValueType fn ## className ## _ ## name \ TORQUE_API EngineTypeTraits< returnType >::ReturnValueType fn ## className ## _ ## name \
(className* object, Vector<const char*>* vec) \ (className* object, Vector<const char*>* vec) \
{ \ { \
_CHECK_ENGINE_INITIALIZED( name, returnType ); \ _CHECK_ENGINE_INITIALIZED( name, returnType ); \
StringStackConsoleWrapper args(vec->size(), vec->address()); \ StringArrayToConsoleValueWrapper args(vec->size(), vec->address()); \
_ ## className ## name ## frame frame {}; \ _ ## className ## name ## frame frame {}; \
frame.object = static_cast< className* >( object ); \ frame.object = static_cast< className* >( object ); \
return EngineTypeTraits< returnType >::ReturnValue( \ return EngineTypeTraits< returnType >::ReturnValue( \
@ -915,14 +905,14 @@ public:
( void* ) &fn ## className ## _ ## name, \ ( void* ) &fn ## className ## _ ## name, \
0 \ 0 \
); \ ); \
returnType cm_##className##_##name##_caster(SimObject* object, S32 argc, ConsoleValueRef* argv) { \ returnType cm_##className##_##name##_caster(SimObject* object, S32 argc, ConsoleValue* argv) { \
AssertFatal( dynamic_cast<className*>( object ), "Object passed to " #name " is not a " #className "!" ); \ AssertFatal( dynamic_cast<className*>( object ), "Object passed to " #name " is not a " #className "!" ); \
_ ## className ## name ## frame frame {}; \ _ ## className ## name ## frame frame {}; \
frame.object = static_cast< className* >( object ); \ frame.object = static_cast< className* >( object ); \
conmethod_return_##returnType ) frame._exec(argc,argv); \ conmethod_return_##returnType ) frame._exec(argc,argv); \
}; \ }; \
ConsoleConstructor cc_##className##_##name##_obj(#className,#name,cm_##className##_##name##_caster,usage,minArgs,maxArgs); \ ConsoleConstructor cc_##className##_##name##_obj(#className,#name,cm_##className##_##name##_caster,usage,minArgs,maxArgs); \
inline returnType _ ## className ## name ## frame::_exec(S32 argc, ConsoleValueRef *argv) const inline returnType _ ## className ## name ## frame::_exec(S32 argc, ConsoleValue *argv) const
@ -1167,10 +1157,10 @@ public:
S32 mInitialArgc; S32 mInitialArgc;
S32 mArgc; S32 mArgc;
StringTableEntry mCallbackName; StringTableEntry mCallbackName;
ConsoleValueRef mArgv[ MAX_ARGUMENTS + 2 ]; ConsoleValue mArgv[ MAX_ARGUMENTS + 2 ];
ConsoleValueRef _exec(); ConsoleValue _exec();
ConsoleValueRef _execLater(SimConsoleThreadExecEvent *evt); ConsoleValue _execLater(SimConsoleThreadExecEvent *evt);
_BaseEngineConsoleCallbackHelper(): mThis(NULL), mInitialArgc(0), mArgc(0), mCallbackName(StringTable->EmptyString()){;} _BaseEngineConsoleCallbackHelper(): mThis(NULL), mInitialArgc(0), mArgc(0), mCallbackName(StringTable->EmptyString()){;}
}; };
@ -1181,7 +1171,7 @@ public:
struct _EngineConsoleCallbackHelper : public _BaseEngineConsoleCallbackHelper struct _EngineConsoleCallbackHelper : public _BaseEngineConsoleCallbackHelper
{ {
private: private:
using Helper = engineAPI::detail::MarshallHelpers<ConsoleValueRef>; using Helper = engineAPI::detail::MarshallHelpers<ConsoleValue>;
public: public:
_EngineConsoleCallbackHelper( StringTableEntry callbackName, SimObject* pThis ) _EngineConsoleCallbackHelper( StringTableEntry callbackName, SimObject* pThis )
@ -1197,8 +1187,7 @@ public:
if (Con::isMainThread()) if (Con::isMainThread())
{ {
ConsoleStackFrameSaver sav; sav.save(); ConsoleStackFrameSaver sav; sav.save();
CSTK.reserveValues(mArgc + sizeof...(ArgTs), mArgv); mArgv[ 0 ].setStringTableEntry(mCallbackName);
mArgv[ 0 ].value->setStackStringValue(mCallbackName);
Helper::marshallEach(mArgc, mArgv, args...); Helper::marshallEach(mArgc, mArgv, args...);
@ -1209,7 +1198,7 @@ public:
SimConsoleThreadExecCallback cb; SimConsoleThreadExecCallback cb;
SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc + sizeof...(ArgTs), NULL, false, &cb); SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc + sizeof...(ArgTs), NULL, false, &cb);
evt->populateArgs(mArgv); evt->populateArgs(mArgv);
mArgv[ 0 ].value->setStackStringValue(mCallbackName); mArgv[ 0 ].setStringTableEntry(mCallbackName);
Helper::marshallEach(mArgc, mArgv, args...); Helper::marshallEach(mArgc, mArgv, args...);
@ -1226,7 +1215,7 @@ public:
template<typename P1> struct _EngineConsoleExecCallbackHelper : public _BaseEngineConsoleCallbackHelper template<typename P1> struct _EngineConsoleExecCallbackHelper : public _BaseEngineConsoleCallbackHelper
{ {
private: private:
using Helper = engineAPI::detail::MarshallHelpers<ConsoleValueRef>; using Helper = engineAPI::detail::MarshallHelpers<ConsoleValue>;
public: public:
_EngineConsoleExecCallbackHelper( SimObject* pThis ) _EngineConsoleExecCallbackHelper( SimObject* pThis )
@ -1243,8 +1232,7 @@ public:
if (Con::isMainThread()) if (Con::isMainThread())
{ {
ConsoleStackFrameSaver sav; sav.save(); ConsoleStackFrameSaver sav; sav.save();
CSTK.reserveValues(mArgc+sizeof...(ArgTs), mArgv); mArgv[ 0 ].setString(simCB);
mArgv[ 0 ].value->setStackStringValue(simCB);
Helper::marshallEach(mArgc, mArgv, args...); Helper::marshallEach(mArgc, mArgv, args...);
@ -1255,7 +1243,7 @@ public:
SimConsoleThreadExecCallback cb; SimConsoleThreadExecCallback cb;
SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+sizeof...(ArgTs), NULL, true, &cb); SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+sizeof...(ArgTs), NULL, true, &cb);
evt->populateArgs(mArgv); evt->populateArgs(mArgv);
mArgv[ 0 ].value->setStackStringValue(simCB); mArgv[ 0 ].setString(simCB);
Helper::marshallEach(mArgc, mArgv, args...); Helper::marshallEach(mArgc, mArgv, args...);
@ -1270,7 +1258,7 @@ public:
template<> struct _EngineConsoleExecCallbackHelper<const char*> : public _BaseEngineConsoleCallbackHelper template<> struct _EngineConsoleExecCallbackHelper<const char*> : public _BaseEngineConsoleCallbackHelper
{ {
private: private:
using Helper = engineAPI::detail::MarshallHelpers<ConsoleValueRef>; using Helper = engineAPI::detail::MarshallHelpers<ConsoleValue>;
public: public:
_EngineConsoleExecCallbackHelper( const char *callbackName ) _EngineConsoleExecCallbackHelper( const char *callbackName )
{ {
@ -1285,10 +1273,9 @@ public:
if (Con::isMainThread()) if (Con::isMainThread())
{ {
ConsoleStackFrameSaver sav; sav.save(); ConsoleStackFrameSaver sav; sav.save();
CSTK.reserveValues(mArgc+sizeof...(ArgTs), mArgv); mArgv[ 0 ].setStringTableEntry(mCallbackName);
mArgv[ 0 ].value->setStackStringValue(mCallbackName);
Helper::marshallEach(mArgc, mArgv, args...); Helper::marshallEach(mArgc, mArgv, args...);
return R( EngineUnmarshallData< R >()( _exec() ) ); return R( EngineUnmarshallData< R >()( _exec() ) );
} }
@ -1297,7 +1284,7 @@ public:
SimConsoleThreadExecCallback cb; SimConsoleThreadExecCallback cb;
SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+sizeof...(ArgTs), NULL, false, &cb); SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+sizeof...(ArgTs), NULL, false, &cb);
evt->populateArgs(mArgv); evt->populateArgs(mArgv);
mArgv[ 0 ].value->setStackStringValue(mCallbackName); mArgv[ 0 ].setStringTableEntry(mCallbackName);
Helper::marshallEach(mArgc, mArgv, args...); Helper::marshallEach(mArgc, mArgv, args...);

View file

@ -114,7 +114,7 @@ static void dumpVariable( Stream& stream,
{ {
// Skip variables defined in script. // Skip variables defined in script.
if( entry->value.type < 0 ) if( entry->type <= Dictionary::Entry::TypeInternalString )
return; return;
// Skip internals... don't export them. // Skip internals... don't export them.
@ -149,7 +149,7 @@ static void dumpVariable( Stream& stream,
// Skip variables for which we can't decipher their type. // Skip variables for which we can't decipher their type.
ConsoleBaseType* type = ConsoleBaseType::getType( entry->value.type ); ConsoleBaseType* type = ConsoleBaseType::getType( entry->type );
if( !type ) if( !type )
{ {
Con::errorf( "Can't find type for variable '%s'", entry->name ); Con::errorf( "Can't find type for variable '%s'", entry->name );

View file

@ -0,0 +1,104 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2013 GarageGames, LLC
// Copyright (c) 2021 TGEMIT Authors & Contributors
//
// 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.
//-----------------------------------------------------------------------------
#include "console/console.h"
#include "console/codeBlock.h"
static bool isLiteralNumber(ExprNode* node)
{
ExprNodeName name = node->getExprNodeNameEnum();
return name == NameFloatNode || name == NameIntNode;
}
static F64 getFloatValue(ExprNode* node)
{
if (node->getExprNodeNameEnum() == NameFloatNode)
return static_cast<FloatNode*>(node)->value;
return (F64)static_cast<IntNode*>(node)->value;
}
static S32 getIntValue(ExprNode* node)
{
if (node->getExprNodeNameEnum() == NameFloatNode)
return (S32)static_cast<FloatNode*>(node)->value;
return static_cast<IntNode*>(node)->value;
}
bool FloatBinaryExprNode::optimize()
{
// Perform constant folding
if (isLiteralNumber(right) && isLiteralNumber(left))
{
F64 rightValue = getFloatValue(right);
F64 leftValue = getFloatValue(left);
F64 result = 0.0;
switch (op)
{
case '+':
result = leftValue + rightValue;
break;
case '-':
result = leftValue - rightValue;
break;
case '*':
result = leftValue * rightValue;
break;
case '/':
if (rightValue != 0.0)
result = leftValue / rightValue;
break;
}
optimizedNode = FloatNode::alloc(dbgLineNumber, result);
return true;
}
return false;
}
bool IntBinaryExprNode::optimize()
{
if (op == '%' && left->getExprNodeNameEnum() == NameVarNode && isLiteralNumber(right))
{
// %a % intconst
S32 val = getIntValue(right);
switch (val)
{
case 2:
op = '&';
optimizedNode = IntNode::alloc(dbgLineNumber, 1);
return true;
case 4:
op = '&';
optimizedNode = IntNode::alloc(dbgLineNumber, 3);
return true;
case 8:
op = '&';
optimizedNode = IntNode::alloc(dbgLineNumber, 7);
return true;
}
}
return false;
}

View file

@ -125,15 +125,12 @@ namespace Sim
SimDataBlockGroup *getDataBlockGroup(); SimDataBlockGroup *getDataBlockGroup();
SimGroup* getRootGroup(); SimGroup* getRootGroup();
SimObject* findObject(ConsoleValueRef&);
SimObject* findObject(SimObjectId); SimObject* findObject(SimObjectId);
SimObject* findObject(const ConsoleValue&);
SimObject* findObject(ConsoleValue*);
SimObject* findObject(const char* name); SimObject* findObject(const char* name);
SimObject* findObject(const char* fileName, S32 declarationLine); SimObject* findObject(const char* fileName, S32 declarationLine);
template<class T> inline bool findObject(ConsoleValueRef &ref,T*&t)
{
t = dynamic_cast<T*>(findObject(ref));
return t != NULL;
}
template<class T> inline bool findObject(SimObjectId iD,T*&t) template<class T> inline bool findObject(SimObjectId iD,T*&t)
{ {
t = dynamic_cast<T*>(findObject(iD)); t = dynamic_cast<T*>(findObject(iD));

View file

@ -28,30 +28,23 @@
// Stupid globals not declared in a header // Stupid globals not declared in a header
extern ExprEvalState gEvalState; extern ExprEvalState gEvalState;
SimConsoleEvent::SimConsoleEvent(S32 argc, ConsoleValueRef *argv, bool onObject) SimConsoleEvent::SimConsoleEvent(S32 argc, ConsoleValue *argv, bool onObject)
{ {
mOnObject = onObject; mOnObject = onObject;
mArgc = argc; mArgc = argc;
mArgv = new ConsoleValueRef[argc]; mArgv = new ConsoleValue[argc]();
for (int i=0; i<argc; i++) for (int i=0; i<argc; i++)
{ {
mArgv[i].value = new ConsoleValue(); if (argv)
mArgv[i].value->type = ConsoleValue::TypeInternalString; {
mArgv[i].value->init(); mArgv[i].setString(argv[i].getString());
if (argv) }
{
mArgv[i].value->setStringValue((const char*)argv[i]);
}
} }
} }
SimConsoleEvent::~SimConsoleEvent() SimConsoleEvent::~SimConsoleEvent()
{ {
for (int i=0; i<mArgc; i++)
{
delete mArgv[i].value;
}
delete[] mArgv; delete[] mArgv;
} }
@ -67,7 +60,7 @@ void SimConsoleEvent::process(SimObject* object)
// Grab the function name. If '::' doesn't exist, then the schedule is // Grab the function name. If '::' doesn't exist, then the schedule is
// on a global function. // on a global function.
char funcName[256]; char funcName[256];
dStrncpy(funcName, (const char*)mArgv[0], 256); dStrncpy(funcName, mArgv[0].getString(), 256);
char* func = dStrstr( funcName, (char*)"::" ); char* func = dStrstr( funcName, (char*)"::" );
if( func ) if( func )
{ {
@ -95,11 +88,11 @@ void SimConsoleEvent::process(SimObject* object)
} }
} }
void SimConsoleEvent::populateArgs(ConsoleValueRef *argv) void SimConsoleEvent::populateArgs(ConsoleValue *argv)
{ {
for (U32 i=0; i<mArgc; i++) for (U32 i=0; i<mArgc; i++)
{ {
argv[i].value = mArgv[i].value; argv[i].setString(mArgv[i].getString());
} }
} }
@ -107,7 +100,6 @@ void SimConsoleEvent::populateArgs(ConsoleValueRef *argv)
SimConsoleThreadExecCallback::SimConsoleThreadExecCallback() SimConsoleThreadExecCallback::SimConsoleThreadExecCallback()
{ {
retVal.value = NULL;
sem = new Semaphore(0); sem = new Semaphore(0);
} }
@ -116,37 +108,44 @@ SimConsoleThreadExecCallback::~SimConsoleThreadExecCallback()
delete sem; delete sem;
} }
void SimConsoleThreadExecCallback::handleCallback(ConsoleValueRef ret) void SimConsoleThreadExecCallback::handleCallback(ConsoleValue ret)
{ {
retVal = ret; // can we move this pls?
retVal.setString(ret.getString());
sem->release(); sem->release();
} }
ConsoleValueRef SimConsoleThreadExecCallback::waitForResult() ConsoleValue SimConsoleThreadExecCallback::waitForResult()
{ {
if(sem->acquire(true)) if(sem->acquire(true))
{ {
return retVal; return std::move(retVal);
} }
return ConsoleValueRef(); return ConsoleValue();
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
SimConsoleThreadExecEvent::SimConsoleThreadExecEvent(S32 argc, ConsoleValueRef *argv, bool onObject, SimConsoleThreadExecCallback *callback) : SimConsoleThreadExecEvent::SimConsoleThreadExecEvent(S32 argc, ConsoleValue *argv, bool onObject, SimConsoleThreadExecCallback *callback) :
SimConsoleEvent(argc, argv, onObject), cb(callback) SimConsoleEvent(argc, argv, onObject), cb(callback)
{ {
} }
void SimConsoleThreadExecEvent::process(SimObject* object) void SimConsoleThreadExecEvent::process(SimObject* object)
{ {
ConsoleValueRef retVal; if (cb)
if(mOnObject) {
retVal = Con::execute(object, mArgc, mArgv); if (mOnObject)
cb->handleCallback(std::move(Con::execute(object, mArgc, mArgv)));
else
cb->handleCallback(std::move(Con::execute(mArgc, mArgv)));
}
else else
retVal = Con::execute(mArgc, mArgv); {
if (mOnObject)
if(cb) Con::execute(object, mArgc, mArgv);
cb->handleCallback(retVal); else
Con::execute(mArgc, mArgv);
}
} }

View file

@ -83,8 +83,6 @@ public:
virtual void process(SimObject *object)=0; virtual void process(SimObject *object)=0;
}; };
class ConsoleValueRef;
/// Implementation of schedule() function. /// Implementation of schedule() function.
/// ///
/// This allows you to set a console function to be /// This allows you to set a console function to be
@ -93,7 +91,7 @@ class SimConsoleEvent : public SimEvent
{ {
protected: protected:
S32 mArgc; S32 mArgc;
ConsoleValueRef *mArgv; ConsoleValue *mArgv;
bool mOnObject; bool mOnObject;
public: public:
@ -110,13 +108,13 @@ public:
/// ///
/// @see Con::execute(S32 argc, const char *argv[]) /// @see Con::execute(S32 argc, const char *argv[])
/// @see Con::execute(SimObject *object, S32 argc, const char *argv[]) /// @see Con::execute(SimObject *object, S32 argc, const char *argv[])
SimConsoleEvent(S32 argc, ConsoleValueRef *argv, bool onObject); SimConsoleEvent(S32 argc, ConsoleValue *argv, bool onObject);
~SimConsoleEvent(); ~SimConsoleEvent();
virtual void process(SimObject *object); virtual void process(SimObject *object);
/// Creates a reference to our internal args list in argv /// Creates a reference to our internal args list in argv
void populateArgs(ConsoleValueRef *argv); void populateArgs(ConsoleValue *argv);
}; };
@ -125,13 +123,13 @@ public:
struct SimConsoleThreadExecCallback struct SimConsoleThreadExecCallback
{ {
Semaphore *sem; Semaphore *sem;
ConsoleValueRef retVal; ConsoleValue retVal;
SimConsoleThreadExecCallback(); SimConsoleThreadExecCallback();
~SimConsoleThreadExecCallback(); ~SimConsoleThreadExecCallback();
void handleCallback(ConsoleValueRef ret); void handleCallback(ConsoleValue ret);
ConsoleValueRef waitForResult(); ConsoleValue waitForResult();
}; };
class SimConsoleThreadExecEvent : public SimConsoleEvent class SimConsoleThreadExecEvent : public SimConsoleEvent
@ -139,7 +137,7 @@ class SimConsoleThreadExecEvent : public SimConsoleEvent
SimConsoleThreadExecCallback *cb; SimConsoleThreadExecCallback *cb;
public: public:
SimConsoleThreadExecEvent(S32 argc, ConsoleValueRef *argv, bool onObject, SimConsoleThreadExecCallback *callback); SimConsoleThreadExecEvent(S32 argc, ConsoleValue *argv, bool onObject, SimConsoleThreadExecCallback *callback);
SimConsoleThreadExecCallback& getCB() { return *cb; } SimConsoleThreadExecCallback& getCB() { return *cb; }
virtual void process(SimObject *object); virtual void process(SimObject *object);

View file

@ -328,11 +328,6 @@ SimObject* findObject(const char* fileName, S32 declarationLine)
return gRootGroup->findObjectByLineNumber(fileName, declarationLine, true); return gRootGroup->findObjectByLineNumber(fileName, declarationLine, true);
} }
SimObject* findObject(ConsoleValueRef &ref)
{
return findObject((const char*)ref);
}
SimObject* findObject(const char* name) SimObject* findObject(const char* name)
{ {
PROFILE_SCOPE(SimFindObject); PROFILE_SCOPE(SimFindObject);
@ -391,6 +386,20 @@ SimObject* findObject(const char* name)
return obj->findObject(name + len + 1); return obj->findObject(name + len + 1);
} }
SimObject* findObject(const ConsoleValue &val)
{
if (val.getType() == ConsoleValueType::cvInteger)
return findObject((SimObjectId)val.getFastInt());
return findObject(val.getString());
}
SimObject* findObject(ConsoleValue* val)
{
if (val->getType() == ConsoleValueType::cvInteger)
return findObject((SimObjectId)val->getFastInt());
return findObject(val->getString());
}
SimObject* findObject(SimObjectId id) SimObject* findObject(SimObjectId id)
{ {
return gIdDictionary->find(id); return gIdDictionary->find(id);

View file

@ -141,7 +141,7 @@ SimObject::~SimObject()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool SimObject::processArguments(S32 argc, ConsoleValueRef *argv) bool SimObject::processArguments(S32 argc, ConsoleValue *argv)
{ {
return argc == 0; return argc == 0;
} }
@ -2971,8 +2971,10 @@ DefineEngineStringlyVariadicMethod( SimObject, call, const char*, 3, 0, "( strin
"@param args Zero or more arguments for the method.\n" "@param args Zero or more arguments for the method.\n"
"@return The result of the method call." ) "@return The result of the method call." )
{ {
argv[1] = argv[2]; argv[1].setString(argv[2].getString());
return Con::execute( object, argc - 1, argv + 1 );
ConsoleValue returnValue = Con::execute(object, argc - 1, argv + 1);
return Con::getReturnBuffer(returnValue.getString());
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -3074,9 +3076,9 @@ DefineEngineStringlyVariadicMethod( SimObject,schedule, S32, 4, 0, "( float time
"@param args The arguments with which to call the method.\n" "@param args The arguments with which to call the method.\n"
"@return The numeric ID of the created schedule. Can be used to cancel the call.\n" ) "@return The numeric ID of the created schedule. Can be used to cancel the call.\n" )
{ {
U32 timeDelta = U32(dAtof(argv[2])); U32 timeDelta = U32(argv[2].getFloat());
argv[2] = argv[3]; argv[2].setString(argv[3].getString());
argv[3] = argv[1]; argv[3].setString(argv[1].getString());
SimConsoleEvent *evt = new SimConsoleEvent(argc - 2, argv + 2, true); SimConsoleEvent *evt = new SimConsoleEvent(argc - 2, argv + 2, true);
S32 ret = Sim::postEvent(object, evt, Sim::getCurrentTime() + timeDelta); S32 ret = Sim::postEvent(object, evt, Sim::getCurrentTime() + timeDelta);
// #ifdef DEBUG // #ifdef DEBUG

View file

@ -587,7 +587,7 @@ class SimObject: public ConsoleObject, public TamlCallbacks
virtual ~SimObject(); virtual ~SimObject();
virtual bool processArguments(S32 argc, ConsoleValueRef *argv); ///< Process constructor options. (ie, new SimObject(1,2,3)) virtual bool processArguments(S32 argc, ConsoleValue *argv); ///< Process constructor options. (ie, new SimObject(1,2,3))
/// @} /// @}

View file

@ -47,7 +47,7 @@ SimPersistSet::SimPersistSet()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool SimPersistSet::processArguments( S32 argc, ConsoleValueRef *argv ) bool SimPersistSet::processArguments( S32 argc, ConsoleValue *argv )
{ {
for( U32 i = 0; i < argc; ++ i ) for( U32 i = 0; i < argc; ++ i )
{ {

View file

@ -58,7 +58,7 @@ class SimPersistSet : public SimSet
// SimSet. // SimSet.
virtual void addObject( SimObject* ); virtual void addObject( SimObject* );
virtual void write( Stream &stream, U32 tabStop, U32 flags = 0 ); virtual void write( Stream &stream, U32 tabStop, U32 flags = 0 );
virtual bool processArguments( S32 argc, ConsoleValueRef *argv ); virtual bool processArguments( S32 argc, ConsoleValue *argv );
DECLARE_CONOBJECT( SimPersistSet ); DECLARE_CONOBJECT( SimPersistSet );
DECLARE_CATEGORY( "Console" ); DECLARE_CATEGORY( "Console" );

View file

@ -229,17 +229,15 @@ void SimSet::scriptSort( const String &scriptCallbackFn )
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void SimSet::callOnChildren( const String &method, S32 argc, ConsoleValueRef argv[], bool executeOnChildGroups ) void SimSet::callOnChildren( const String &method, S32 argc, ConsoleValue argv[], bool executeOnChildGroups )
{ {
// Prep the arguments for the console exec... // Prep the arguments for the console exec...
// Make sure and leave args[1] empty. // Make sure and leave args[1] empty.
ConsoleValueRef args[21] = { }; ConsoleValue args[21] = { };
ConsoleValue name_method; args[0].setString(method.c_str());
name_method.setStackStringValue(method.c_str());
args[0] = ConsoleValueRef::fromValue(&name_method);
for (S32 i = 0; i < argc; i++) for (S32 i = 0; i < argc; i++)
args[i + 2] = argv[i]; args[i + 2].setString(argv[i].getString());
for( iterator i = begin(); i != end(); i++ ) for( iterator i = begin(); i != end(); i++ )
{ {
@ -838,7 +836,7 @@ SimGroup* SimGroup::deepClone()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool SimGroup::processArguments(S32, ConsoleValueRef *argv) bool SimGroup::processArguments(S32, ConsoleValue *argv)
{ {
return true; return true;
} }

View file

@ -218,7 +218,7 @@ class SimSet : public SimObject, public TamlChildren
/// @} /// @}
void callOnChildren( const String &method, S32 argc, ConsoleValueRef argv[], bool executeOnChildGroups = true ); void callOnChildren( const String &method, S32 argc, ConsoleValue argv[], bool executeOnChildGroups = true );
/// Return the number of objects in this set as well as all sets that are contained /// Return the number of objects in this set as well as all sets that are contained
/// in this set and its children. /// in this set and its children.
@ -464,7 +464,7 @@ class SimGroup: public SimSet
virtual SimObject* findObject(const char* name); virtual SimObject* findObject(const char* name);
virtual void onRemove(); virtual void onRemove();
virtual bool processArguments( S32 argc, ConsoleValueRef *argv ); virtual bool processArguments( S32 argc, ConsoleValue *argv );
virtual SimObject* getObject(const S32& index); virtual SimObject* getObject(const S32& index);

View file

@ -39,7 +39,6 @@ StringStack::StringStack()
mStart = 0; mStart = 0;
mLen = 0; mLen = 0;
mStartStackSize = 0; mStartStackSize = 0;
mFunctionOffset = 0;
validateBufferSize(8192); validateBufferSize(8192);
validateArgBufferSize(2048); validateArgBufferSize(2048);
dMemset(mBuffer, '\0', mBufferSize); dMemset(mBuffer, '\0', mBufferSize);
@ -82,7 +81,7 @@ void StringStack::setIntValue(U32 i)
void StringStack::setFloatValue(F64 v) void StringStack::setFloatValue(F64 v)
{ {
validateBufferSize(mStart + 32); validateBufferSize(mStart + 32);
dSprintf(mBuffer + mStart, 32, "%g", v); dSprintf(mBuffer + mStart, 32, "%.9g", v);
mLen = dStrlen(mBuffer + mStart); mLen = dStrlen(mBuffer + mStart);
} }
@ -180,255 +179,3 @@ U32 StringStack::compare()
return ret; return ret;
} }
void StringStack::pushFrame()
{
//Con::printf("StringStack pushFrame [frame=%i, start=%i]", mNumFrames, mStartStackSize);
mFrameOffsets[mNumFrames++] = mStartStackSize;
mStartOffsets[mStartStackSize++] = mStart;
mStart += ReturnBufferSpace;
validateBufferSize(0);
}
void StringStack::popFrame()
{
//Con::printf("StringStack popFrame [frame=%i, start=%i]", mNumFrames, mStartStackSize);
mStartStackSize = mFrameOffsets[--mNumFrames];
mStart = mStartOffsets[mStartStackSize];
mLen = 0;
}
void StringStack::clearFrames()
{
//Con::printf("StringStack clearFrames");
mNumFrames = 0;
mStart = 0;
mLen = 0;
mStartStackSize = 0;
mFunctionOffset = 0;
}
void ConsoleValueStack::getArgcArgv(StringTableEntry name, U32 *argc, ConsoleValueRef **in_argv, bool popStackFrame /* = false */)
{
U32 startStack = mStackFrames[mFrame-1];
U32 argCount = getMin(mStackPos - startStack, (U32)MaxArgs - 1);
*in_argv = mArgv;
mArgv[0].value = CSTK.pushStackString(name);
for(U32 i = 0; i < argCount; i++) {
ConsoleValueRef *ref = &mArgv[i+1];
ref->value = &mStack[startStack + i];
}
argCount++;
*argc = argCount;
if(popStackFrame)
popFrame();
}
ConsoleValueStack::ConsoleValueStack() :
mFrame(0),
mStackPos(0)
{
for (int i=0; i<ConsoleValueStack::MaxStackDepth; i++) {
mStack[i].init();
mStack[i].type = ConsoleValue::TypeInternalString;
}
dMemset(mStackFrames, 0, sizeof(mStackFrames));
}
ConsoleValueStack::~ConsoleValueStack()
{
}
void ConsoleValueStack::pushVar(ConsoleValue *variable)
{
if (mStackPos == ConsoleValueStack::MaxStackDepth) {
AssertFatal(false, "Console Value Stack is empty");
return;
}
switch (variable->type)
{
case ConsoleValue::TypeInternalInt:
mStack[mStackPos++].setIntValue((S32)variable->getIntValue());
case ConsoleValue::TypeInternalFloat:
mStack[mStackPos++].setFloatValue((F32)variable->getFloatValue());
default:
mStack[mStackPos++].setStackStringValue(variable->getStringValue());
}
}
void ConsoleValueStack::pushValue(ConsoleValue &variable)
{
if (mStackPos == ConsoleValueStack::MaxStackDepth) {
AssertFatal(false, "Console Value Stack is empty");
return;
}
switch (variable.type)
{
case ConsoleValue::TypeInternalInt:
mStack[mStackPos++].setIntValue((S32)variable.getIntValue());
case ConsoleValue::TypeInternalFloat:
mStack[mStackPos++].setFloatValue((F32)variable.getFloatValue());
case ConsoleValue::TypeInternalStringStackPtr:
mStack[mStackPos++].setStringStackPtrValue(variable.getStringStackPtr());
default:
mStack[mStackPos++].setStringValue(variable.getStringValue());
}
}
ConsoleValue* ConsoleValueStack::reserveValues(U32 count)
{
U32 startPos = mStackPos;
if (startPos+count >= ConsoleValueStack::MaxStackDepth) {
AssertFatal(false, "Console Value Stack is empty");
return NULL;
}
//Con::printf("[%i]CSTK reserveValues %i", mStackPos, count);
mStackPos += count;
return &mStack[startPos];
}
bool ConsoleValueStack::reserveValues(U32 count, ConsoleValueRef *outValues)
{
U32 startPos = mStackPos;
if (startPos+count >= ConsoleValueStack::MaxStackDepth) {
AssertFatal(false, "Console Value Stack is empty");
return false;
}
//Con::printf("[%i]CSTK reserveValues %i", mStackPos, count);
for (U32 i=0; i<count; i++)
{
outValues[i].value = &mStack[mStackPos+i];
}
mStackPos += count;
return true;
}
ConsoleValue *ConsoleValueStack::pushString(const char *value)
{
if (mStackPos == ConsoleValueStack::MaxStackDepth) {
AssertFatal(false, "Console Value Stack is empty");
return NULL;
}
//Con::printf("[%i]CSTK pushString %s", mStackPos, value);
mStack[mStackPos++].setStringValue(value);
return &mStack[mStackPos-1];
}
ConsoleValue *ConsoleValueStack::pushStackString(const char *value)
{
if (mStackPos == ConsoleValueStack::MaxStackDepth) {
AssertFatal(false, "Console Value Stack is empty");
return NULL;
}
//Con::printf("[%i]CSTK pushString %s", mStackPos, value);
mStack[mStackPos++].setStackStringValue(value);
return &mStack[mStackPos-1];
}
ConsoleValue *ConsoleValueStack::pushStringStackPtr(StringStackPtr value)
{
if (mStackPos == ConsoleValueStack::MaxStackDepth) {
AssertFatal(false, "Console Value Stack is empty");
return NULL;
}
//Con::printf("[%i]CSTK pushStringStackPtr %s", mStackPos, StringStackPtrRef(value).getPtr(&STR));
mStack[mStackPos++].setStringStackPtrValue(value);
return &mStack[mStackPos-1];
}
ConsoleValue *ConsoleValueStack::pushUINT(U32 value)
{
if (mStackPos == ConsoleValueStack::MaxStackDepth) {
AssertFatal(false, "Console Value Stack is empty");
return NULL;
}
//Con::printf("[%i]CSTK pushUINT %i", mStackPos, value);
mStack[mStackPos++].setIntValue(value);
return &mStack[mStackPos-1];
}
ConsoleValue *ConsoleValueStack::pushFLT(float value)
{
if (mStackPos == ConsoleValueStack::MaxStackDepth) {
AssertFatal(false, "Console Value Stack is empty");
return NULL;
}
//Con::printf("[%i]CSTK pushFLT %f", mStackPos, value);
mStack[mStackPos++].setFloatValue(value);
return &mStack[mStackPos-1];
}
static ConsoleValue gNothing;
ConsoleValue* ConsoleValueStack::pop()
{
if (mStackPos == 0) {
AssertFatal(false, "Console Value Stack is empty");
return &gNothing;
}
return &mStack[--mStackPos];
}
void ConsoleValueStack::pushFrame()
{
//Con::printf("CSTK pushFrame[%i] (%i)", mFrame, mStackPos);
mStackFrames[mFrame++] = mStackPos;
}
void ConsoleValueStack::resetFrame()
{
if (mFrame == 0) {
mStackPos = 0;
return;
}
U32 start = mStackFrames[mFrame-1];
//for (U32 i=start; i<mStackPos; i++) {
//mStack[i].clear();
//}
mStackPos = start;
//Con::printf("CSTK resetFrame to %i", mStackPos);
}
void ConsoleValueStack::clearFrames()
{
mStackPos = 0;
mFrame = 0;
}
void ConsoleValueStack::popFrame()
{
//Con::printf("CSTK popFrame");
if (mFrame == 0) {
// Go back to start
mStackPos = 0;
return;
}
U32 start = mStackFrames[mFrame-1];
//for (U32 i=start; i<mStackPos; i++) {
//mStack[i].clear();
//}
mStackPos = start;
mFrame--;
}

View file

@ -114,15 +114,15 @@ struct StringStack
} }
/// Get an integer representation of the top of the stack. /// Get an integer representation of the top of the stack.
inline U32 getIntValue() inline S64 getIntValue()
{ {
return dAtoi(mBuffer + mStart); return dAtol(mBuffer + mStart);
} }
/// Get a float representation of the top of the stack. /// Get a float representation of the top of the stack.
inline F64 getFloatValue() inline F64 getFloatValue()
{ {
return dAtof(mBuffer + mStart); return dAtod(mBuffer + mStart);
} }
/// Get a string representation of the top of the stack. /// Get a string representation of the top of the stack.
@ -138,16 +138,6 @@ struct StringStack
return mBuffer + mStartOffsets[mStartStackSize-1]; return mBuffer + mStartOffsets[mStartStackSize-1];
} }
inline StringStackPtr getStringValuePtr()
{
return (getStringValue() - mBuffer);
}
inline StringStackPtr getPreviousStringValuePtr()
{
return (getPreviousStringValue() - mBuffer);
}
/// Advance the start stack, placing a zero length string on the top. /// Advance the start stack, placing a zero length string on the top.
/// ///
/// @note You should use StringStack::push, not this, if you want to /// @note You should use StringStack::push, not this, if you want to
@ -179,61 +169,10 @@ struct StringStack
/// and returning true if they matched, false if they didn't. /// and returning true if they matched, false if they didn't.
U32 compare(); U32 compare();
void pushFrame();
void popFrame();
void clearFrames(); void clearFrames();
/// Get the arguments for a function call from the stack.
void getArgcArgv(StringTableEntry name, U32 *argc, const char ***in_argv, bool popStackFrame = false);
};
// New console value stack
class ConsoleValueStack
{
enum {
MaxStackDepth = 1024,
MaxArgs = 20,
ReturnBufferSpace = 512
};
public:
ConsoleValueStack();
~ConsoleValueStack();
void pushVar(ConsoleValue *variable);
void pushValue(ConsoleValue &value);
ConsoleValue* reserveValues(U32 numValues);
bool reserveValues(U32 numValues, ConsoleValueRef *values);
ConsoleValue* pop();
ConsoleValue *pushString(const char *value);
ConsoleValue *pushStackString(const char *value);
ConsoleValue *pushStringStackPtr(StringStackPtr ptr);
ConsoleValue *pushUINT(U32 value);
ConsoleValue *pushFLT(float value);
void pushFrame();
void popFrame();
void resetFrame();
void clearFrames();
void getArgcArgv(StringTableEntry name, U32 *argc, ConsoleValueRef **in_argv, bool popStackFrame = false);
ConsoleValue mStack[MaxStackDepth];
U32 mStackFrames[MaxStackDepth];
U32 mFrame;
U32 mStackPos;
ConsoleValueRef mArgv[MaxArgs];
}; };
extern StringStack STR; extern StringStack STR;
extern ConsoleValueStack CSTK;
inline char* StringStackPtrRef::getPtr(StringStack *stk) { return stk->mBuffer + mOffset; } inline char* StringStackPtrRef::getPtr(StringStack *stk) { return stk->mBuffer + mOffset; }

View file

@ -864,6 +864,49 @@ void TelnetDebugger::evaluateExpression(const char *tag, S32 frame, const char *
if ( frame < 0 ) if ( frame < 0 )
frame = 0; frame = 0;
// Local variables use their own memory management and can't be queried by just executing
// TorqueScript, we have to go digging into the interpreter.
S32 evalBufferLen = dStrlen(evalBuffer);
bool isEvaluatingLocalVariable = evalBufferLen > 0 && evalBuffer[0] == '%';
if (isEvaluatingLocalVariable)
{
// See calculation of current frame in pushing a reference frame for console exec, we need access
// to the proper scope.
//frame = gEvalState.getTopOfStack() - frame - 1;
S32 stackIndex = gEvalState.getTopOfStack() - frame - 1;
const char* format = "EVALOUT %s %s\r\n";
gEvalState.pushDebugFrame(stackIndex);
Dictionary& stackFrame = gEvalState.getCurrentFrame();
StringTableEntry functionName = stackFrame.scopeName;
StringTableEntry namespaceName = stackFrame.scopeNamespace->mName;
StringTableEntry varToLookup = StringTable->insert(evalBuffer);
S32 registerId = stackFrame.code->variableRegisterTable.lookup(namespaceName, functionName, varToLookup);
if (registerId == -1)
{
// ERROR, can't read the variable!
send("EVALOUT \"\" \"\"");
return;
}
const char* varResult = gEvalState.getLocalStringVariable(registerId);
gEvalState.popFrame();
S32 len = dStrlen(format) + dStrlen(tag) + dStrlen(varResult);
char* buffer = new char[len];
dSprintf(buffer, len, format, tag, varResult[0] ? varResult : "\"\"");
send(buffer);
delete[] buffer;
return;
}
// Build a buffer just big enough for this eval. // Build a buffer just big enough for this eval.
const char* format = "return %s;"; const char* format = "return %s;";
dsize_t len = dStrlen( format ) + dStrlen( evalBuffer ); dsize_t len = dStrlen( format ) + dStrlen( evalBuffer );
@ -872,14 +915,14 @@ void TelnetDebugger::evaluateExpression(const char *tag, S32 frame, const char *
// Execute the eval. // Execute the eval.
CodeBlock *newCodeBlock = new CodeBlock(); CodeBlock *newCodeBlock = new CodeBlock();
const char* result = newCodeBlock->compileExec( NULL, buffer, false, frame ); ConsoleValue result = newCodeBlock->compileExec( NULL, buffer, false, frame );
delete [] buffer; delete [] buffer;
// Create a new buffer that fits the result. // Create a new buffer that fits the result.
format = "EVALOUT %s %s\r\n"; format = "EVALOUT %s %s\r\n";
len = dStrlen( format ) + dStrlen( tag ) + dStrlen( result ); len = dStrlen( format ) + dStrlen( tag ) + dStrlen( result.getString() );
buffer = new char[ len ]; buffer = new char[ len ];
dSprintf( buffer, len, format, tag, result[0] ? result : "\"\"" ); dSprintf( buffer, len, format, tag, result.getString()[0] ? result.getString() : "\"\"" );
send( buffer ); send( buffer );
delete [] buffer; delete [] buffer;

File diff suppressed because it is too large Load diff

View file

@ -1,3 +1,5 @@
#if 0
#ifdef TORQUE_TESTS_ENABLED #ifdef TORQUE_TESTS_ENABLED
#include "testing/unitTesting.h" #include "testing/unitTesting.h"
#include "platform/platform.h" #include "platform/platform.h"
@ -253,3 +255,4 @@ TEST(Con, execute)
} }
#endif #endif
#endif

View file

@ -1,3 +1,4 @@
#if 0
#ifdef TORQUE_TESTS_ENABLED #ifdef TORQUE_TESTS_ENABLED
#include "testing/unitTesting.h" #include "testing/unitTesting.h"
#include "platform/platform.h" #include "platform/platform.h"
@ -148,3 +149,4 @@ TEST(EngineAPI, _EngineConsoleExecCallbackHelper)
} }
#endif #endif
#endif

View file

@ -428,7 +428,7 @@ S32 dStrlcpy(char *dst, const char *src, dsize_t dstSize)
S32 copyLen = srcLen; S32 copyLen = srcLen;
//Check for buffer overflow and don't allow it. Warn on debug so we can fix it //Check for buffer overflow and don't allow it. Warn on debug so we can fix it
AssertWarn(copyLen < dstSize, "Buffer too small in call to dStrlcpy!"); AssertFatal(copyLen < dstSize, "Buffer too small in call to dStrlcpy!");
if (srcLen + 1 > dstSize) if (srcLen + 1 > dstSize)
{ {
copyLen = dstSize - 1; copyLen = dstSize - 1;

View file

@ -200,6 +200,11 @@ inline F64 dAtod(const char *str)
return strtod(str, NULL); return strtod(str, NULL);
} }
inline S64 dAtol(const char* str)
{
return strtol(str, NULL, 10);
}
inline char dToupper(const char c) inline char dToupper(const char c)
{ {
return toupper( c ); return toupper( c );

View file

@ -160,6 +160,7 @@ class Vector
void erase(U32 index, U32 count); void erase(U32 index, U32 count);
void erase_fast(iterator); void erase_fast(iterator);
void clear(); void clear();
void resetAndTreatAsScratchBuffer();
void compact(); void compact();
void sort(compare_func f); void sort(compare_func f);
void fill( const T& value ); void fill( const T& value );
@ -529,6 +530,15 @@ template<class T> inline void Vector<T>::clear()
mElementCount = 0; mElementCount = 0;
} }
/// This method sets the vector as its 0 and will overwrite memory on subsequent usage.
/// Note that the current memory in use is never freed or deallocated, so only use this if the vector
/// is being used as a scratch buffer only.
template<class T> inline
void Vector<T>::resetAndTreatAsScratchBuffer()
{
mElementCount = 0;
}
template<class T> inline void Vector<T>::compact() template<class T> inline void Vector<T>::compact()
{ {
resize(mElementCount); resize(mElementCount);

View file

@ -418,7 +418,7 @@ void WaterObject::inspectPostApply()
setMaskBits( UpdateMask | WaveMask | TextureMask | SoundMask ); setMaskBits( UpdateMask | WaveMask | TextureMask | SoundMask );
} }
bool WaterObject::processArguments( S32 argc, ConsoleValueRef *argv ) bool WaterObject::processArguments( S32 argc, ConsoleValue *argv )
{ {
if( typeid( *this ) == typeid( WaterObject ) ) if( typeid( *this ) == typeid( WaterObject ) )
{ {

View file

@ -158,7 +158,7 @@ public:
virtual bool onAdd(); virtual bool onAdd();
virtual void onRemove(); virtual void onRemove();
virtual void inspectPostApply(); virtual void inspectPostApply();
virtual bool processArguments(S32 argc, ConsoleValueRef *argv); virtual bool processArguments(S32 argc, ConsoleValue *argv);
// NetObject // NetObject
virtual U32 packUpdate( NetConnection * conn, U32 mask, BitStream *stream ); virtual U32 packUpdate( NetConnection * conn, U32 mask, BitStream *stream );

View file

@ -361,10 +361,8 @@ void GuiGameListMenuCtrl::onRenderSliderOption(Row* row, Point2I currentOffset)
// calculate text to be at the center between the arrows // calculate text to be at the center between the arrows
GFont* font = profile->mFont; GFont* font = profile->mFont;
ConsoleValue val; char stringVal[32];
val.setFloatValue(row->mValue); dSprintf(stringVal, 32, "%f", row->mValue);
const char* stringVal = val.getStringValue();
S32 textWidth = font->getStrWidth(stringVal); S32 textWidth = font->getStrWidth(stringVal);
S32 columnWidth = profile->mHitAreaLowerRight.x * xScale - profile->mRightPad - columnSplit; S32 columnWidth = profile->mHitAreaLowerRight.x * xScale - profile->mRightPad - columnSplit;

View file

@ -319,7 +319,7 @@ void GuiControl::initPersistFields()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool GuiControl::processArguments(S32 argc, ConsoleValueRef *argv) bool GuiControl::processArguments(S32 argc, ConsoleValue *argv)
{ {
// argv[0] - The GuiGroup to add this control to when it's created. // argv[0] - The GuiGroup to add this control to when it's created.
// this is an optional parameter that may be specified at // this is an optional parameter that may be specified at

View file

@ -341,7 +341,7 @@ class GuiControl : public SimGroup
GuiControl(); GuiControl();
virtual ~GuiControl(); virtual ~GuiControl();
virtual bool processArguments(S32 argc, ConsoleValueRef *argv); virtual bool processArguments(S32 argc, ConsoleValue *argv);
static void initPersistFields(); static void initPersistFields();
static void consoleInit(); static void consoleInit();

View file

@ -83,7 +83,7 @@ DefineEngineStringlyVariadicMethod( GuiFilterCtrl, setValue, void, 3, 20, "(f1,
{ {
Filter filter; Filter filter;
StringStackWrapper args(argc - 2, argv + 2); ConsoleValueToStringArrayWrapper args(argc - 2, argv + 2);
filter.set(args.count(), args); filter.set(args.count(), args);
object->set(filter); object->set(filter);

View file

@ -318,7 +318,8 @@ void GuiInspectorField::setData( const char* data, bool callbacks )
{ {
char buffer[ 2048 ]; char buffer[ 2048 ];
expandEscape( buffer, newValue ); expandEscape( buffer, newValue );
newValue = (const char*)Con::evaluatef( "%%f = \"%s\"; return ( %s );", oldValue.c_str(), buffer ); newValue = (const char*)Con::evaluatef( "$f = \"%s\"; return ( %s );", oldValue.c_str(), buffer );
Con::evaluatef("$f=0;");
} }
else if( type == TypeS32Vector else if( type == TypeS32Vector
|| type == TypeF32Vector || type == TypeF32Vector
@ -353,8 +354,9 @@ void GuiInspectorField::setData( const char* data, bool callbacks )
char buffer[ 2048 ]; char buffer[ 2048 ];
expandEscape( buffer, newComponentExpr ); expandEscape( buffer, newComponentExpr );
const char* newComponentVal = Con::evaluatef( "%%f = \"%s\"; %%v = \"%s\"; return ( %s );", const char* newComponentVal = Con::evaluatef( "$f = \"%s\"; $v = \"%s\"; return ( %s );",
oldComponentVal, oldValue.c_str(), buffer ); oldComponentVal, oldValue.c_str(), buffer );
Con::evaluatef("$f=0;$v=0;");
if( !isFirst ) if( !isFirst )
strNew.append( ' ' ); strNew.append( ' ' );

View file

@ -120,12 +120,14 @@ void PopupMenu::handleSelectEvent(U32 popID, U32 command)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool PopupMenu::onMessageReceived(StringTableEntry queue, const char* event, const char* data) bool PopupMenu::onMessageReceived(StringTableEntry queue, const char* event, const char* data)
{ {
return Con::executef(this, "onMessageReceived", queue, event, data); ConsoleValue returnValue = Con::executef(this, "onMessageReceived", queue, event, data);
return returnValue.getBool();
} }
bool PopupMenu::onMessageObjectReceived(StringTableEntry queue, Message *msg ) bool PopupMenu::onMessageObjectReceived(StringTableEntry queue, Message *msg )
{ {
return Con::executef(this, "onMessageReceived", queue, Con::getIntArg(msg->getId())); ConsoleValue returnValue = Con::executef(this, "onMessageReceived", queue, Con::getIntArg(msg->getId()));
return returnValue.getBool();
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////

View file

@ -2861,17 +2861,17 @@ void WorldEditor::initPersistFields()
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// These methods are needed for the console interfaces. // These methods are needed for the console interfaces.
void WorldEditor::ignoreObjClass( U32 argc, ConsoleValueRef *argv ) void WorldEditor::ignoreObjClass( U32 argc, ConsoleValue *argv )
{ {
for(S32 i = 2; i < argc; i++) for(S32 i = 2; i < argc; i++)
{ {
ClassInfo::Entry * entry = getClassEntry(argv[i]); ClassInfo::Entry * entry = getClassEntry(argv[i].getString());
if(entry) if(entry)
entry->mIgnoreCollision = true; entry->mIgnoreCollision = true;
else else
{ {
entry = new ClassInfo::Entry; entry = new ClassInfo::Entry;
entry->mName = StringTable->insert(argv[i]); entry->mName = StringTable->insert(argv[i].getString());
entry->mIgnoreCollision = true; entry->mIgnoreCollision = true;
if(!addClassEntry(entry)) if(!addClassEntry(entry))
delete entry; delete entry;

View file

@ -76,7 +76,7 @@ class WorldEditor : public EditTSCtrl
Point3F p2; Point3F p2;
}; };
void ignoreObjClass(U32 argc, ConsoleValueRef* argv); void ignoreObjClass(U32 argc, ConsoleValue* argv);
void clearIgnoreList(); void clearIgnoreList();
static bool setObjectsUseBoxCenter( void *object, const char *index, const char *data ) { static_cast<WorldEditor*>(object)->setObjectsUseBoxCenter( dAtob( data ) ); return false; }; static bool setObjectsUseBoxCenter( void *object, const char *index, const char *data ) { static_cast<WorldEditor*>(object)->setObjectsUseBoxCenter( dAtob( data ) ); return false; };

View file

@ -43,6 +43,10 @@ typedef unsigned long U64;
// Compiler Version // Compiler Version
#define TORQUE_COMPILER_GCC (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) #define TORQUE_COMPILER_GCC (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
#define TORQUE_FORCEINLINE __attribute__((always_inline))
#define TORQUE_CASE_FALLTHROUGH __attribute__((fallthrough))
#define TORQUE_NOINLINE __attribute__ ((noinline))
#define TORQUE_UNLIKELY
//-------------------------------------- //--------------------------------------
// Identify the compiler string // Identify the compiler string
@ -165,8 +169,5 @@ typedef unsigned long U64;
#endif #endif
#endif #endif
// Set GCC noinline
#define TORQUE_NOINLINE __attribute__ ((noinline))
#endif // INCLUDED_TYPES_GCC_H #endif // INCLUDED_TYPES_GCC_H

View file

@ -104,8 +104,16 @@ typedef unsigned _int64 U64;
// see msdn.microsoft.com "Compiler Warning (level 1) C4291" for more details // see msdn.microsoft.com "Compiler Warning (level 1) C4291" for more details
#pragma warning(disable: 4291) #pragma warning(disable: 4291)
// Set MSVC noline attribute #define TORQUE_FORCEINLINE __forceinline
#define TORQUE_NOINLINE __declspec(noinline) #define TORQUE_NOINLINE __declspec(noinline)
#if __cplusplus >= 201703L
#define TORQUE_CASE_FALLTHROUGH [[fallthrough]];
#define TORQUE_UNLIKELY [[unlikely]]
#else
#define TORQUE_CASE_FALLTHROUGH __fallthrough
#define TORQUE_UNLIKELY
#endif
#endif // INCLUDED_TYPES_VISUALC_H #endif // INCLUDED_TYPES_VISUALC_H

View file

@ -911,7 +911,7 @@ static bool recurseDumpDirectories(const char *basePath, const char *subPath, Ve
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool Platform::dumpDirectories(const char *path, Vector<StringTableEntry> &directoryVector, S32 depth, bool noBasePath) bool Platform::dumpDirectories(const char *path, Vector<StringTableEntry> &directoryVector, S32 depth, bool noBasePath)
{ {
bool retVal = recurseDumpDirectories(path, "", directoryVector, 0, depth, noBasePath); bool retVal = recurseDumpDirectories(path, "", directoryVector, -1, depth, noBasePath);
clearExcludedDirectories(); clearExcludedDirectories();
return retVal; return retVal;
} }

View file

@ -55,31 +55,36 @@ DefineEngineStringlyVariadicFunction( mathInit, void, 1, 10, "( ... )"
} }
for (argc--, argv++; argc; argc--, argv++) for (argc--, argv++; argc; argc--, argv++)
{ {
if (dStricmp(*argv, "DETECT") == 0) { const char* str = (*argv).getString();
if (dStricmp(str, "DETECT") == 0) {
Math::init(0); Math::init(0);
return; return;
} }
if (dStricmp(*argv, "C") == 0) { if (dStricmp(str, "C") == 0) {
properties |= CPU_PROP_C; properties |= CPU_PROP_C;
continue; continue;
} }
if (dStricmp(*argv, "FPU") == 0) { if (dStricmp(str, "FPU") == 0) {
properties |= CPU_PROP_FPU; properties |= CPU_PROP_FPU;
continue; continue;
} }
if (dStricmp(*argv, "MMX") == 0) { if (dStricmp(str, "MMX") == 0) {
properties |= CPU_PROP_MMX; properties |= CPU_PROP_MMX;
continue; continue;
} }
if (dStricmp(*argv, "3DNOW") == 0) { if (dStricmp(str, "3DNOW") == 0) {
properties |= CPU_PROP_3DNOW; properties |= CPU_PROP_3DNOW;
continue; continue;
} }
if (dStricmp(*argv, "SSE") == 0) { if (dStricmp(str, "SSE") == 0) {
properties |= CPU_PROP_SSE; properties |= CPU_PROP_SSE;
continue; continue;
} }
Con::printf("Error: MathInit(): ignoring unknown math extension '%s'", argv->getStringValue()); if (dStricmp(str, "SSE2") == 0) {
properties |= CPU_PROP_SSE2;
continue;
}
Con::printf("Error: MathInit(): ignoring unknown math extension '%s'", str);
} }
Math::init(properties); Math::init(properties);
} }

View file

@ -316,7 +316,7 @@ void SFXSource::initPersistFields()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool SFXSource::processArguments( S32 argc, ConsoleValueRef *argv ) bool SFXSource::processArguments( S32 argc, ConsoleValue *argv )
{ {
// Don't allow subclasses of this to be created via script. Force // Don't allow subclasses of this to be created via script. Force
// usage of the SFXSystem functions. // usage of the SFXSystem functions.
@ -791,6 +791,9 @@ void SFXSource::_setStatus( SFXStatus status )
void SFXSource::_updateVolume( const MatrixF& listener ) void SFXSource::_updateVolume( const MatrixF& listener )
{ {
if (!mDescription)
return;
// Handle fades (compute mFadedVolume). // Handle fades (compute mFadedVolume).
mFadedVolume = mPreFadeVolume; mFadedVolume = mPreFadeVolume;
@ -919,6 +922,9 @@ void SFXSource::_updateVolume( const MatrixF& listener )
void SFXSource::_updatePitch() void SFXSource::_updatePitch()
{ {
if (!mDescription)
return;
mEffectivePitch = mModulativePitch * mPitch; mEffectivePitch = mModulativePitch * mPitch;
} }
@ -926,6 +932,9 @@ void SFXSource::_updatePitch()
void SFXSource::_updatePriority() void SFXSource::_updatePriority()
{ {
if (!mDescription)
return;
mEffectivePriority = mPriority * mModulativePriority; mEffectivePriority = mPriority * mModulativePriority;
SFXSource* group = getSourceGroup(); SFXSource* group = getSourceGroup();

View file

@ -382,7 +382,7 @@ class SFXSource : public SimGroup
/// We overload this to disable creation of /// We overload this to disable creation of
/// a source via script 'new'. /// a source via script 'new'.
virtual bool processArguments( S32 argc, ConsoleValueRef *argv ); virtual bool processArguments( S32 argc, ConsoleValue *argv );
// Console getters/setters. // Console getters/setters.
static bool _setDescription( void *obj, const char *index, const char *data ); static bool _setDescription( void *obj, const char *index, const char *data );

View file

@ -95,7 +95,7 @@ void SFXTrack::initPersistFields()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool SFXTrack::processArguments( S32 argc, ConsoleValueRef *argv ) bool SFXTrack::processArguments( S32 argc, ConsoleValue *argv )
{ {
if( typeid( *this ) == typeid( SFXTrack ) ) if( typeid( *this ) == typeid( SFXTrack ) )
{ {

View file

@ -61,7 +61,7 @@ class SFXTrack : public SimDataBlock
StringTableEntry mParameters[ MaxNumParameters ]; StringTableEntry mParameters[ MaxNumParameters ];
/// Overload this to disable direct instantiation of this class via script 'new'. /// Overload this to disable direct instantiation of this class via script 'new'.
virtual bool processArguments( S32 argc, ConsoleValueRef *argv ); virtual bool processArguments( S32 argc, ConsoleValue *argv );
public: public:

View file

@ -238,7 +238,7 @@ void CustomFeatureGLSL::addVertTexCoord(String name)
mVars.push_back(newVarHolder); mVars.push_back(newVarHolder);
} }
void CustomFeatureGLSL::writeLine(String format, S32 argc, ConsoleValueRef * argv) void CustomFeatureGLSL::writeLine(String format, S32 argc, ConsoleValue * argv)
{ {
//do the var/arg fetching here //do the var/arg fetching here
Vector<Var*> varList; Vector<Var*> varList;
@ -246,7 +246,7 @@ void CustomFeatureGLSL::writeLine(String format, S32 argc, ConsoleValueRef * arg
for (U32 i = 0; i < argc; i++) for (U32 i = 0; i < argc; i++)
{ {
String varName = argv[i].getStringValue(); String varName = argv[i].getString();
Var* newVar = (Var*)LangElement::find(varName.c_str()); Var* newVar = (Var*)LangElement::find(varName.c_str());
if (!newVar) if (!newVar)
{ {
@ -304,7 +304,7 @@ void CustomFeatureGLSL::writeLine(String format, S32 argc, ConsoleValueRef * arg
if (!newVar) if (!newVar)
{ {
//couldn't find that variable, bail out //couldn't find that variable, bail out
Con::errorf("CustomShaderFeature::writeLine: unable to find variable %s, meaning it was not declared before being used!", argv[i].getStringValue()); Con::errorf("CustomShaderFeature::writeLine: unable to find variable %s, meaning it was not declared before being used!", argv[i].getString());
return; return;
} }
} }

View file

@ -128,5 +128,5 @@ public:
void addTexture(String name, String type, String samplerState, U32 arraySize); void addTexture(String name, String type, String samplerState, U32 arraySize);
void addConnector(String name, String type, String elementName); void addConnector(String name, String type, String elementName);
void addVertTexCoord(String name); void addVertTexCoord(String name);
void writeLine(String format, S32 argc, ConsoleValueRef* argv); void writeLine(String format, S32 argc, ConsoleValue* argv);
}; };

View file

@ -255,7 +255,7 @@ void CustomFeatureHLSL::addVertTexCoord(String name)
mVars.push_back(newVarHolder); mVars.push_back(newVarHolder);
} }
void CustomFeatureHLSL::writeLine(String format, S32 argc, ConsoleValueRef * argv) void CustomFeatureHLSL::writeLine(String format, S32 argc, ConsoleValue *argv)
{ {
//do the var/arg fetching here //do the var/arg fetching here
Vector<Var*> varList; Vector<Var*> varList;
@ -263,7 +263,7 @@ void CustomFeatureHLSL::writeLine(String format, S32 argc, ConsoleValueRef * arg
for (U32 i = 0; i < argc; i++) for (U32 i = 0; i < argc; i++)
{ {
String varName = argv[i].getStringValue(); String varName = argv[i].getString();
Var* newVar = (Var*)LangElement::find(varName.c_str()); Var* newVar = (Var*)LangElement::find(varName.c_str());
if (!newVar) if (!newVar)
{ {
@ -321,7 +321,7 @@ void CustomFeatureHLSL::writeLine(String format, S32 argc, ConsoleValueRef * arg
if (!newVar) if (!newVar)
{ {
//couldn't find that variable, bail out //couldn't find that variable, bail out
Con::errorf("CustomShaderFeature::writeLine: unable to find variable %s, meaning it was not declared before being used!", argv[i].getStringValue()); Con::errorf("CustomShaderFeature::writeLine: unable to find variable %s, meaning it was not declared before being used!", argv[i].getString());
return; return;
} }
} }

View file

@ -128,5 +128,5 @@ public:
void addTexture(String name, String type, String samplerState, U32 arraySize); void addTexture(String name, String type, String samplerState, U32 arraySize);
void addConnector(String name, String type, String elementName); void addConnector(String name, String type, String elementName);
void addVertTexCoord(String name); void addVertTexCoord(String name);
void writeLine(String format, S32 argc, ConsoleValueRef* argv); void writeLine(String format, S32 argc, ConsoleValue* argv);
}; };

View file

@ -189,7 +189,7 @@ bool CustomShaderFeatureData::hasFeature(String name)
return false; return false;
} }
void CustomShaderFeatureData::writeLine(String format, S32 argc, ConsoleValueRef* argv) void CustomShaderFeatureData::writeLine(String format, S32 argc, ConsoleValue* argv)
{ {
#ifdef TORQUE_D3D11 #ifdef TORQUE_D3D11
if (GFX->getAdapterType() == GFXAdapterType::Direct3D11) if (GFX->getAdapterType() == GFXAdapterType::Direct3D11)
@ -236,7 +236,7 @@ DefineEngineStringlyVariadicMethod(CustomShaderFeatureData, writeLine, void, 3,
"@param args Zero or more arguments for the method.\n" "@param args Zero or more arguments for the method.\n"
"@return The result of the method call.") "@return The result of the method call.")
{ {
object->writeLine(argv[2], argc - 3, argv + 3); object->writeLine(argv[2].getString(), argc - 3, argv + 3);
} }
DefineEngineMethod(CustomShaderFeatureData, hasFeature, bool, (String name), (""), "") DefineEngineMethod(CustomShaderFeatureData, hasFeature, bool, (String name), (""), "")

View file

@ -77,7 +77,7 @@ public:
void addVertTexCoord(String name); void addVertTexCoord(String name);
bool hasFeature(String name); bool hasFeature(String name);
void writeLine(String format, S32 argc, ConsoleValueRef *argv); void writeLine(String format, S32 argc, ConsoleValue *argv);
}; };
#endif #endif

View file

@ -2080,7 +2080,7 @@ static ConsoleDocFragment _ActionMapbind2(
DefineEngineStringlyVariadicMethod( ActionMap, bind, bool, 5, 10, "actionMap.bind( device, action, [modifier, spec, mod...], command )" DefineEngineStringlyVariadicMethod( ActionMap, bind, bool, 5, 10, "actionMap.bind( device, action, [modifier, spec, mod...], command )"
"@hide") "@hide")
{ {
StringStackWrapper args(argc - 2, argv + 2); ConsoleValueToStringArrayWrapper args(argc - 2, argv + 2);
return object->processBind( args.count(), args, NULL ); return object->processBind( args.count(), args, NULL );
} }
@ -2136,7 +2136,7 @@ DefineEngineStringlyVariadicMethod( ActionMap, bindObj, bool, 6, 11, "(device, a
return false; return false;
} }
StringStackWrapper args(argc - 3, argv + 2); ConsoleValueToStringArrayWrapper args(argc - 3, argv + 2);
return object->processBind( args.count(), args, simObject ); return object->processBind( args.count(), args, simObject );
} }

View file

@ -143,6 +143,7 @@ function parseMissionGroupForIds( %className, %childGroup )
if(!isObject(%currentGroup)) if(!isObject(%currentGroup))
return ""; return "";
%classIds = "";
for(%i = 0; %i < (%currentGroup).getCount(); %i++) for(%i = 0; %i < (%currentGroup).getCount(); %i++)
{ {
if( (%currentGroup).getObject(%i).getClassName() $= %className ) if( (%currentGroup).getObject(%i).getClassName() $= %className )

View file

@ -193,6 +193,9 @@ function resetMission()
clearServerPaths(); clearServerPaths();
// TODO: Is this right?
%client = ClientGroup.getObject(0);
// Inform the game code we're resetting. // Inform the game code we're resetting.
%hasGameMode = callGamemodeFunction("onMissionReset", %client); %hasGameMode = callGamemodeFunction("onMissionReset", %client);
} }

View file

@ -1,5 +1,5 @@
//--- OBJECT WRITE BEGIN --- //--- OBJECT WRITE BEGIN ---
%guiContent = new GuiControl(ConsoleDlg) { $guiContent = new GuiControl(ConsoleDlg) {
position = "0 0"; position = "0 0";
extent = "1024 768"; extent = "1024 768";
minExtent = "8 8"; minExtent = "8 8";

View file

@ -62,7 +62,7 @@ function ConsoleEntry::eval()
&& !startsWith(%text, "for(") && !startsWith(%text, "for(")
&& !startsWith(%text, "switch(") && !startsWith(%text, "switch(")
&& !startsWith(%text, "switch$(")) && !startsWith(%text, "switch$("))
eval("%result = " @ %text); %result = eval("return" SPC %text);
else else
eval(%text); eval(%text);
$Con::warnVoidAssignment = %oldWarnVoidAssignment; $Con::warnVoidAssignment = %oldWarnVoidAssignment;

View file

@ -75,7 +75,7 @@ singleton shaderData( AL_VectorLightShader )
pixVersion = 3.0; pixVersion = 3.0;
}; };
new CustomMaterial( AL_VectorLightMaterial ) singleton CustomMaterial( AL_VectorLightMaterial )
{ {
shader = AL_VectorLightShader; shader = AL_VectorLightShader;
stateBlock = AL_VectorLightState; stateBlock = AL_VectorLightState;
@ -149,7 +149,7 @@ singleton shaderData( AL_PointLightShader )
pixVersion = 3.0; pixVersion = 3.0;
}; };
new CustomMaterial( AL_PointLightMaterial ) singleton CustomMaterial( AL_PointLightMaterial )
{ {
shader = AL_PointLightShader; shader = AL_PointLightShader;
stateBlock = AL_ConvexLightState; stateBlock = AL_ConvexLightState;
@ -186,7 +186,7 @@ singleton shaderData( AL_SpotLightShader )
pixVersion = 3.0; pixVersion = 3.0;
}; };
new CustomMaterial( AL_SpotLightMaterial ) singleton CustomMaterial( AL_SpotLightMaterial )
{ {
shader = AL_SpotLightShader; shader = AL_SpotLightShader;
stateBlock = AL_ConvexLightState; stateBlock = AL_ConvexLightState;
@ -205,7 +205,7 @@ new CustomMaterial( AL_SpotLightMaterial )
/// This material is used for generating deferred /// This material is used for generating deferred
/// materials for objects that do not have materials. /// materials for objects that do not have materials.
new Material( AL_DefaultDeferredMaterial ) singleton Material( AL_DefaultDeferredMaterial )
{ {
// We need something in the first pass else it // We need something in the first pass else it
// won't create a proper material instance. // won't create a proper material instance.
@ -219,7 +219,7 @@ new Material( AL_DefaultDeferredMaterial )
/// This material is used for generating shadow /// This material is used for generating shadow
/// materials for objects that do not have materials. /// materials for objects that do not have materials.
new Material( AL_DefaultShadowMaterial ) singleton Material( AL_DefaultShadowMaterial )
{ {
// We need something in the first pass else it // We need something in the first pass else it
// won't create a proper material instance. // won't create a proper material instance.
@ -255,7 +255,7 @@ singleton shaderData( AL_ParticlePointLightShader )
pixVersion = 3.0; pixVersion = 3.0;
}; };
new CustomMaterial( AL_ParticlePointLightMaterial ) singleton CustomMaterial( AL_ParticlePointLightMaterial )
{ {
shader = AL_ParticlePointLightShader; shader = AL_ParticlePointLightShader;
stateBlock = AL_ConvexLightState; stateBlock = AL_ConvexLightState;

View file

@ -59,7 +59,7 @@ function PostFXManager::loadPresetFile()
{ {
//Show the dialog and set the flag //Show the dialog and set the flag
getLoadFilename($PostFXManager::fileFilter, "PostFXManager::loadPresetHandler"); getLoadFilename($PostFXManager::fileFilter, "PostFXManager::loadPresetHandler");
$PostFXManager::currentPreset = $Tools::FileDialogs::LastFilePath(); $PostFXManager::currentPreset = $Tools::FileDialogs::LastFilePath;
} }
function PostFXManager::loadPresetHandler( %filename ) function PostFXManager::loadPresetHandler( %filename )

View file

@ -1,4 +1,4 @@
new TerrainMaterial() singleton TerrainMaterial()
{ {
diffuseSize = "200"; diffuseSize = "200";
detailSize = "10"; detailSize = "10";

View file

@ -15,7 +15,7 @@ function findGameObject(%name)
//%assetName = AssetDatabase.getAssetName(%assetId); //%assetName = AssetDatabase.getAssetName(%assetId);
if(%assetId $= %name) if(%assetId $= %name)
{ {
%gameObjectAsset = AssetDatabase.acquireAsset(%assetId); %gameObjectAsset = AssetDatabase.acquireAsset(%assetId);
@ -47,7 +47,7 @@ function spawnGameObject(%name, %addToScene)
%go.setHidden(false); %go.setHidden(false);
%go.setScopeAlways(); %go.setScopeAlways();
if(%addToMissionGroup == true) //save instance when saving level if(%addToScene == true) //save instance when saving level
getScene(0).add(%go); getScene(0).add(%go);
else // clear instance on level exit else // clear instance on level exit
MissionCleanup.add(%go); MissionCleanup.add(%go);

View file

@ -524,7 +524,9 @@ function loadDir(%dir)
function loadDirs(%dirPath) function loadDirs(%dirPath)
{ {
%dirPath = nextToken(%dirPath, token, ";"); %dirPath = nextToken(%dirPath, "$token", ";");
%token = $token;
if (%dirPath !$= "") if (%dirPath !$= "")
loadDirs(%dirPath); loadDirs(%dirPath);

View file

@ -43,11 +43,11 @@ function popFront(%list, %delim)
function parseArgs() function parseArgs()
{ {
for ($i = 1; $i < $Game::argc ; $i++) for (%i = 1; %i < $Game::argc ; %i++)
{ {
$arg = $Game::argv[$i]; $arg = $Game::argv[%i];
$nextArg = $Game::argv[$i+1]; $nextArg = $Game::argv[%i+1];
$hasNextArg = $Game::argc - $i > 1; $hasNextArg = $Game::argc - %i > 1;
$logModeSpecified = false; $logModeSpecified = false;
// Check for dedicated run // Check for dedicated run
@ -55,7 +55,7 @@ function parseArgs()
{ {
$userDirs = $defaultGame; $userDirs = $defaultGame;
$dirCount = 1; $dirCount = 1;
$isDedicated = true; %isDedicated = true;
}*/ }*/
switch$ ($arg) switch$ ($arg)
@ -64,7 +64,7 @@ function parseArgs()
case "-dedicated": case "-dedicated":
$userDirs = $defaultGame; $userDirs = $defaultGame;
$dirCount = 1; $dirCount = 1;
$isDedicated = true; %isDedicated = true;
$Server::Dedicated = true; $Server::Dedicated = true;
enableWinConsole(true); enableWinConsole(true);
$argUsed[%i]++; $argUsed[%i]++;
@ -96,7 +96,7 @@ function parseArgs()
//-------------------- //--------------------
case "-log": case "-log":
$argUsed[$i]++; $argUsed[%i]++;
if ($hasNextArg) if ($hasNextArg)
{ {
// Turn on console logging // Turn on console logging
@ -107,22 +107,22 @@ function parseArgs()
} }
setLogMode($nextArg); setLogMode($nextArg);
$logModeSpecified = true; $logModeSpecified = true;
$argUsed[$i+1]++; $argUsed[%i+1]++;
$i++; %i++;
} }
else else
error("Error: Missing Command Line argument. Usage: -log <Mode: 0,1,2>"); error("Error: Missing Command Line argument. Usage: -log <Mode: 0,1,2>");
//-------------------- //--------------------
case "-dir": case "-dir":
$argUsed[$i]++; $argUsed[%i]++;
if ($hasNextArg) if ($hasNextArg)
{ {
// Append the mod to the end of the current list // Append the mod to the end of the current list
$userDirs = strreplace($userDirs, $nextArg, ""); $userDirs = strreplace($userDirs, $nextArg, "");
$userDirs = pushFront($userDirs, $nextArg, ";"); $userDirs = pushFront($userDirs, $nextArg, ";");
$argUsed[$i+1]++; $argUsed[%i+1]++;
$i++; %i++;
$dirCount++; $dirCount++;
} }
else else
@ -133,12 +133,12 @@ function parseArgs()
// defaults to ONLY loading the game, not tools // defaults to ONLY loading the game, not tools
// default auto-run already loads in tools --SRZ 11/29/07 // default auto-run already loads in tools --SRZ 11/29/07
case "-game": case "-game":
$argUsed[$i]++; $argUsed[%i]++;
if ($hasNextArg) if ($hasNextArg)
{ {
// Set the selected dir --NOTE: we no longer allow tools with this argument // Set the selected dir --NOTE: we no longer allow tools with this argument
/* /*
if( $isDedicated ) if( %isDedicated )
{ {
$userDirs = $nextArg; $userDirs = $nextArg;
$dirCount = 1; $dirCount = 1;
@ -151,8 +151,8 @@ function parseArgs()
*/ */
$userDirs = $nextArg; $userDirs = $nextArg;
$dirCount = 1; $dirCount = 1;
$argUsed[$i+1]++; $argUsed[%i+1]++;
$i++; %i++;
error($userDirs); error($userDirs);
} }
else else
@ -161,109 +161,109 @@ function parseArgs()
//-------------------- //--------------------
case "-console": case "-console":
enableWinConsole(true); enableWinConsole(true);
$argUsed[$i]++; $argUsed[%i]++;
//-------------------- //--------------------
case "-jSave": case "-jSave":
$argUsed[$i]++; $argUsed[%i]++;
if ($hasNextArg) if ($hasNextArg)
{ {
echo("Saving event log to journal: " @ $nextArg); echo("Saving event log to journal: " @ $nextArg);
saveJournal($nextArg); saveJournal($nextArg);
$argUsed[$i+1]++; $argUsed[%i+1]++;
$i++; %i++;
} }
else else
error("Error: Missing Command Line argument. Usage: -jSave <journal_name>"); error("Error: Missing Command Line argument. Usage: -jSave <journal_name>");
//-------------------- //--------------------
case "-jPlay": case "-jPlay":
$argUsed[$i]++; $argUsed[%i]++;
if ($hasNextArg) if ($hasNextArg)
{ {
playJournal($nextArg); playJournal($nextArg);
$argUsed[$i+1]++; $argUsed[%i+1]++;
$i++; %i++;
} }
else else
error("Error: Missing Command Line argument. Usage: -jPlay <journal_name>"); error("Error: Missing Command Line argument. Usage: -jPlay <journal_name>");
//-------------------- //--------------------
case "-jPlayToVideo": case "-jPlayToVideo":
$argUsed[$i]++; $argUsed[%i]++;
if ($hasNextArg) if ($hasNextArg)
{ {
$VideoCapture::journalName = $nextArg; $VideoCapture::journalName = $nextArg;
$VideoCapture::captureFromJournal = true; $VideoCapture::captureFromJournal = true;
$argUsed[$i+1]++; $argUsed[%i+1]++;
$i++; %i++;
} }
else else
error("Error: Missing Command Line argument. Usage: -jPlayToVideo <journal_name>"); error("Error: Missing Command Line argument. Usage: -jPlayToVideo <journal_name>");
//-------------------- //--------------------
case "-vidCapFile": case "-vidCapFile":
$argUsed[$i]++; $argUsed[%i]++;
if ($hasNextArg) if ($hasNextArg)
{ {
$VideoCapture::fileName = $nextArg; $VideoCapture::fileName = $nextArg;
$argUsed[$i+1]++; $argUsed[%i+1]++;
$i++; %i++;
} }
else else
error("Error: Missing Command Line argument. Usage: -vidCapFile <ouput_video_name>"); error("Error: Missing Command Line argument. Usage: -vidCapFile <ouput_video_name>");
//-------------------- //--------------------
case "-vidCapFPS": case "-vidCapFPS":
$argUsed[$i]++; $argUsed[%i]++;
if ($hasNextArg) if ($hasNextArg)
{ {
$VideoCapture::fps = $nextArg; $VideoCapture::fps = $nextArg;
$argUsed[$i+1]++; $argUsed[%i+1]++;
$i++; %i++;
} }
else else
error("Error: Missing Command Line argument. Usage: -vidCapFPS <ouput_video_framerate>"); error("Error: Missing Command Line argument. Usage: -vidCapFPS <ouput_video_framerate>");
//-------------------- //--------------------
case "-vidCapEncoder": case "-vidCapEncoder":
$argUsed[$i]++; $argUsed[%i]++;
if ($hasNextArg) if ($hasNextArg)
{ {
$VideoCapture::encoder = $nextArg; $VideoCapture::encoder = $nextArg;
$argUsed[$i+1]++; $argUsed[%i+1]++;
$i++; %i++;
} }
else else
error("Error: Missing Command Line argument. Usage: -vidCapEncoder <ouput_video_encoder>"); error("Error: Missing Command Line argument. Usage: -vidCapEncoder <ouput_video_encoder>");
//-------------------- //--------------------
case "-vidCapWidth": case "-vidCapWidth":
$argUsed[$i]++; $argUsed[%i]++;
if ($hasNextArg) if ($hasNextArg)
{ {
$videoCapture::width = $nextArg; $videoCapture::width = $nextArg;
$argUsed[$i+1]++; $argUsed[%i+1]++;
$i++; %i++;
} }
else else
error("Error: Missing Command Line argument. Usage: -vidCapWidth <ouput_video_width>"); error("Error: Missing Command Line argument. Usage: -vidCapWidth <ouput_video_width>");
//-------------------- //--------------------
case "-vidCapHeight": case "-vidCapHeight":
$argUsed[$i]++; $argUsed[%i]++;
if ($hasNextArg) if ($hasNextArg)
{ {
$videoCapture::height = $nextArg; $videoCapture::height = $nextArg;
$argUsed[$i+1]++; $argUsed[%i+1]++;
$i++; %i++;
} }
else else
error("Error: Missing Command Line argument. Usage: -vidCapHeight <ouput_video_height>"); error("Error: Missing Command Line argument. Usage: -vidCapHeight <ouput_video_height>");
//-------------------- //--------------------
case "-level": case "-level":
$argUsed[$i]++; $argUsed[%i]++;
if ($hasNextArg) if ($hasNextArg)
{ {
%hasExt = strpos($nextArg, ".mis"); %hasExt = strpos($nextArg, ".mis");
@ -271,9 +271,9 @@ function parseArgs()
{ {
$levelToLoad = $nextArg @ " "; $levelToLoad = $nextArg @ " ";
for(%i = $i + 2; %i < $Game::argc; %i++) for(%j = %i + 2; %j < $Game::argc; %j++)
{ {
$arg = $Game::argv[%i]; $arg = $Game::argv[%j];
%hasExt = strpos($arg, ".mis"); %hasExt = strpos($arg, ".mis");
if(%hasExt == -1) if(%hasExt == -1)
@ -291,8 +291,8 @@ function parseArgs()
$levelToLoad = $nextArg; $levelToLoad = $nextArg;
} }
$argUsed[$i+1]++; $argUsed[%i+1]++;
$i++; %i++;
} }
else else
error("Error: Missing Command Line argument. Usage: -level <level file name (no path), with or without extension>"); error("Error: Missing Command Line argument. Usage: -level <level file name (no path), with or without extension>");
@ -300,32 +300,32 @@ function parseArgs()
//------------------- //-------------------
case "-worldeditor": case "-worldeditor":
$startWorldEditor = true; $startWorldEditor = true;
$argUsed[$i]++; $argUsed[%i]++;
//------------------- //-------------------
case "-guieditor": case "-guieditor":
$startGUIEditor = true; $startGUIEditor = true;
$argUsed[$i]++; $argUsed[%i]++;
//------------------- //-------------------
case "-help": case "-help":
$displayHelp = true; $displayHelp = true;
$argUsed[$i]++; $argUsed[%i]++;
//------------------- //-------------------
case "-compileAll": case "-compileAll":
$compileAll = true; $compileAll = true;
$argUsed[$i]++; $argUsed[%i]++;
//------------------- //-------------------
case "-compileTools": case "-compileTools":
$compileTools = true; $compileTools = true;
$argUsed[$i]++; $argUsed[%i]++;
//------------------- //-------------------
case "-genScript": case "-genScript":
$genScript = true; $genScript = true;
$argUsed[$i]++; $argUsed[%i]++;
case "-fullscreen": case "-fullscreen":
$cliFullscreen = true; $cliFullscreen = true;
@ -360,7 +360,7 @@ function parseArgs()
//------------------- //-------------------
default: default:
$argUsed[$i]++; $argUsed[%i]++;
if($userDirs $= "") if($userDirs $= "")
$userDirs = $arg; $userDirs = $arg;
} }

View file

@ -1,8 +1,5 @@
function callGamemodeFunction(%gameModeFuncName, %arg0, %arg1, %arg2, %arg3, %arg4, %arg5, %arg6) function callGamemodeFunction(%gameModeFuncName, %arg0, %arg1, %arg2, %arg3, %arg4, %arg5, %arg6)
{ {
if(%data !$= "")
%data = "\""@%data@"\"";
%activeSceneCount = getSceneCount(); %activeSceneCount = getSceneCount();
%hasGameMode = 0; %hasGameMode = 0;

View file

@ -1,5 +1,5 @@
//--- OBJECT WRITE BEGIN --- //--- OBJECT WRITE BEGIN ---
%guiContent = new GuiControl(ExampleGUI) $guiContent = new GuiControl(ExampleGUI)
{ {
position = "0 0"; position = "0 0";
extent = "100 100"; extent = "100 100";

View file

@ -1,5 +1,5 @@
//--- OBJECT WRITE BEGIN --- //--- OBJECT WRITE BEGIN ---
%guiContent = new GuiControl(IODropdownDlg) { $guiContent = new GuiControl(IODropdownDlg) {
profile = "GuiDefaultProfile"; profile = "GuiDefaultProfile";
horizSizing = "width"; horizSizing = "width";
vertSizing = "height"; vertSizing = "height";

Some files were not shown because too many files have changed in this diff Show more