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"
#endif
#ifndef _SFXSOURCE_H_
#include "sfx/sfxSource.h"
#endif
// Debug Profiling.
#include "platform/profiler.h"
#include "sfx/sfxTypes.h"
@ -159,7 +163,7 @@ void SoundAsset::initPersistFields()
addField("maxDistance", TypeF32, Offset(mProfileDesc.mMaxDistance, SoundAsset), "Max distance for sound.");
addField("coneInsideAngle", TypeS32, Offset(mProfileDesc.mConeInsideAngle, SoundAsset), "Cone inside 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("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.");
@ -181,13 +185,7 @@ void SoundAsset::initializeAsset(void)
if (mSoundFile == StringTable->EmptyString())
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 = expandAssetFilePath(mSoundPath);
loadSound();
}
@ -208,7 +206,6 @@ void SoundAsset::onAssetRefresh(void)
//Update
mSoundPath = getOwned() ? expandAssetFilePath(mSoundFile) : mSoundPath;
loadSound();
}
@ -225,7 +222,7 @@ bool SoundAsset::loadSound()
else
{// = new SFXProfile(mProfileDesc, mSoundFile, mPreload);
mSFXProfile.setDescription(&mProfileDesc);
mSFXProfile.setSoundFileName(mSoundFile);
mSFXProfile.setSoundFileName(mSoundPath);
mSFXProfile.setPreload(mPreload);
}
@ -254,11 +251,106 @@ void SoundAsset::setSoundFile(const char* pSoundFile)
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*, (), , "")
{
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);
ConsoleDocClass(GuiInspectorTypeSoundAssetPtr,
@ -276,12 +368,63 @@ void GuiInspectorTypeSoundAssetPtr::consoleInit()
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()
{
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);

View file

@ -122,6 +122,9 @@ public:
bool isLoop() { return mProfileDesc.mIsLooping; }
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:
virtual void initializeAsset(void);
@ -143,7 +146,7 @@ class GuiInspectorTypeSoundAssetPtr : public GuiInspectorTypeFileName
typedef GuiInspectorTypeFileName Parent;
public:
GuiBitmapButtonCtrl* mSoundButton;
GuiBitmapButtonCtrl* mEditButton;
DECLARE_CONOBJECT(GuiInspectorTypeSoundAssetPtr);
static void consoleInit();
@ -168,14 +171,14 @@ public:
/// Declares a sound asset
/// This establishes the assetId, asset and legacy filepath fields, along with supplemental getter and setter functions
/// </Summary>
#define DECLARE_SOUNDASSET(className, name, profile) public: \
#define DECLARE_SOUNDASSET(className, name) public: \
Resource<SFXResource> m##name;\
StringTableEntry m##name##Name; \
StringTableEntry m##name##AssetId;\
AssetPtr<SoundAsset> m##name##Asset = NULL;\
SFXProfile* m##name##Profile = &profile;\
SFXProfile* m##name##Profile = NULL;\
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());}\
const AssetPtr<SoundAsset> & get##name##Asset() const { return m##name##Asset; }\
void set##name##Asset(const AssetPtr<SoundAsset> &_in) { m##name##Asset = _in;}\
@ -206,7 +209,7 @@ public: \
}\
else\
{\
StringTableEntry assetId = SoundAsset::getAssetIdByFilename(_in);\
StringTableEntry assetId = SoundAsset::getAssetIdByFileName(_in);\
if (assetId != StringTable->EmptyString())\
{\
m##name##AssetId = assetId;\
@ -232,9 +235,9 @@ public: \
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; \
}\
else if (m##name)\

View file

@ -1382,32 +1382,32 @@ void AssetImporter::processImportAssets(AssetImportObject* assetItem)
if (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"))
{
processImageAsset(item);
}
else if (item->assetType == String("ShapeAsset"))
{
processShapeAsset(item);
}
/*else if (item->assetType == String("SoundAsset"))
SoundAsset::prepareAssetForImport(this, item);*/
else if (item->assetType == String("MaterialAsset"))
{
processMaterialAsset(item);
}
/*else if (item->assetType == String("ShapeAnimationAsset"))
ShapeAnimationAsset::prepareAssetForImport(this, item);*/
else
{
String processCommand = "process";
processCommand += item->assetType;
if(isMethod(processCommand.c_str()))
Con::executef(this, processCommand.c_str(), item);
}
//process the asset items
if (item->assetType == String("ImageAsset"))
{
processImageAsset(item);
}
else if (item->assetType == String("ShapeAsset"))
{
processShapeAsset(item);
}
else if (item->assetType == String("SoundAsset"))
{
processSoundAsset(item);
}
else if (item->assetType == String("MaterialAsset"))
{
processMaterialAsset(item);
}
/*else if (item->assetType == String("ShapeAnimationAsset"))
ShapeAnimationAsset::prepareAssetForImport(this, item);*/
else
{
String processCommand = "process";
processCommand += item->assetType;
if(isMethod(processCommand.c_str()))
Con::executef(this, processCommand.c_str(), item);
}
item->importStatus == AssetImportObject::Processed;
@ -1975,93 +1975,12 @@ void AssetImporter::processShapeMaterialInfo(AssetImportObject* assetItem, S32 m
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);
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;
}
//
// Validation
//
@ -2514,6 +2433,8 @@ void AssetImporter::importAssets(AssetImportObject* assetItem)
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());
activityLog.push_back(importLogBuffer);
}

View file

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

View file

@ -94,22 +94,23 @@ ColorI SFXEmitter::smRenderColorRangeSphere( 200, 0, 0, 90 );
SFXEmitter::SFXEmitter()
: SceneObject(),
mSource( NULL ),
mTrack( NULL ),
mUseTrackDescriptionOnly( false ),
mLocalProfile( &mDescription ),
mPlayOnAdd( true )
{
mTypeMask |= MarkerObjectType;
mNetFlags.set( Ghostable | ScopeAlways );
mDescription.mIs3D = true;
mDescription.mIsLooping = true;
mDescription.mIsStreaming = false;
mDescription.mFadeInTime = -1.f;
mDescription.mFadeOutTime = -1.f;
mLocalProfile.mFilename = StringTable->EmptyString();
mLocalProfile._registerSignals();
INIT_SOUNDASSET(Sound);
mObjBox.minExtents.set( -1.f, -1.f, -1.f );
mObjBox.maxExtents.set( 1.f, 1.f, 1.f );
}
@ -174,15 +175,17 @@ void SFXEmitter::consoleInit()
void SFXEmitter::initPersistFields()
{
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"
"@note If assigned, this field will take precedence over a #fileName that may also be assigned to the "
"emitter." );
addField( "fileName", TypeStringFilename, Offset( mLocalProfile.mFilename, SFXEmitter),
"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 "
"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");
@ -287,12 +290,13 @@ U32 SFXEmitter::packUpdate( NetConnection *con, U32 mask, BitStream *stream )
stream->writeAffineTransform( mObjToWorld );
// track
if( stream->writeFlag( mDirty.test( Track ) ) )
sfxWrite( stream, mTrack );
PACK_SOUNDASSET(con, Sound);
//if (stream->writeFlag(mDirty.test(Track)))
// sfxWrite( stream, mTrack );
// filename
if( stream->writeFlag( mDirty.test( Filename ) ) )
stream->writeString( mLocalProfile.mFilename );
//if( stream->writeFlag( mDirty.test( Filename ) ) )
// stream->writeString( mLocalProfile.mFilename );
// volume
if( stream->writeFlag( mDirty.test( Volume ) ) )
@ -397,7 +401,8 @@ void SFXEmitter::unpackUpdate( NetConnection *conn, BitStream *stream )
}
// track
if ( _readDirtyFlag( stream, Track ) )
UNPACK_SOUNDASSET(conn, Sound);
/*if (_readDirtyFlag(stream, Track))
{
String errorStr;
if( !sfxReadAndResolve( stream, &mTrack, errorStr ) )
@ -406,7 +411,7 @@ void SFXEmitter::unpackUpdate( NetConnection *conn, BitStream *stream )
// filename
if ( _readDirtyFlag( stream, Filename ) )
mLocalProfile.mFilename = stream->readSTString();
mLocalProfile.mFilename = stream->readSTString();*/
// volume
if ( _readDirtyFlag( stream, Volume ) )
@ -586,8 +591,8 @@ void SFXEmitter::inspectPostApply()
// Parent will call setScale so sync up scale with distance.
F32 maxDistance = mDescription.mMaxDistance;
if( mUseTrackDescriptionOnly && mTrack )
maxDistance = mTrack->getDescription()->mMaxDistance;
if( mUseTrackDescriptionOnly && mSoundAsset )
maxDistance = mSoundAsset->getSfxDescription()->mMaxDistance;
mObjScale.set( maxDistance, maxDistance, maxDistance );
@ -608,8 +613,8 @@ bool SFXEmitter::onAdd()
mDescription.validate();
// Read an old 'profile' field for backwards-compatibility.
if( !mTrack )
/*
if(mSoundAsset.isNull() || !mSoundAsset->getSfxProfile())
{
static const char* sProfile = StringTable->insert( "profile" );
const char* profileName = getDataField( sProfile, NULL );
@ -643,7 +648,7 @@ bool SFXEmitter::onAdd()
// Remove the old 'channel' field.
setDataField( sChannel, NULL, "" );
}
}
}*/
}
else
{
@ -683,6 +688,12 @@ void SFXEmitter::_update()
// we can restore it.
SFXStatus prevState = mSource ? mSource->getStatus() : SFXStatusNull;
if (mSoundAsset.notNull() )
{
mLocalProfile = *mSoundAsset->getSfxProfile();
mDescription = *mSoundAsset->getSfxDescription();
}
// Make sure all the settings are valid.
mDescription.validate();
@ -695,12 +706,12 @@ void SFXEmitter::_update()
SFX_DELETE( mSource );
// 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 )
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
// 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
// editor feel responsive and that things are working.
if( gEditingMission &&
!mTrack &&
(mSoundAsset.isNull() || !mSoundAsset->getSfxProfile()) &&
mPlayOnAdd &&
mDirty.test( IsLooping ) )
prevState = SFXStatusPlaying;
bool useTrackDescriptionOnly = ( mUseTrackDescriptionOnly && mTrack );
bool useTrackDescriptionOnly = ( mUseTrackDescriptionOnly && mSoundAsset.notNull() && mSoundAsset->getSfxProfile());
// The rest only applies if we have a source.
if( mSource )
@ -1087,8 +1098,8 @@ SFXStatus SFXEmitter::_getPlaybackStatus() const
bool SFXEmitter::is3D() const
{
if( mTrack != NULL )
return mTrack->getDescription()->mIs3D;
if( mSoundAsset.notNull() && mSoundAsset->getSfxProfile() != NULL )
return mSoundAsset->getSfxProfile()->getDescription()->mIs3D;
else
return mDescription.mIs3D;
}
@ -1124,8 +1135,8 @@ void SFXEmitter::setScale( const VectorF &scale )
{
F32 maxDistance;
if( mUseTrackDescriptionOnly && mTrack )
maxDistance = mTrack->getDescription()->mMaxDistance;
if( mUseTrackDescriptionOnly && mSoundAsset.notNull() && mSoundAsset->getSfxProfile())
maxDistance = mSoundAsset->getSfxProfile()->getDescription()->mMaxDistance;
else
{
// Use the average of the three coords.

View file

@ -36,6 +36,7 @@
#include "gfx/gfxStateBlock.h"
#endif
#include "T3D/assets/SoundAsset.h"
class SFXSource;
class SFXTrack;
@ -103,13 +104,11 @@ class SFXEmitter : public SceneObject
/// The current dirty flags.
BitSet32 mDirty;
DECLARE_SOUNDASSET(SFXEmitter, Sound);
DECLARE_SOUNDASSET_NET_SETGET(SFXEmitter, Sound, DirtyUpdateMask);
/// The sound source for the emitter.
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
/// override part of the track's description with emitter properties.
bool mUseTrackDescriptionOnly;

View file

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

View file

@ -2638,23 +2638,25 @@ DefineEngineStringlyVariadicMethod(afxMagicSpell, setTimeFactor, void, 3, 4, "(F
"@ingroup AFX")
{
if (argc == 3)
object->setTimeFactor(dAtof(argv[2]));
object->setTimeFactor(argv[2].getFloat());
else
{
F32 value = argv[3].getFloat();
if (dStricmp(argv[2], "overall") == 0)
object->setTimeFactor(dAtof(argv[3]));
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)
object->setTimeFactor(afxMagicSpell::LAUNCH_PHRASE, dAtof(argv[3]));
object->setTimeFactor(afxMagicSpell::LAUNCH_PHRASE, value);
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)
object->setTimeFactor(afxMagicSpell::IMPACT_PHRASE, dAtof(argv[3]));
object->setTimeFactor(afxMagicSpell::IMPACT_PHRASE, value);
else if (dStricmp(argv[2], "linger") == 0)
object->setTimeFactor(afxMagicSpell::LINGER_PHRASE, dAtof(argv[3]));
object->setTimeFactor(afxMagicSpell::LINGER_PHRASE, value);
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)
const char* result = Con::executef(datablock, "onPreactivate",
Con::getIntArg(param_holder->getId()),
(extra) ? Con::getIntArg(extra->getId()) : "");
(extra) ? Con::getIntArg(extra->getId()) : "").getString();
if (result && result[0] != '\0' && !dAtob(result))
{
#if defined(TORQUE_DEBUG)

View file

@ -874,7 +874,7 @@ DefineEngineStringlyVariadicFunction(echoThru, const char*, 2, 0, "(string passt
for (i = 2; i < argc; i++)
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;
return argv[1];
@ -894,7 +894,7 @@ DefineEngineStringlyVariadicFunction(warnThru, const char*, 2, 0, "(string passt
for(i = 2; i < argc; i++)
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;
return argv[1];
@ -914,7 +914,7 @@ DefineEngineStringlyVariadicFunction(errorThru, const char*, 2, 0, "(string pass
for(i = 2; i < argc; i++)
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;
return argv[1];

View file

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

View file

@ -254,7 +254,7 @@ DefineEngineStringlyVariadicFunction( commandToServer, void, 2, RemoteCommandEve
NetConnection *conn = NetConnection::getConnectionToServer();
if(!conn)
return;
StringStackWrapper args(argc - 1, argv + 1);
ConsoleValueToStringArrayWrapper args(argc - 1, argv + 1);
RemoteCommandEvent::sendRemoteCommand(conn, args.count(), args);
}
@ -292,7 +292,7 @@ DefineEngineStringlyVariadicFunction( commandToClient, void, 3, RemoteCommandEve
NetConnection *conn;
if(!Sim::findObject(argv[1], conn))
return;
StringStackWrapper args(argc - 2, argv + 2);
ConsoleValueToStringArrayWrapper args(argc - 2, argv + 2);
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)
return true;
else if(argc == 1)
{
addToTable(NetSocket::fromHandle(dAtoi(argv[0])));
addToTable(NetSocket::fromHandle(argv[0].getInt()));
return true;
}
return false;

View file

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

View file

@ -55,7 +55,7 @@ bool CInterface::_isMethod(const char* className, const char* methodName) const
if (mIsMethodCallback)
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
@ -93,4 +93,4 @@ TORQUE_API void SetCallbacks(void* ptr, void* methodPtr, void* isMethodPtr, void
CInterface::GetCInterface().SetCallMethodCallback(methodPtr);
CInterface::GetCInterface().SetCallIsMethodCallback(isMethodPtr);
CInterface::GetCInterface().SetMainCallback(mainPtr);
}
}

View file

@ -456,6 +456,8 @@ expr
{ $$ = (ExprNode*)VarNode::alloc( $1.lineNumber, $1.value, NULL); }
| VAR '[' aidx_expr ']'
{ $$ = (ExprNode*)VarNode::alloc( $1.lineNumber, $1.value, $3 ); }
;
/*
| rwDEFINE '(' var_list_decl ')' '{' statement_list '}'
{
const U32 bufLen = 64;
@ -471,7 +473,7 @@ expr
$$ = StrConstNode::alloc( $1.lineNumber, (UTF8*)fName, false );
}
;
*/
slot_acc
: expr '.' IDENT
@ -551,9 +553,12 @@ funcall_expr
{ $$ = FuncCallExprNode::alloc( $1.lineNumber, $3.value, $1.value, $5, false); }
| expr '.' IDENT '(' expr_list_decl ')'
{ $1->append($5); $$ = FuncCallExprNode::alloc( $1->dbgLineNumber, $3.value, NULL, $1, true); }
;
/*
| expr '(' expr_list_decl ')'
{ $$ = FuncPointerCallExprNode::alloc( $1->dbgLineNumber, $1, $3); }
;
*/
assert_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; }
"false" { CMDlval.i = MakeToken< int >( 0, lineIndex ); return INTCONST; }
{VAR} { return(Sc_ScanVar()); }
{ID} { return Sc_ScanIdent(); }
0[xX]{HEXDIGIT}+ return(Sc_ScanHex());
{INTEGER} { CMDtext[CMDleng] = 0; CMDlval.i = MakeToken< int >( dAtoi(CMDtext), lineIndex ); return INTCONST; }

View file

@ -27,7 +27,7 @@ class ICallMethod
{
public:
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.
// -----------------------------------------------------------------------------
bool SimXMLDocument::processArguments(S32 argc, ConsoleValueRef *argv)
bool SimXMLDocument::processArguments(S32 argc, ConsoleValue *argv)
{
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
// comments on these.
//-----------------------------------------------------------------------
bool processArguments(S32 argc, ConsoleValueRef *argv);
bool processArguments(S32 argc, ConsoleValue *argv);
bool onAdd();
void onRemove();
static void initPersistFields();

View file

@ -39,8 +39,15 @@ enum TypeReq
TypeReqNone,
TypeReqUInt,
TypeReqFloat,
TypeReqString,
TypeReqVar
TypeReqString
};
enum ExprNodeName
{
NameExprNode,
NameFloatNode,
NameIntNode,
NameVarNode
};
/// Representation of a node for the scripting language parser.
@ -52,7 +59,7 @@ enum TypeReq
/// each representing a different language construct.
struct StmtNode
{
StmtNode *mNext; ///< Next entry in parse tree.
StmtNode* next; ///< Next entry in parse tree.
StmtNode();
virtual ~StmtNode() {}
@ -61,8 +68,8 @@ struct StmtNode
/// @{
///
void append(StmtNode *next);
StmtNode *getNext() const { return mNext; }
void append(StmtNode* next);
StmtNode* getNext() const { return next; }
/// @}
@ -79,93 +86,95 @@ struct StmtNode
/// @name Breaking
/// @{
void addBreakLine(CodeStream &codeStream);
void addBreakLine(CodeStream& codeStream);
/// @}
/// @name Compilation
/// @{
virtual U32 compileStmt(CodeStream &codeStream, U32 ip) = 0;
virtual U32 compileStmt(CodeStream& codeStream, U32 ip) = 0;
virtual void setPackage(StringTableEntry packageName);
/// @}
};
/// Helper macro
#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
# define DBG_STMT_TYPE(s)
#endif
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);
};
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);
};
/// A mathematical expression.
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 ExprNodeName getExprNodeNameEnum() const { return NameExprNode; }
};
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);
};
struct IfStmtNode : StmtNode
{
ExprNode *testExpr;
StmtNode *ifBlock, *elseBlock;
ExprNode* testExpr;
StmtNode* ifBlock, * elseBlock;
U32 endifOffset;
U32 elseOffset;
bool integer;
bool propagate;
static IfStmtNode *alloc(S32 lineNumber, ExprNode *testExpr, StmtNode *ifBlock, StmtNode *elseBlock, bool propagateThrough);
void propagateSwitchExpr(ExprNode *left, bool string);
ExprNode *getSwitchOR(ExprNode *left, ExprNode *list, bool string);
static IfStmtNode* alloc(S32 lineNumber, ExprNode* testExpr, StmtNode* ifBlock, StmtNode* elseBlock, bool propagateThrough);
void propagateSwitchExpr(ExprNode* left, 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);
};
struct LoopStmtNode : StmtNode
{
ExprNode *testExpr;
ExprNode *initExpr;
ExprNode *endLoopExpr;
StmtNode *loopBlock;
ExprNode* testExpr;
ExprNode* initExpr;
ExprNode* endLoopExpr;
StmtNode* loopBlock;
bool isDoLoop;
U32 breakOffset;
U32 continueOffset;
U32 loopBlockStartOffset;
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);
};
@ -189,35 +198,38 @@ struct IterStmtNode : StmtNode
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).
struct BinaryExprNode : ExprNode
{
S32 op;
ExprNode *left;
ExprNode *right;
ExprNode* left;
ExprNode* right;
};
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();
DBG_STMT_TYPE(FloatBinaryExprNode);
};
struct ConditionalExprNode : ExprNode
{
ExprNode *testExpr;
ExprNode *trueExpr;
ExprNode *falseExpr;
ExprNode* testExpr;
ExprNode* trueExpr;
ExprNode* falseExpr;
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();
DBG_STMT_TYPE(ConditionalExprNode);
};
@ -227,11 +239,13 @@ struct IntBinaryExprNode : BinaryExprNode
TypeReq subType;
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();
U32 compile(CodeStream &codeStream, U32 ip, TypeReq type);
bool optimize();
U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
TypeReq getPreferredType();
DBG_STMT_TYPE(IntBinaryExprNode);
};
@ -239,9 +253,9 @@ struct IntBinaryExprNode : BinaryExprNode
struct StreqExprNode : BinaryExprNode
{
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();
DBG_STMT_TYPE(StreqExprNode);
};
@ -249,19 +263,19 @@ struct StreqExprNode : BinaryExprNode
struct StrcatExprNode : BinaryExprNode
{
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();
DBG_STMT_TYPE(StrcatExprNode);
};
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();
DBG_STMT_TYPE(CommaCatExprNode);
};
@ -269,12 +283,12 @@ struct CommaCatExprNode : BinaryExprNode
struct IntUnaryExprNode : ExprNode
{
S32 op;
ExprNode *expr;
ExprNode* expr;
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();
DBG_STMT_TYPE(IntUnaryExprNode);
};
@ -282,11 +296,11 @@ struct IntUnaryExprNode : ExprNode
struct FloatUnaryExprNode : ExprNode
{
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();
DBG_STMT_TYPE(FloatUnaryExprNode);
};
@ -294,12 +308,13 @@ struct FloatUnaryExprNode : ExprNode
struct VarNode : ExprNode
{
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();
virtual ExprNodeName getExprNodeNameEnum() const { return NameVarNode; }
DBG_STMT_TYPE(VarNode);
};
@ -308,10 +323,11 @@ struct IntNode : ExprNode
S32 value;
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();
virtual ExprNodeName getExprNodeNameEnum() const { return NameIntNode; }
DBG_STMT_TYPE(IntNode);
};
@ -320,24 +336,25 @@ struct FloatNode : ExprNode
F64 value;
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();
virtual ExprNodeName getExprNodeNameEnum() const { return NameFloatNode; }
DBG_STMT_TYPE(FloatNode);
};
struct StrConstNode : ExprNode
{
char *str;
char* str;
F64 fVal;
U32 index;
bool tag;
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();
DBG_STMT_TYPE(StrConstNode);
};
@ -348,9 +365,9 @@ struct ConstantNode : ExprNode
F64 fVal;
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();
DBG_STMT_TYPE(ConstantNode);
};
@ -358,13 +375,13 @@ struct ConstantNode : ExprNode
struct AssignExprNode : ExprNode
{
StringTableEntry varName;
ExprNode *expr;
ExprNode *arrayIndex;
ExprNode* expr;
ExprNode* arrayIndex;
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();
DBG_STMT_TYPE(AssignExprNode);
};
@ -373,22 +390,22 @@ struct AssignDecl
{
S32 lineNumber;
S32 token;
ExprNode *expr;
ExprNode* expr;
bool integer;
};
struct AssignOpExprNode : ExprNode
{
StringTableEntry varName;
ExprNode *expr;
ExprNode *arrayIndex;
ExprNode* expr;
ExprNode* arrayIndex;
S32 op;
U32 operand;
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();
DBG_STMT_TYPE(AssignOpExprNode);
};
@ -396,22 +413,22 @@ struct AssignOpExprNode : ExprNode
struct TTagSetStmtNode : StmtNode
{
StringTableEntry tag;
ExprNode *valueExpr;
ExprNode *stringExpr;
ExprNode* valueExpr;
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);
};
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();
DBG_STMT_TYPE(TTagDerefNode);
};
@ -420,9 +437,9 @@ struct TTagExprNode : ExprNode
{
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();
DBG_STMT_TYPE(TTagExprNode);
};
@ -431,42 +448,31 @@ struct FuncCallExprNode : ExprNode
{
StringTableEntry funcName;
StringTableEntry nameSpace;
ExprNode *args;
ExprNode* args;
U32 callType;
enum {
FunctionCall,
StaticCall,
MethodCall,
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();
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
{
ExprNode *testExpr;
const char *message;
ExprNode* testExpr;
const char* message;
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();
DBG_STMT_TYPE(AssertCallExprNode);
};
@ -474,19 +480,19 @@ struct AssertCallExprNode : ExprNode
struct SlotDecl
{
S32 lineNumber;
ExprNode *object;
ExprNode* object;
StringTableEntry slotName;
ExprNode *array;
ExprNode* array;
};
struct SlotAccessNode : ExprNode
{
ExprNode *objectExpr, *arrayExpr;
ExprNode* objectExpr, * arrayExpr;
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();
DBG_STMT_TYPE(SlotAccessNode);
};
@ -494,101 +500,99 @@ struct SlotAccessNode : ExprNode
struct InternalSlotDecl
{
S32 lineNumber;
ExprNode *object;
ExprNode *slotExpr;
ExprNode* object;
ExprNode* slotExpr;
bool recurse;
};
struct InternalSlotAccessNode : ExprNode
{
ExprNode *objectExpr, *slotExpr;
ExprNode* objectExpr, * slotExpr;
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();
DBG_STMT_TYPE(InternalSlotAccessNode);
};
struct SlotAssignNode : ExprNode
{
ExprNode *objectExpr, *arrayExpr;
ExprNode* objectExpr, * arrayExpr;
StringTableEntry slotName;
ExprNode *valueExpr;
ExprNode* valueExpr;
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();
DBG_STMT_TYPE(SlotAssignNode);
};
struct SlotAssignOpNode : ExprNode
{
ExprNode *objectExpr, *arrayExpr;
ExprNode* objectExpr, * arrayExpr;
StringTableEntry slotName;
S32 op;
ExprNode *valueExpr;
ExprNode* valueExpr;
U32 operand;
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();
DBG_STMT_TYPE(SlotAssignOpNode);
};
struct ObjectDeclNode : ExprNode
{
ExprNode *classNameExpr;
ExprNode* classNameExpr;
StringTableEntry parentObject;
ExprNode *objectNameExpr;
ExprNode *argList;
SlotAssignNode *slotDecls;
ObjectDeclNode *subObjects;
ExprNode* objectNameExpr;
ExprNode* argList;
SlotAssignNode* slotDecls;
ObjectDeclNode* subObjects;
bool isDatablock;
U32 failOffset;
bool isClassNameInternal;
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 compile(CodeStream &codeStream, U32 ip, TypeReq type);
U32 compileSubObject(CodeStream &codeStream, U32 ip, bool);
U32 compile(CodeStream& codeStream, U32 ip, TypeReq type);
U32 compileSubObject(CodeStream& codeStream, U32 ip, bool);
TypeReq getPreferredType();
DBG_STMT_TYPE(ObjectDeclNode);
};
struct ObjectBlockDecl
{
SlotAssignNode *slots;
ObjectDeclNode *decls;
SlotAssignNode* slots;
ObjectDeclNode* decls;
};
struct FunctionDeclStmtNode : StmtNode
{
StringTableEntry fnName;
VarNode *args;
StmtNode *stmts;
VarNode* args;
StmtNode* stmts;
StringTableEntry nameSpace;
StringTableEntry package;
U32 endOffset;
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);
DBG_STMT_TYPE(FunctionDeclStmtNode);
};
extern StmtNode *gStatementList;
extern StmtNode *gAnonFunctionList;
extern U32 gAnonFunctionID;
extern StmtNode* gStatementList;
extern ExprEvalState gEvalState;
#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
// of this software and associated documentation files (the "Software"), to
@ -20,7 +20,6 @@
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "platform/platform.h"
#include "console/console.h"
#include "console/compiler.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);
ret->dbgLineNumber = lineNumber;
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);
ret->dbgLineNumber = lineNumber;
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);
ret->expr = expr;
ret->dbgLineNumber = lineNumber;
@ -64,9 +63,9 @@ ReturnStmtNode *ReturnStmtNode::alloc(S32 lineNumber, ExprNode *expr)
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);
ret->dbgLineNumber = lineNumber;
@ -78,9 +77,9 @@ IfStmtNode *IfStmtNode::alloc(S32 lineNumber, ExprNode *testExpr, StmtNode *ifBl
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);
ret->dbgLineNumber = lineNumber;
ret->testExpr = testExpr;
@ -111,11 +110,12 @@ IterStmtNode* IterStmtNode::alloc(S32 lineNumber, StringTableEntry varName, Expr
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);
ret->dbgLineNumber = lineNumber;
ret->optimizedNode = NULL;
ret->op = op;
ret->left = left;
@ -124,11 +124,12 @@ FloatBinaryExprNode *FloatBinaryExprNode::alloc(S32 lineNumber, S32 op, ExprNode
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);
ret->dbgLineNumber = lineNumber;
ret->optimizedNode = NULL;
ret->op = op;
ret->left = left;
@ -137,11 +138,12 @@ IntBinaryExprNode *IntBinaryExprNode::alloc(S32 lineNumber, S32 op, ExprNode *le
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);
ret->dbgLineNumber = lineNumber;
ret->optimizedNode = NULL;
ret->left = left;
ret->right = right;
ret->eq = eq;
@ -149,11 +151,12 @@ StreqExprNode *StreqExprNode::alloc(S32 lineNumber, ExprNode *left, ExprNode *ri
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);
ret->dbgLineNumber = lineNumber;
ret->optimizedNode = NULL;
ret->left = left;
ret->right = right;
ret->appendChar = appendChar;
@ -161,61 +164,67 @@ StrcatExprNode *StrcatExprNode::alloc(S32 lineNumber, ExprNode *left, ExprNode *
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);
ret->dbgLineNumber = lineNumber;
ret->optimizedNode = NULL;
ret->left = left;
ret->right = right;
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);
ret->dbgLineNumber = lineNumber;
ret->optimizedNode = NULL;
ret->op = op;
ret->expr = expr;
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);
ret->dbgLineNumber = lineNumber;
ret->optimizedNode = NULL;
ret->op = op;
ret->expr = expr;
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);
ret->dbgLineNumber = lineNumber;
ret->optimizedNode = NULL;
ret->varName = varName;
ret->arrayIndex = arrayIndex;
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);
ret->dbgLineNumber = lineNumber;
ret->optimizedNode = NULL;
ret->value = value;
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);
ret->dbgLineNumber = lineNumber;
ret->optimizedNode = NULL;
ret->testExpr = testExpr;
ret->trueExpr = trueExpr;
ret->falseExpr = falseExpr;
@ -223,44 +232,50 @@ ConditionalExprNode *ConditionalExprNode::alloc(S32 lineNumber, ExprNode *testEx
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);
ret->dbgLineNumber = lineNumber;
ret->optimizedNode = NULL;
ret->value = value;
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);
S32 len = dStrlen(str);
ret->dbgLineNumber = lineNumber;
dsize_t retStrLen = dStrlen(str) + 1;
ret->str = (char *)consoleAlloc(retStrLen);
ret->optimizedNode = NULL;
ret->str = (char*)consoleAlloc(len + 1);
ret->tag = tag;
ret->doc = doc;
dStrcpy(ret->str, str, retStrLen);
dStrcpy(ret->str, str, len + 1);
ret->str[len] = '\0';
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);
ret->dbgLineNumber = lineNumber;
ret->optimizedNode = NULL;
ret->value = value;
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);
ret->dbgLineNumber = lineNumber;
ret->optimizedNode = NULL;
ret->varName = varName;
ret->expr = expr;
ret->arrayIndex = arrayIndex;
@ -268,11 +283,12 @@ AssignExprNode *AssignExprNode::alloc(S32 lineNumber, StringTableEntry varName,
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);
ret->dbgLineNumber = lineNumber;
ret->optimizedNode = NULL;
ret->varName = varName;
ret->expr = expr;
ret->arrayIndex = arrayIndex;
@ -280,9 +296,9 @@ AssignOpExprNode *AssignOpExprNode::alloc(S32 lineNumber, StringTableEntry varNa
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);
ret->dbgLineNumber = lineNumber;
ret->tag = tag;
@ -291,59 +307,54 @@ TTagSetStmtNode *TTagSetStmtNode::alloc(S32 lineNumber, StringTableEntry tag, Ex
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);
ret->dbgLineNumber = lineNumber;
ret->optimizedNode = NULL;
ret->expr = expr;
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);
ret->dbgLineNumber = lineNumber;
ret->optimizedNode = NULL;
ret->tag = tag;
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);
ret->dbgLineNumber = lineNumber;
ret->optimizedNode = NULL;
ret->funcName = funcName;
ret->nameSpace = nameSpace;
ret->args = args;
if (dot)
ret->callType = MethodCall;
else
else if (nameSpace != NULL)
{
if (nameSpace && !dStricmp(nameSpace, "Parent"))
if (dStricmp(nameSpace, "Parent") == 0)
ret->callType = ParentCall;
else
ret->callType = FunctionCall;
ret->callType = StaticCall;
}
else
ret->callType = FunctionCall;
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;
}
#ifdef TORQUE_ENABLE_SCRIPTASSERTS
AssertCallExprNode *AssertCallExprNode::alloc(S32 lineNumber, ExprNode *testExpr, const char *message)
{
#ifdef TORQUE_ENABLE_SCRIPTASSERTS
AssertCallExprNode *ret = (AssertCallExprNode *)consoleAlloc(sizeof(FuncCallExprNode));
AssertCallExprNode* ret = (AssertCallExprNode*)consoleAlloc(sizeof(FuncCallExprNode));
constructInPlace(ret);
ret->dbgLineNumber = lineNumber;
ret->testExpr = testExpr;
@ -357,10 +368,11 @@ AssertCallExprNode *AssertCallExprNode::alloc(S32 lineNumber, ExprNode *testExpr
#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);
ret->optimizedNode = NULL;
ret->dbgLineNumber = lineNumber;
ret->objectExpr = objectExpr;
ret->arrayExpr = arrayExpr;
@ -368,22 +380,24 @@ SlotAccessNode *SlotAccessNode::alloc(S32 lineNumber, ExprNode *objectExpr, Expr
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);
ret->dbgLineNumber = lineNumber;
ret->optimizedNode = NULL;
ret->objectExpr = objectExpr;
ret->slotExpr = slotExpr;
ret->recurse = recurse;
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);
ret->dbgLineNumber = lineNumber;
ret->optimizedNode = NULL;
ret->objectExpr = objectExpr;
ret->arrayExpr = arrayExpr;
ret->slotName = slotName;
@ -392,11 +406,12 @@ SlotAssignNode *SlotAssignNode::alloc(S32 lineNumber, ExprNode *objectExpr, Expr
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);
ret->dbgLineNumber = lineNumber;
ret->optimizedNode = NULL;
ret->objectExpr = objectExpr;
ret->arrayExpr = arrayExpr;
ret->slotName = slotName;
@ -405,11 +420,12 @@ SlotAssignOpNode *SlotAssignOpNode::alloc(S32 lineNumber, ExprNode *objectExpr,
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);
ret->dbgLineNumber = lineNumber;
ret->optimizedNode = NULL;
ret->classNameExpr = classNameExpr;
ret->objectNameExpr = objectNameExpr;
ret->argList = argList;
@ -422,13 +438,13 @@ ObjectDeclNode *ObjectDeclNode::alloc(S32 lineNumber, ExprNode *classNameExpr, E
if (parentObject)
ret->parentObject = parentObject;
else
ret->parentObject = StringTable->EmptyString();
ret->parentObject = StringTable->insert("");
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);
ret->dbgLineNumber = lineNumber;
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_
#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/consoleParser.h"
class Stream;
class ConsoleValue;
class ConsoleValueRef;
/// Core TorqueScript code management class.
///
/// This class represents a block of code, usually mapped directly to a file.
class CodeBlock
{
friend class CodeInterpreter;
private:
static CodeBlock* smCodeBlockList;
static CodeBlock* smCurrentCodeBlock;
@ -78,6 +95,8 @@ public:
U32 codeSize;
U32 *code;
CompilerLocalVariableToRegisterMappingTable variableRegisterTable;
U32 refCount;
U32 lineBreakPairCount;
U32 *lineBreakPairs;
@ -130,7 +149,7 @@ public:
/// 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
/// top stack frame is used.
ConsoleValueRef compileExec(StringTableEntry fileName, const char *script,
ConsoleValue compileExec(StringTableEntry fileName, const char *script,
bool noCalls, S32 setFrame = -1);
/// Executes the existing code in the CodeBlock. The return string is any
@ -148,9 +167,9 @@ public:
/// -1 a new frame is created. If the index is out of range the
/// top stack frame is used.
/// @param packageName The code package name or null.
ConsoleValueRef exec(U32 offset, const char *fnName, Namespace *ns, U32 argc,
ConsoleValueRef *argv, bool noCalls, StringTableEntry packageName,
ConsoleValue exec(U32 offset, const char *fnName, Namespace *ns, U32 argc,
ConsoleValue *argv, bool noCalls, StringTableEntry packageName,
S32 setFrame = -1);
};
#endif
#endif

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;
DataChunker gConsoleAllocator;
CompilerIdentTable gIdentTable;
CompilerLocalVariableToRegisterMappingTable gFunctionVariableMappingTable;
//------------------------------------------------------------
@ -92,6 +93,8 @@ namespace Compiler
CompilerStringTable &getGlobalStringTable() { return gGlobalStringTable; }
CompilerStringTable &getFunctionStringTable() { return gFunctionStringTable; }
CompilerLocalVariableToRegisterMappingTable& getFunctionVariableMappingTable() { return gFunctionVariableMappingTable; }
void setCurrentStringTable(CompilerStringTable* cst) { gCurrentStringTable = cst; }
CompilerFloatTable *getCurrentFloatTable() { return gCurrentFloatTable; }
@ -117,6 +120,7 @@ namespace Compiler
getFunctionFloatTable().reset();
getFunctionStringTable().reset();
getIdentTable().reset();
getFunctionVariableMappingTable().reset();
}
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)
{
Entry **walk;

View file

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

View file

@ -41,9 +41,40 @@
#include "platform/threads/mutex.h"
#include "core/util/journal/journal.h"
#include "cinterface/cinterface.h"
#include "console/consoleValueStack.h"
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;
ExprEvalState gEvalState;
@ -271,8 +302,6 @@ StringTableEntry gCurrentFile;
StringTableEntry gCurrentRoot;
/// @}
S32 gObjectCopyFailures = -1;
bool alwaysUseDebugOutput = true;
bool useTimestamp = false;
bool useRealTimestamp = false;
@ -327,6 +356,7 @@ void init()
// Setup the console types.
ConsoleBaseType::initialize();
ConsoleValue::init();
// And finally, the ACR...
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"
"@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
addVariable( "Con::File", TypeString, &gCurrentFile, "The currently executing script file.\n"
"@ingroup FileSystem\n");
@ -1474,7 +1500,7 @@ bool executeFile(const char* fileName, bool noCalls, bool journalScript)
return ret;
}
ConsoleValueRef evaluate(const char* string, bool echo, const char *fileName)
ConsoleValue evaluate(const char* string, bool echo, const char *fileName)
{
ConsoleStackFrameSaver stackSaver;
stackSaver.save();
@ -1491,11 +1517,11 @@ ConsoleValueRef evaluate(const char* string, bool echo, const char *fileName)
fileName = StringTable->insert(fileName);
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;
stackSaver.save();
@ -1512,36 +1538,41 @@ ConsoleValueRef evaluatef(const char* string, ...)
//------------------------------------------------------------------------------
// 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 *)));
for (int i = 0; i < argc - 1; i++)
{
argv_str[i] = argv[i + 1];
argv_str[i] = argv[i + 1].getString();
}
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);
if (result)
{
return ConsoleValueRef::fromValue(CSTK.pushString(methodRes));
ConsoleValue ret;
ret.setString(methodRes);
return std::move(ret);
}
Namespace::Entry *ent;
StringTableEntry funcName = StringTable->insert(argv[0]);
ent = Namespace::global()->lookup(funcName);
if(!ent)
{
warnf(ConsoleLogEntry::Script, "%s: Unknown command.", (const char*)argv[0]);
warnf(ConsoleLogEntry::Script, "%s: Unknown command.", funcName);
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
if(isMainThread())
@ -1563,23 +1594,23 @@ ConsoleValueRef execute(S32 argc, ConsoleValueRef argv[])
#endif
}
ConsoleValueRef execute(S32 argc, const char *argv[])
ConsoleValue execute(S32 argc, const char *argv[])
{
ConsoleStackFrameSaver stackSaver;
stackSaver.save();
StringStackConsoleWrapper args(argc, argv);
return execute(args.count(), args);
StringArrayToConsoleValueWrapper args(argc, argv);
return std::move(execute(args.count(), args));
}
//------------------------------------------------------------------------------
// 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)
{
STR.clearFunctionOffset();
return ConsoleValueRef();
return std::move(ConsoleValue());
}
// [neo, 10/05/2007 - #3010]
@ -1590,35 +1621,36 @@ ConsoleValueRef _internalExecute(SimObject *object, S32 argc, ConsoleValueRef ar
ICallMethod *com = dynamic_cast<ICallMethod *>(object);
if(com)
{
STR.pushFrame();
CSTK.pushFrame();
gCallStack.pushFrame(0);
com->callMethodArgList(argc, argv, false);
STR.popFrame();
CSTK.popFrame();
gCallStack.popFrame();
}
}
StringTableEntry funcName = StringTable->insert(argv[0].getString());
const char** argv_str = static_cast<const char**>(malloc((argc - 2) * sizeof(char *)));
for (int i = 0; i < argc - 2; i++)
{
argv_str[i] = argv[i + 2];
argv_str[i] = argv[i + 2].getString();
}
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);
if (result)
{
return ConsoleValueRef::fromValue(CSTK.pushString(methodRes));
ConsoleValue val;
val.setString(methodRes);
return val;
}
if(object->getNamespace())
{
U32 ident = object->getId();
ConsoleValueRef oldIdent(argv[1]);
StringTableEntry funcName = StringTable->insert(argv[0]);
const char* oldIdent = dStrdup(argv[1].getString());
Namespace::Entry *ent = object->getNamespace()->lookup(funcName);
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());
STR.clearFunctionOffset();
return ConsoleValueRef();
return std::move(ConsoleValue());
}
// Twiddle %this argument
ConsoleValue func_ident;
func_ident.setIntValue((S32)ident);
argv[1] = ConsoleValueRef::fromValue(&func_ident);
argv[1].setInt(ident);
SimObject *save = gEvalState.thisObject;
gEvalState.thisObject = object;
ConsoleValueRef ret = ent->execute(argc, argv, &gEvalState);
ConsoleValue ret = std::move(ent->execute(argc, argv, &gEvalState));
gEvalState.thisObject = save;
// Twiddle it back
argv[1] = oldIdent;
argv[1].setString(oldIdent);
dFree(oldIdent);
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();
return ConsoleValueRef();
return std::move(ConsoleValue());
}
ConsoleValueRef execute(SimObject *object, S32 argc, ConsoleValueRef argv[], bool thisCallOnly)
ConsoleValue execute(SimObject *object, S32 argc, ConsoleValue argv[], bool thisCallOnly)
{
if(argc < 2)
{
STR.clearFunctionOffset();
return ConsoleValueRef();
return std::move(ConsoleValue());
}
ConsoleStackFrameSaver stackSaver;
@ -1666,7 +1696,7 @@ ConsoleValueRef execute(SimObject *object, S32 argc, ConsoleValueRef argv[], boo
{
if (isMainThread())
{
return _internalExecute(object, argc, argv, thisCallOnly);
return std::move(_internalExecute(object, argc, argv, thisCallOnly));
}
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();
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;
stackSaver.save();
StringStackConsoleWrapper args(argc, argv);
return execute(object, args.count(), args, thisCallOnly);
StringArrayToConsoleValueWrapper args(argc, argv);
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;
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.");
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;
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.");
return execute(argc, argv);
return std::move(execute(argc, argv));
}
//------------------------------------------------------------------------------
@ -1901,15 +1931,9 @@ StringTableEntry getModNameFromPath(const char *path)
void postConsoleInput( RawData data )
{
// Schedule this to happen at the next time event.
ConsoleValue values[2];
ConsoleValueRef argv[2];
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];
ConsoleValue argv[2];
argv[0].setString("eval");
argv[1].setString(reinterpret_cast<const char*>(data.data));
Sim::postCurrentEvent(Sim::getRootGroup(), new SimConsoleEvent(2, argv, false));
}
@ -2524,70 +2548,20 @@ DefineEngineFunction( logWarning, void, ( const char* message ),,
//------------------------------------------------------------------------------
extern ConsoleValueStack CSTK;
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[])
ConsoleValueToStringArrayWrapper::ConsoleValueToStringArrayWrapper(int targc, ConsoleValue *targv)
{
argv = new const char*[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]);
}
@ -2595,201 +2569,58 @@ StringStackWrapper::~StringStackWrapper()
}
StringStackConsoleWrapper::StringStackConsoleWrapper(int targc, const char** targ)
StringArrayToConsoleValueWrapper::StringArrayToConsoleValueWrapper(int targc, const char** targv)
{
argv = new ConsoleValueRef[targc];
argvValue = new ConsoleValue[targc];
argv = new ConsoleValue[targc]();
argc = targc;
for (int i=0; i<targc; i++) {
argvValue[i].init();
argv[i].value = &argvValue[i];
argvValue[i].setStackStringValue(targ[i]);
for (int i=0; i<targc; i++)
{
argv[i].setString(targv[i]);
}
}
StringStackConsoleWrapper::~StringStackConsoleWrapper()
StringArrayToConsoleValueWrapper::~StringArrayToConsoleValueWrapper()
{
for (int i=0; i<argc; i++)
{
argv[i] = 0;
}
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 )
{
// Cannot invoke callback until object has been registered
if (mThis->isProperlyAdded()) {
returnValue = Con::_internalExecute( mThis, mArgc, mArgv, false );
} else {
STR.clearFunctionOffset();
returnValue = ConsoleValueRef();
if (mThis->isProperlyAdded())
{
ConsoleValue returnValue = Con::_internalExecute( mThis, mArgc, mArgv, false );
mArgc = mInitialArgc; // reset
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
return returnValue;
return std::move(returnValue);
}
ConsoleValueRef _BaseEngineConsoleCallbackHelper::_execLater(SimConsoleThreadExecEvent *evt)
ConsoleValue _BaseEngineConsoleCallbackHelper::_execLater(SimConsoleThreadExecEvent *evt)
{
mArgc = mInitialArgc; // reset args
Sim::postEvent((SimObject*)Sim::getRootGroup(), evt, Sim::getCurrentTime());
return evt->getCB().waitForResult();
return std::move(evt->getCB().waitForResult());
}
//------------------------------------------------------------------------------
void ConsoleStackFrameSaver::save()
{
CSTK.pushFrame();
STR.pushFrame();
gCallStack.pushFrame(0);
mSaved = true;
}
@ -2797,7 +2628,6 @@ void ConsoleStackFrameSaver::restore()
{
if (mSaved)
{
CSTK.popFrame();
STR.popFrame();
gCallStack.popFrame();
}
}

View file

@ -36,6 +36,7 @@
#include "core/util/str.h"
#include "core/util/journal/journaledSignal.h"
#include "core/stringTable.h"
class SimObject;
class Namespace;
@ -117,188 +118,313 @@ struct ConsoleLogEntry
typedef const char *StringTableEntry;
extern char *typeValueEmpty;
enum ConsoleValueType
{
cvInteger = -4,
cvFloat = -3,
cvString = -2,
cvSTEntry = -1,
cvConsoleValueType = 0
};
struct ConsoleValueConsoleType
{
void* dataPtr;
EnumTable* enumTable;
};
class ConsoleValue
{
public:
enum
union
{
TypeInternalInt = -5,
TypeInternalFloat = -4,
TypeInternalStringStackPtr = -3,
TypeInternalStackString = -2,
TypeInternalString = -1,
F64 f;
S64 i;
char* s;
void* data;
ConsoleValueConsoleType* ct;
};
S32 type;
public:
// 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
enum Constants
{
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;
};
ConversionBufferStride = 32
};
U32 getIntValue();
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()
struct ConversionBuffer
{
ival = 0;
fval = 0;
sval = typeValueEmpty;
bufferLen = 0;
type = TypeInternalString;
char buffer[ConversionBufferStride];
};
static Vector<ConversionBuffer> sConversionBuffer;
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);
bufferLen = 0;
dFree(data);
data = NULL;
}
sval = typeValueEmpty;
type = ConsoleValue::TypeInternalString;
ival = 0;
fval = 0;
}
ConsoleValue() { init(); };
~ConsoleValue() { cleanup(); };
};
// Proxy class for console variables
// Can point to existing console variables,
// or act like a free floating value.
class ConsoleValueRef
{
TORQUE_FORCEINLINE void _move(ConsoleValue&& ref) noexcept
{
type = ref.type;
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:
ConsoleValue *value;
ConsoleValue()
{
type = ConsoleValueType::cvSTEntry;
s = const_cast<char*>(StringTable->EmptyString());
}
ConsoleValueRef() : value(0) { ; }
~ConsoleValueRef() { ; }
ConsoleValue(ConsoleValue&& ref) noexcept
{
_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() : ""; }
StringStackPtr getStringStackPtrValue() { return value ? value->getStringStackPtr() : 0; }
TORQUE_FORCEINLINE ~ConsoleValue()
{
cleanupData();
}
inline U32 getIntValue() { return value ? value->getIntValue() : 0; }
inline S32 getSignedIntValue() { return value ? value->getSignedIntValue() : 0; }
inline F32 getFloatValue() { return value ? value->getFloatValue() : 0.0f; }
inline bool getBoolValue() { return value ? value->getBoolValue() : false; }
TORQUE_FORCEINLINE void reset()
{
setEmptyString();
}
inline operator const char*() { return getStringValue(); }
inline operator String() { return String(getStringValue()); }
inline operator U32() { return getIntValue(); }
inline operator S32() { return getSignedIntValue(); }
inline operator F32() { return getFloatValue(); }
inline operator bool() { return getBoolValue(); }
TORQUE_FORCEINLINE F64 getFloat() const
{
if (type == ConsoleValueType::cvFloat)
return f;
if (type == ConsoleValueType::cvInteger)
return i;
if (isStringType())
return dAtof(s);
return dAtof(getConsoleData());
}
inline bool isStringStackPtr() { return value ? value->type == ConsoleValue::TypeInternalStringStackPtr : false; }
inline bool isString() { return value ? value->type >= ConsoleValue::TypeInternalStringStackPtr : true; }
inline bool isInt() { return value ? value->type == ConsoleValue::TypeInternalInt : false; }
inline bool isFloat() { return value ? value->type == ConsoleValue::TypeInternalFloat : false; }
inline S32 getType() { return value ? value->type : -1; }
TORQUE_FORCEINLINE S64 getInt() const
{
if (type == ConsoleValueType::cvInteger)
return i;
if (type == ConsoleValueType::cvFloat)
return f;
if (isStringType())
return dAtoi(s);
return dAtoi(getConsoleData());
}
// Note: operators replace value
ConsoleValueRef& operator=(const ConsoleValueRef &other);
ConsoleValueRef& operator=(const char *newValue);
ConsoleValueRef& operator=(U32 newValue);
ConsoleValueRef& operator=(S32 newValue);
ConsoleValueRef& operator=(F32 newValue);
ConsoleValueRef& operator=(F64 newValue);
TORQUE_FORCEINLINE const char* getString() const
{
if (isStringType())
return s;
if (isNumberType())
return convertToBuffer();
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**
class StringStackWrapper
class ConsoleValueToStringArrayWrapper
{
public:
const char **argv;
int argc;
S32 argc;
StringStackWrapper(int targc, ConsoleValueRef targv[]);
~StringStackWrapper();
ConsoleValueToStringArrayWrapper(int targc, ConsoleValue* targv);
~ConsoleValueToStringArrayWrapper();
const char* operator[](int idx) { return argv[idx]; }
const char* operator[](S32 idx) { return argv[idx]; }
operator const char**() { return argv; }
int count() { return argc; }
S32 count() { return argc; }
};
// Transparently converts const char** to ConsoleValue
class StringStackConsoleWrapper
class StringArrayToConsoleValueWrapper
{
public:
ConsoleValue *argvValue;
ConsoleValueRef *argv;
int argc;
ConsoleValue *argv;
S32 argc;
StringStackConsoleWrapper(int targc, const char **targv);
~StringStackConsoleWrapper();
StringArrayToConsoleValueWrapper(int targc, const char **targv);
~StringArrayToConsoleValueWrapper();
ConsoleValueRef& operator[](int idx) { return argv[idx]; }
operator ConsoleValueRef*() { return argv; }
ConsoleValue& operator[](int idx) { return argv[idx]; }
operator ConsoleValue*() { return argv; }
int count() { return argc; }
S32 count() { return argc; }
};
/// @defgroup console_callbacks Scripting Engine Callbacks
@ -319,11 +445,11 @@ public:
/// @{
///
typedef const char * (*StringCallback)(SimObject *obj, S32 argc, ConsoleValueRef argv[]);
typedef S32(*IntCallback)(SimObject *obj, S32 argc, ConsoleValueRef argv[]);
typedef F32(*FloatCallback)(SimObject *obj, S32 argc, ConsoleValueRef argv[]);
typedef void(*VoidCallback)(SimObject *obj, S32 argc, ConsoleValueRef argv[]); // We have it return a value so things don't break..
typedef bool(*BoolCallback)(SimObject *obj, S32 argc, ConsoleValueRef argv[]);
typedef const char * (*StringCallback)(SimObject *obj, S32 argc, ConsoleValue argv[]);
typedef S32(*IntCallback)(SimObject *obj, S32 argc, ConsoleValue argv[]);
typedef F32(*FloatCallback)(SimObject *obj, S32 argc, ConsoleValue argv[]);
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, ConsoleValue argv[]);
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/07/17 - JTH - 48->49 Added opcode for function pointers and revamp of interpreter
/// 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.
MaxDataTypes = 256 ///< Maximum number of registered data types.
@ -786,8 +913,8 @@ namespace Con
/// char* result = execute(2, argv);
/// @endcode
/// NOTE: this function restores the console stack on return.
ConsoleValueRef execute(S32 argc, const char* argv[]);
ConsoleValueRef execute(S32 argc, ConsoleValueRef argv[]);
ConsoleValue execute(S32 argc, const char* argv[]);
ConsoleValue execute(S32 argc, ConsoleValue argv[]);
/// Call a Torque Script member function of a SimObject from C/C++ code.
/// @param object Object on which to execute the method call.
@ -802,8 +929,8 @@ namespace Con
/// char* result = execute(mysimobject, 3, argv);
/// @endcode
/// NOTE: this function restores the console stack on return.
ConsoleValueRef 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, const char* 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.
///
@ -821,13 +948,13 @@ namespace Con
/// @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.
/// 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.
///
/// This wraps dVsprintf(), so you can substitute parameters into the code being executed.
/// 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
///
template<typename R, typename ...ArgTs>
ConsoleValueRef executef(R r, ArgTs ...argTs)
ConsoleValue executef(R r, ArgTs ...argTs)
{
_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)
# 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); \
returnType ctf_##name(SimObject *, S32 argc, ConsoleValueRef *argv)
returnType ctf_##name(SimObject *, S32 argc, ConsoleValue *argv)
# define ConsoleFunctionGroupEnd(groupName) \
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.
# 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 returnType c##name(SimObject *, S32 argc, ConsoleValueRef *argv)
static returnType c##name(SimObject *, S32 argc, ConsoleValue *argv)
# 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 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) \
static inline returnType c##className##name(className *, S32, ConsoleValueRef *argv); \
static returnType c##className##name##caster(SimObject *object, S32 argc, ConsoleValueRef *argv) { \
static inline returnType c##className##name(className *, S32, ConsoleValue *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); \
}; \
static ConsoleConstructor \
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 )

View file

@ -2286,7 +2286,8 @@ DefineEngineStringlyVariadicFunction( call, const char *, 2, 0, "( string functi
"@endtsexample\n\n"
"@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)" )
{
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"

View file

@ -183,13 +183,13 @@ void Dictionary::exportVariables(const char *varString, const char *fileName, bo
for (s = sortList.begin(); s != sortList.end(); s++)
{
switch ((*s)->value.type)
switch ((*s)->type)
{
case ConsoleValue::TypeInternalInt:
dSprintf(buffer, sizeof(buffer), "%s = %d;%s", (*s)->name, (*s)->value.ival, cat);
case Entry::TypeInternalInt:
dSprintf(buffer, sizeof(buffer), "%s = %d;%s", (*s)->name, (*s)->ival, cat);
break;
case ConsoleValue::TypeInternalFloat:
dSprintf(buffer, sizeof(buffer), "%s = %g;%s", (*s)->name, (*s)->value.fval, cat);
case Entry::TypeInternalFloat:
dSprintf(buffer, sizeof(buffer), "%s = %g;%s", (*s)->name, (*s)->fval, cat);
break;
default:
expandEscape(expandBuffer, (*s)->getStringValue());
@ -243,13 +243,11 @@ void Dictionary::exportVariables(const char *varString, Vector<String> *names, V
if (values)
{
switch ((*s)->value.type)
switch ((*s)->type)
{
case ConsoleValue::TypeInternalInt:
values->push_back(String::ToString((*s)->value.ival));
break;
case ConsoleValue::TypeInternalFloat:
values->push_back(String::ToString((*s)->value.fval));
case ConsoleValueType::cvInteger:
case ConsoleValueType::cvFloat:
values->push_back(String((*s)->getStringValue()));
break;
default:
expandEscape(expandBuffer, (*s)->getStringValue());
@ -470,25 +468,94 @@ char *typeValueEmpty = "";
Dictionary::Entry::Entry(StringTableEntry in_name)
{
name = in_name;
value.type = ConsoleValue::TypeInternalString;
type = TypeInternalString;
notify = NULL;
nextEntry = NULL;
mUsage = NULL;
mIsConstant = false;
mNext = NULL;
// NOTE: This is data inside a nameless
// union, so we don't need to init the rest.
value.init();
ival = 0;
fval = 0;
sval = typeValueEmpty;
bufferLen = 0;
}
Dictionary::Entry::~Entry()
{
value.cleanup();
reset();
}
void Dictionary::Entry::reset()
{
name = NULL;
if (type <= TypeInternalString && sval != typeValueEmpty)
dFree(sval);
if (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)
{
Entry *ent = lookup(name);
@ -508,150 +575,6 @@ const char *Dictionary::getVariable(StringTableEntry name, bool *entValid)
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)
{
Entry *ent = lookup(name);
@ -708,19 +631,17 @@ Dictionary::Entry* Dictionary::addVariable(const char *name,
Entry *ent = add(StringTable->insert(name));
if (ent->value.type <= ConsoleValue::TypeInternalString &&
ent->value.bufferLen > 0)
dFree(ent->value.sval);
if (ent->type <= Entry::TypeInternalString && ent->sval != typeValueEmpty)
dFree(ent->sval);
ent->value.type = type;
ent->value.dataPtr = dataPtr;
ent->mUsage = usage;
ent->type = type;
ent->dataPtr = dataPtr;
// Fetch enum table, if any.
ConsoleBaseType* conType = ConsoleBaseType::getType(type);
AssertFatal(conType, "Dictionary::addVariable - invalid console type");
ent->value.enumTable = conType->getEnumTable();
ent->enumTable = conType->getEnumTable();
return ent;
}
@ -760,7 +681,7 @@ void Dictionary::validate()
"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
validate();
@ -789,6 +710,12 @@ void ExprEvalState::pushFrame(StringTableEntry frameName, Namespace *ns)
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
validate();
#endif
@ -809,6 +736,15 @@ void ExprEvalState::popFrame()
stack[mStackDepth]->reset();
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
validate();
#endif
@ -816,7 +752,7 @@ void ExprEvalState::popFrame()
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
validate();
@ -840,11 +776,30 @@ void ExprEvalState::pushFrameRef(S32 stackIndex)
mStackDepth++;
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
validate();
#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()
{
VECTOR_SET_ASSOCIATION(stack);
@ -1413,7 +1368,7 @@ void Namespace::markGroup(const char* name, const char* usage)
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();
@ -1421,11 +1376,11 @@ ConsoleValueRef Namespace::Entry::execute(S32 argc, ConsoleValueRef *argv, ExprE
{
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
{
return ConsoleValueRef();
return std::move(ConsoleValue());
}
}
@ -1435,7 +1390,7 @@ ConsoleValueRef Namespace::Entry::execute(S32 argc, ConsoleValueRef *argv, ExprE
if (mToolOnly && !Con::isCurrentScriptToolScript())
{
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
@ -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, "usage: %s", mUsage);
return ConsoleValueRef();
return std::move(ConsoleValue());
}
ConsoleValue result;
switch (mType)
{
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:
return ConsoleValueRef::fromValue(CSTK.pushUINT((U32)cb.mIntCallbackFunc(state->thisObject, argc, argv)));
result.setInt(cb.mIntCallbackFunc(state->thisObject, argc, argv));
break;
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:
cb.mVoidCallbackFunc(state->thisObject, argc, argv);
return ConsoleValueRef();
break;
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();
///
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.
String getBriefDescription(String* outRemainingDocText = NULL) const;
@ -274,17 +274,24 @@ public:
typedef VectorPtr<Namespace::Entry *>::iterator NamespaceEntryListIterator;
class Dictionary
{
public:
struct Entry
{
friend class Dictionary;
enum
{
TypeInternalInt = -3,
TypeInternalFloat = -2,
TypeInternalString = -1,
};
StringTableEntry name;
ConsoleValue value;
Entry *nextEntry;
S32 type;
typedef Signal<void()> NotifySignal;
@ -298,16 +305,56 @@ public:
/// Whether this is a constant that cannot be assigned to.
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:
Entry() {
name = NULL;
type = TypeInternalString;
notify = NULL;
nextEntry = NULL;
mUsage = NULL;
mIsConstant = false;
mNext = NULL;
value.init();
ival = 0;
fval = 0;
sval = typeValueEmpty;
bufferLen = 0;
}
Entry(StringTableEntry name);
@ -315,26 +362,34 @@ public:
Entry *mNext;
void reset() {
name = NULL;
value.cleanup();
if (notify)
delete notify;
}
void reset();
inline U32 getIntValue()
{
return value.getIntValue();
if (type <= TypeInternalString)
return ival;
else
return dAtoi(Con::getData(type, dataPtr, 0, enumTable));
}
inline F32 getFloatValue()
{
return value.getFloatValue();
if (type <= TypeInternalString)
return fval;
else
return dAtof(Con::getData(type, dataPtr, 0, enumTable));
}
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)
@ -345,7 +400,22 @@ public:
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.
if (notify)
@ -360,44 +430,29 @@ public:
return;
}
value.setFloatValue(val);
// Fire off the notification if we have one.
if (notify)
notify->trigger();
}
void setStringStackPtrValue(StringStackPtr newValue)
{
if (mIsConstant)
if (type <= TypeInternalString)
{
Con::errorf("Cannot assign value to constant '%s'.", name);
return;
fval = val;
ival = static_cast<U32>(val);
if (sval != typeValueEmpty)
{
dFree(sval);
sval = typeValueEmpty;
}
type = TypeInternalFloat;
}
else
{
const char* dptr = Con::getData(TypeF32, &val, 0);
Con::setData(type, dataPtr, 0, 1, &dptr, enumTable);
}
value.setStringStackPtrValue(newValue);
// Fire off the notification if we have one.
if (notify)
notify->trigger();
}
void setStringValue(const char *newValue)
{
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();
}
void setStringValue(const char* value);
};
struct HashTableData
@ -471,6 +526,21 @@ public:
void validate();
};
struct ConsoleValueFrame
{
ConsoleValue* values;
bool isReference;
ConsoleValueFrame() : values(NULL), isReference(false)
{}
ConsoleValueFrame(ConsoleValue* vals, bool isRef)
{
values = vals;
isReference = isRef;
}
};
class ExprEvalState
{
public:
@ -499,6 +569,11 @@ public:
/// an interior pointer that will become invalid when the object changes address.
Vector< Dictionary* > stack;
S32 getTopOfStack() { return (S32)mStackDepth; }
Vector< ConsoleValueFrame > localStack;
ConsoleValueFrame* currentRegisterArray; // contains array at to top of localStack
///
Dictionary globalVars;
@ -511,16 +586,56 @@ public:
void setIntVariable(S32 val);
void setFloatVariable(F64 val);
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();
/// Puts a reference to an existing stack frame
/// on the top of the stack.
void pushFrameRef(S32 stackIndex);
void pushDebugFrame(S32 stackIndex);
U32 getStackDepth() const
{
return mStackDepth;
@ -531,6 +646,11 @@ public:
return *(stack[mStackDepth - 1]);
}
Dictionary& getFrameAt(S32 depth)
{
return *(stack[depth]);
}
/// @}
/// 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 )
return false;
bool append = false;
if( argc == 2 )
append = dAtob( argv[1] );
if (argc == 2)
append = argv[1].getBool();
mAppend = append;
mFilename = StringTable->insert( argv[0] );
mFilename = StringTable->insert( argv[0].getString() );
if( init() )
{

View file

@ -81,7 +81,7 @@ class ConsoleLogger : public SimObject
/// // Example script constructor usage.
/// %obj = new ConsoleLogger( objName, logFileName, [append = false] );
/// @endcode
bool processArguments( S32 argc, ConsoleValueRef *argv );
bool processArguments( S32 argc, ConsoleValue *argv );
/// Default constructor, make sure to initalize
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
/// client function invocation vector.
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 );
argc ++;
const char* str = castConsoleTypeToString(arg);;
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 ] = 1;
else
argv[ argc ] = 0;
argc ++;
argv[ argc++ ].setBool(arg);
}
inline void EngineMarshallData( S32 arg, S32& argc, ConsoleValueRef *argv )
inline void EngineMarshallData( S32 arg, S32& argc, ConsoleValue *argv )
{
argv[ argc ] = arg;
argc ++;
argv[ argc++ ].setInt(arg);
}
inline void EngineMarshallData( U32 arg, S32& argc, ConsoleValueRef *argv )
inline void EngineMarshallData( U32 arg, S32& argc, ConsoleValue *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;
argc ++;
argv[ argc++ ].setFloat(arg);
}
inline void EngineMarshallData( const char* arg, S32& argc, ConsoleValueRef *argv )
inline void EngineMarshallData( const char* arg, S32& argc, ConsoleValue *argv )
{
argv[ argc ] = arg;
argc ++;
argv[ argc++ ].setString(arg);
}
inline void EngineMarshallData( char* arg, S32& argc, ConsoleValueRef *argv )
inline void EngineMarshallData( char* arg, S32& argc, ConsoleValue *argv )
{
argv[ argc ] = arg;
argc ++;
argv[ argc++ ].setString(arg);
}
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;
argc ++;
argv[ argc++ ].setInt(object ? object->getId() : 0);
}
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;
argc ++;
argv[ argc++ ].setInt(object ? object->getId() : 0);
}
/// Unmarshal data from client form to engine form.
@ -216,9 +206,9 @@ struct EngineUnmarshallData
template<>
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
@ -229,9 +219,9 @@ struct EngineUnmarshallData< S32 >
template<>
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
@ -242,9 +232,9 @@ struct EngineUnmarshallData< U32 >
template<>
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
@ -255,9 +245,9 @@ struct EngineUnmarshallData< F32 >
template<>
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
@ -268,9 +258,9 @@ struct EngineUnmarshallData< U8 >
template<>
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
@ -281,9 +271,9 @@ struct EngineUnmarshallData< const char* >
template< typename 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
@ -294,17 +284,17 @@ struct EngineUnmarshallData< T* >
template<>
struct EngineUnmarshallData< void >
{
void operator()( ConsoleValueRef& ) const {}
void operator()( ConsoleValue& ) const {}
void operator()( const char* ) const {}
};
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;
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)
{
@ -559,12 +549,12 @@ namespace engineAPI{
}
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) ...);
}
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) ...);
}
@ -579,9 +569,9 @@ namespace engineAPI{
}
};
template<> struct MarshallHelpers<ConsoleValueRef> {
template<typename ...ArgTs> static void marshallEach(S32 &argc, ConsoleValueRef *argv, const ArgTs& ...args){}
template<typename H, typename ...Tail> static void marshallEach(S32 &argc, ConsoleValueRef *argv, const H& head, const Tail& ...tail){
template<> struct MarshallHelpers<ConsoleValue> {
template<typename ...ArgTs> static void marshallEach(S32 &argc, ConsoleValue *argv, const ArgTs& ...args){}
template<typename H, typename ...Tail> static void marshallEach(S32 &argc, ConsoleValue *argv, const H& head, const Tail& ...tail){
EngineMarshallData(head, argc, argv);
marshallEach(argc, argv, tail...);
}
@ -604,12 +594,12 @@ public:
template<typename Frame> using MethodType = typename Helper::template MethodType<Frame>;
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()));
}
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()));
}
@ -627,12 +617,12 @@ public:
template<typename Frame> using MethodType = typename Helper::template MethodType<Frame>;
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());
}
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());
}
@ -705,7 +695,7 @@ public:
( void* ) &fn ## name, \
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( \
argc, argv, &_fn ## name ## impl, _fn ## name ## DefaultArgs \
@ -785,7 +775,7 @@ public:
( void* ) &fn ## className ## _ ## name, \
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; \
frame.object = static_cast< className* >( object ); \
@ -842,7 +832,7 @@ public:
( void* ) &fn ## className ## _ ## name, \
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( \
argc, argv, &_fn ## className ## name ## impl, _fn ## className ## name ## DefaultArgs \
@ -859,12 +849,12 @@ public:
static inline returnType _fn ## className ## name ## impl args
# 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 \
(Vector<const char*>* vec) \
{ \
_CHECK_ENGINE_INITIALIZED( name, returnType ); \
StringStackConsoleWrapper args(vec->size(), vec->address()); \
StringArrayToConsoleValueWrapper args(vec->size(), vec->address()); \
return EngineTypeTraits< returnType >::ReturnValue( \
_fn ## name ## impl(NULL, args.count(), args) \
); \
@ -882,20 +872,20 @@ public:
0 \
); \
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) \
struct _ ## className ## name ## frame \
{ \
typedef className ObjectType; \
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 \
(className* object, Vector<const char*>* vec) \
{ \
_CHECK_ENGINE_INITIALIZED( name, returnType ); \
StringStackConsoleWrapper args(vec->size(), vec->address()); \
StringArrayToConsoleValueWrapper args(vec->size(), vec->address()); \
_ ## className ## name ## frame frame {}; \
frame.object = static_cast< className* >( object ); \
return EngineTypeTraits< returnType >::ReturnValue( \
@ -915,14 +905,14 @@ public:
( void* ) &fn ## className ## _ ## name, \
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 "!" ); \
_ ## className ## name ## frame frame {}; \
frame.object = static_cast< className* >( object ); \
conmethod_return_##returnType ) frame._exec(argc,argv); \
}; \
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 mArgc;
StringTableEntry mCallbackName;
ConsoleValueRef mArgv[ MAX_ARGUMENTS + 2 ];
ConsoleValue mArgv[ MAX_ARGUMENTS + 2 ];
ConsoleValueRef _exec();
ConsoleValueRef _execLater(SimConsoleThreadExecEvent *evt);
ConsoleValue _exec();
ConsoleValue _execLater(SimConsoleThreadExecEvent *evt);
_BaseEngineConsoleCallbackHelper(): mThis(NULL), mInitialArgc(0), mArgc(0), mCallbackName(StringTable->EmptyString()){;}
};
@ -1181,7 +1171,7 @@ public:
struct _EngineConsoleCallbackHelper : public _BaseEngineConsoleCallbackHelper
{
private:
using Helper = engineAPI::detail::MarshallHelpers<ConsoleValueRef>;
using Helper = engineAPI::detail::MarshallHelpers<ConsoleValue>;
public:
_EngineConsoleCallbackHelper( StringTableEntry callbackName, SimObject* pThis )
@ -1197,8 +1187,7 @@ public:
if (Con::isMainThread())
{
ConsoleStackFrameSaver sav; sav.save();
CSTK.reserveValues(mArgc + sizeof...(ArgTs), mArgv);
mArgv[ 0 ].value->setStackStringValue(mCallbackName);
mArgv[ 0 ].setStringTableEntry(mCallbackName);
Helper::marshallEach(mArgc, mArgv, args...);
@ -1209,7 +1198,7 @@ public:
SimConsoleThreadExecCallback cb;
SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc + sizeof...(ArgTs), NULL, false, &cb);
evt->populateArgs(mArgv);
mArgv[ 0 ].value->setStackStringValue(mCallbackName);
mArgv[ 0 ].setStringTableEntry(mCallbackName);
Helper::marshallEach(mArgc, mArgv, args...);
@ -1226,7 +1215,7 @@ public:
template<typename P1> struct _EngineConsoleExecCallbackHelper : public _BaseEngineConsoleCallbackHelper
{
private:
using Helper = engineAPI::detail::MarshallHelpers<ConsoleValueRef>;
using Helper = engineAPI::detail::MarshallHelpers<ConsoleValue>;
public:
_EngineConsoleExecCallbackHelper( SimObject* pThis )
@ -1243,8 +1232,7 @@ public:
if (Con::isMainThread())
{
ConsoleStackFrameSaver sav; sav.save();
CSTK.reserveValues(mArgc+sizeof...(ArgTs), mArgv);
mArgv[ 0 ].value->setStackStringValue(simCB);
mArgv[ 0 ].setString(simCB);
Helper::marshallEach(mArgc, mArgv, args...);
@ -1255,7 +1243,7 @@ public:
SimConsoleThreadExecCallback cb;
SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+sizeof...(ArgTs), NULL, true, &cb);
evt->populateArgs(mArgv);
mArgv[ 0 ].value->setStackStringValue(simCB);
mArgv[ 0 ].setString(simCB);
Helper::marshallEach(mArgc, mArgv, args...);
@ -1270,7 +1258,7 @@ public:
template<> struct _EngineConsoleExecCallbackHelper<const char*> : public _BaseEngineConsoleCallbackHelper
{
private:
using Helper = engineAPI::detail::MarshallHelpers<ConsoleValueRef>;
using Helper = engineAPI::detail::MarshallHelpers<ConsoleValue>;
public:
_EngineConsoleExecCallbackHelper( const char *callbackName )
{
@ -1285,10 +1273,9 @@ public:
if (Con::isMainThread())
{
ConsoleStackFrameSaver sav; sav.save();
CSTK.reserveValues(mArgc+sizeof...(ArgTs), mArgv);
mArgv[ 0 ].value->setStackStringValue(mCallbackName);
mArgv[ 0 ].setStringTableEntry(mCallbackName);
Helper::marshallEach(mArgc, mArgv, args...);
Helper::marshallEach(mArgc, mArgv, args...);
return R( EngineUnmarshallData< R >()( _exec() ) );
}
@ -1297,7 +1284,7 @@ public:
SimConsoleThreadExecCallback cb;
SimConsoleThreadExecEvent *evt = new SimConsoleThreadExecEvent(mArgc+sizeof...(ArgTs), NULL, false, &cb);
evt->populateArgs(mArgv);
mArgv[ 0 ].value->setStackStringValue(mCallbackName);
mArgv[ 0 ].setStringTableEntry(mCallbackName);
Helper::marshallEach(mArgc, mArgv, args...);

View file

@ -114,7 +114,7 @@ static void dumpVariable( Stream& stream,
{
// Skip variables defined in script.
if( entry->value.type < 0 )
if( entry->type <= Dictionary::Entry::TypeInternalString )
return;
// 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.
ConsoleBaseType* type = ConsoleBaseType::getType( entry->value.type );
ConsoleBaseType* type = ConsoleBaseType::getType( entry->type );
if( !type )
{
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();
SimGroup* getRootGroup();
SimObject* findObject(ConsoleValueRef&);
SimObject* findObject(SimObjectId);
SimObject* findObject(const ConsoleValue&);
SimObject* findObject(ConsoleValue*);
SimObject* findObject(const char* name);
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)
{
t = dynamic_cast<T*>(findObject(iD));

View file

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

View file

@ -83,8 +83,6 @@ public:
virtual void process(SimObject *object)=0;
};
class ConsoleValueRef;
/// Implementation of schedule() function.
///
/// This allows you to set a console function to be
@ -93,7 +91,7 @@ class SimConsoleEvent : public SimEvent
{
protected:
S32 mArgc;
ConsoleValueRef *mArgv;
ConsoleValue *mArgv;
bool mOnObject;
public:
@ -110,13 +108,13 @@ public:
///
/// @see Con::execute(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();
virtual void process(SimObject *object);
/// 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
{
Semaphore *sem;
ConsoleValueRef retVal;
ConsoleValue retVal;
SimConsoleThreadExecCallback();
~SimConsoleThreadExecCallback();
void handleCallback(ConsoleValueRef ret);
ConsoleValueRef waitForResult();
void handleCallback(ConsoleValue ret);
ConsoleValue waitForResult();
};
class SimConsoleThreadExecEvent : public SimConsoleEvent
@ -139,7 +137,7 @@ class SimConsoleThreadExecEvent : public SimConsoleEvent
SimConsoleThreadExecCallback *cb;
public:
SimConsoleThreadExecEvent(S32 argc, ConsoleValueRef *argv, bool onObject, SimConsoleThreadExecCallback *callback);
SimConsoleThreadExecEvent(S32 argc, ConsoleValue *argv, bool onObject, SimConsoleThreadExecCallback *callback);
SimConsoleThreadExecCallback& getCB() { return *cb; }
virtual void process(SimObject *object);

View file

@ -328,11 +328,6 @@ SimObject* findObject(const char* fileName, S32 declarationLine)
return gRootGroup->findObjectByLineNumber(fileName, declarationLine, true);
}
SimObject* findObject(ConsoleValueRef &ref)
{
return findObject((const char*)ref);
}
SimObject* findObject(const char* name)
{
PROFILE_SCOPE(SimFindObject);
@ -391,6 +386,20 @@ SimObject* findObject(const char* name)
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)
{
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;
}
@ -2971,8 +2971,10 @@ DefineEngineStringlyVariadicMethod( SimObject, call, const char*, 3, 0, "( strin
"@param args Zero or more arguments for the method.\n"
"@return The result of the method call." )
{
argv[1] = argv[2];
return Con::execute( object, argc - 1, argv + 1 );
argv[1].setString(argv[2].getString());
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"
"@return The numeric ID of the created schedule. Can be used to cancel the call.\n" )
{
U32 timeDelta = U32(dAtof(argv[2]));
argv[2] = argv[3];
argv[3] = argv[1];
U32 timeDelta = U32(argv[2].getFloat());
argv[2].setString(argv[3].getString());
argv[3].setString(argv[1].getString());
SimConsoleEvent *evt = new SimConsoleEvent(argc - 2, argv + 2, true);
S32 ret = Sim::postEvent(object, evt, Sim::getCurrentTime() + timeDelta);
// #ifdef DEBUG

View file

@ -587,7 +587,7 @@ class SimObject: public ConsoleObject, public TamlCallbacks
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 )
{

View file

@ -58,7 +58,7 @@ class SimPersistSet : public SimSet
// SimSet.
virtual void addObject( SimObject* );
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_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...
// Make sure and leave args[1] empty.
ConsoleValueRef args[21] = { };
ConsoleValue name_method;
name_method.setStackStringValue(method.c_str());
args[0] = ConsoleValueRef::fromValue(&name_method);
ConsoleValue args[21] = { };
args[0].setString(method.c_str());
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++ )
{
@ -838,7 +836,7 @@ SimGroup* SimGroup::deepClone()
//-----------------------------------------------------------------------------
bool SimGroup::processArguments(S32, ConsoleValueRef *argv)
bool SimGroup::processArguments(S32, ConsoleValue *argv)
{
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
/// in this set and its children.
@ -464,7 +464,7 @@ class SimGroup: public SimSet
virtual SimObject* findObject(const char* name);
virtual void onRemove();
virtual bool processArguments( S32 argc, ConsoleValueRef *argv );
virtual bool processArguments( S32 argc, ConsoleValue *argv );
virtual SimObject* getObject(const S32& index);

View file

@ -39,7 +39,6 @@ StringStack::StringStack()
mStart = 0;
mLen = 0;
mStartStackSize = 0;
mFunctionOffset = 0;
validateBufferSize(8192);
validateArgBufferSize(2048);
dMemset(mBuffer, '\0', mBufferSize);
@ -82,7 +81,7 @@ void StringStack::setIntValue(U32 i)
void StringStack::setFloatValue(F64 v)
{
validateBufferSize(mStart + 32);
dSprintf(mBuffer + mStart, 32, "%g", v);
dSprintf(mBuffer + mStart, 32, "%.9g", v);
mLen = dStrlen(mBuffer + mStart);
}
@ -180,255 +179,3 @@ U32 StringStack::compare()
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.
inline U32 getIntValue()
inline S64 getIntValue()
{
return dAtoi(mBuffer + mStart);
return dAtol(mBuffer + mStart);
}
/// Get a float representation of the top of the stack.
inline F64 getFloatValue()
{
return dAtof(mBuffer + mStart);
return dAtod(mBuffer + mStart);
}
/// Get a string representation of the top of the stack.
@ -138,16 +138,6 @@ struct StringStack
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.
///
/// @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.
U32 compare();
void pushFrame();
void popFrame();
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 ConsoleValueStack CSTK;
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 )
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.
const char* format = "return %s;";
dsize_t len = dStrlen( format ) + dStrlen( evalBuffer );
@ -872,14 +915,14 @@ void TelnetDebugger::evaluateExpression(const char *tag, S32 frame, const char *
// Execute the eval.
CodeBlock *newCodeBlock = new CodeBlock();
const char* result = newCodeBlock->compileExec( NULL, buffer, false, frame );
ConsoleValue result = newCodeBlock->compileExec( NULL, buffer, false, frame );
delete [] buffer;
// Create a new buffer that fits the result.
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 ];
dSprintf( buffer, len, format, tag, result[0] ? result : "\"\"" );
dSprintf( buffer, len, format, tag, result.getString()[0] ? result.getString() : "\"\"" );
send( 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
#include "testing/unitTesting.h"
#include "platform/platform.h"
@ -253,3 +255,4 @@ TEST(Con, execute)
}
#endif
#endif

View file

@ -1,3 +1,4 @@
#if 0
#ifdef TORQUE_TESTS_ENABLED
#include "testing/unitTesting.h"
#include "platform/platform.h"
@ -147,4 +148,5 @@ TEST(EngineAPI, _EngineConsoleExecCallbackHelper)
"All values should be printed in the correct order";
}
#endif
#endif
#endif

View file

@ -428,7 +428,7 @@ S32 dStrlcpy(char *dst, const char *src, dsize_t dstSize)
S32 copyLen = srcLen;
//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)
{
copyLen = dstSize - 1;

View file

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

View file

@ -160,6 +160,7 @@ class Vector
void erase(U32 index, U32 count);
void erase_fast(iterator);
void clear();
void resetAndTreatAsScratchBuffer();
void compact();
void sort(compare_func f);
void fill( const T& value );
@ -529,6 +530,15 @@ template<class T> inline void Vector<T>::clear()
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()
{
resize(mElementCount);

View file

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

View file

@ -158,7 +158,7 @@ public:
virtual bool onAdd();
virtual void onRemove();
virtual void inspectPostApply();
virtual bool processArguments(S32 argc, ConsoleValueRef *argv);
virtual bool processArguments(S32 argc, ConsoleValue *argv);
// NetObject
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
GFont* font = profile->mFont;
ConsoleValue val;
val.setFloatValue(row->mValue);
const char* stringVal = val.getStringValue();
char stringVal[32];
dSprintf(stringVal, 32, "%f", row->mValue);
S32 textWidth = font->getStrWidth(stringVal);
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.
// this is an optional parameter that may be specified at

View file

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

View file

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

View file

@ -318,7 +318,8 @@ void GuiInspectorField::setData( const char* data, bool callbacks )
{
char buffer[ 2048 ];
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
|| type == TypeF32Vector
@ -353,9 +354,10 @@ void GuiInspectorField::setData( const char* data, bool callbacks )
char buffer[ 2048 ];
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 );
Con::evaluatef("$f=0;$v=0;");
if( !isFirst )
strNew.append( ' ' );
strNew.append( newComponentVal );

View file

@ -120,12 +120,14 @@ void PopupMenu::handleSelectEvent(U32 popID, U32 command)
//-----------------------------------------------------------------------------
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 )
{
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.
void WorldEditor::ignoreObjClass( U32 argc, ConsoleValueRef *argv )
void WorldEditor::ignoreObjClass( U32 argc, ConsoleValue *argv )
{
for(S32 i = 2; i < argc; i++)
{
ClassInfo::Entry * entry = getClassEntry(argv[i]);
ClassInfo::Entry * entry = getClassEntry(argv[i].getString());
if(entry)
entry->mIgnoreCollision = true;
else
{
entry = new ClassInfo::Entry;
entry->mName = StringTable->insert(argv[i]);
entry->mName = StringTable->insert(argv[i].getString());
entry->mIgnoreCollision = true;
if(!addClassEntry(entry))
delete entry;

View file

@ -76,7 +76,7 @@ class WorldEditor : public EditTSCtrl
Point3F p2;
};
void ignoreObjClass(U32 argc, ConsoleValueRef* argv);
void ignoreObjClass(U32 argc, ConsoleValue* argv);
void clearIgnoreList();
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
#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
@ -165,8 +169,5 @@ typedef unsigned long U64;
#endif
#endif
// Set GCC noinline
#define TORQUE_NOINLINE __attribute__ ((noinline))
#endif // INCLUDED_TYPES_GCC_H

View file

@ -102,10 +102,18 @@ typedef unsigned _int64 U64;
// disable warning caused by memory layer
// 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)
#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

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 retVal = recurseDumpDirectories(path, "", directoryVector, 0, depth, noBasePath);
bool retVal = recurseDumpDirectories(path, "", directoryVector, -1, depth, noBasePath);
clearExcludedDirectories();
return retVal;
}

View file

@ -55,31 +55,36 @@ DefineEngineStringlyVariadicFunction( mathInit, void, 1, 10, "( ... )"
}
for (argc--, argv++; argc; argc--, argv++)
{
if (dStricmp(*argv, "DETECT") == 0) {
const char* str = (*argv).getString();
if (dStricmp(str, "DETECT") == 0) {
Math::init(0);
return;
}
if (dStricmp(*argv, "C") == 0) {
if (dStricmp(str, "C") == 0) {
properties |= CPU_PROP_C;
continue;
}
if (dStricmp(*argv, "FPU") == 0) {
if (dStricmp(str, "FPU") == 0) {
properties |= CPU_PROP_FPU;
continue;
}
if (dStricmp(*argv, "MMX") == 0) {
if (dStricmp(str, "MMX") == 0) {
properties |= CPU_PROP_MMX;
continue;
}
if (dStricmp(*argv, "3DNOW") == 0) {
if (dStricmp(str, "3DNOW") == 0) {
properties |= CPU_PROP_3DNOW;
continue;
}
if (dStricmp(*argv, "SSE") == 0) {
if (dStricmp(str, "SSE") == 0) {
properties |= CPU_PROP_SSE;
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);
}

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
// usage of the SFXSystem functions.
@ -791,6 +791,9 @@ void SFXSource::_setStatus( SFXStatus status )
void SFXSource::_updateVolume( const MatrixF& listener )
{
if (!mDescription)
return;
// Handle fades (compute mFadedVolume).
mFadedVolume = mPreFadeVolume;
@ -919,13 +922,19 @@ void SFXSource::_updateVolume( const MatrixF& listener )
void SFXSource::_updatePitch()
{
if (!mDescription)
return;
mEffectivePitch = mModulativePitch * mPitch;
}
//-----------------------------------------------------------------------------
void SFXSource::_updatePriority()
{
{
if (!mDescription)
return;
mEffectivePriority = mPriority * mModulativePriority;
SFXSource* group = getSourceGroup();

View file

@ -382,7 +382,7 @@ class SFXSource : public SimGroup
/// We overload this to disable creation of
/// a source via script 'new'.
virtual bool processArguments( S32 argc, ConsoleValueRef *argv );
virtual bool processArguments( S32 argc, ConsoleValue *argv );
// Console getters/setters.
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 ) )
{

View file

@ -61,7 +61,7 @@ class SFXTrack : public SimDataBlock
StringTableEntry mParameters[ MaxNumParameters ];
/// 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:

View file

@ -238,7 +238,7 @@ void CustomFeatureGLSL::addVertTexCoord(String name)
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
Vector<Var*> varList;
@ -246,7 +246,7 @@ void CustomFeatureGLSL::writeLine(String format, S32 argc, ConsoleValueRef * arg
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());
if (!newVar)
{
@ -304,7 +304,7 @@ void CustomFeatureGLSL::writeLine(String format, S32 argc, ConsoleValueRef * arg
if (!newVar)
{
//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;
}
}

View file

@ -128,5 +128,5 @@ public:
void addTexture(String name, String type, String samplerState, U32 arraySize);
void addConnector(String name, String type, String elementName);
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);
}
void CustomFeatureHLSL::writeLine(String format, S32 argc, ConsoleValueRef * argv)
void CustomFeatureHLSL::writeLine(String format, S32 argc, ConsoleValue *argv)
{
//do the var/arg fetching here
Vector<Var*> varList;
@ -263,7 +263,7 @@ void CustomFeatureHLSL::writeLine(String format, S32 argc, ConsoleValueRef * arg
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());
if (!newVar)
{
@ -321,7 +321,7 @@ void CustomFeatureHLSL::writeLine(String format, S32 argc, ConsoleValueRef * arg
if (!newVar)
{
//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;
}
}

View file

@ -128,5 +128,5 @@ public:
void addTexture(String name, String type, String samplerState, U32 arraySize);
void addConnector(String name, String type, String elementName);
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;
}
void CustomShaderFeatureData::writeLine(String format, S32 argc, ConsoleValueRef* argv)
void CustomShaderFeatureData::writeLine(String format, S32 argc, ConsoleValue* argv)
{
#ifdef TORQUE_D3D11
if (GFX->getAdapterType() == GFXAdapterType::Direct3D11)
@ -236,7 +236,7 @@ DefineEngineStringlyVariadicMethod(CustomShaderFeatureData, writeLine, void, 3,
"@param args Zero or more arguments for the method.\n"
"@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), (""), "")

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -75,7 +75,7 @@ singleton shaderData( AL_VectorLightShader )
pixVersion = 3.0;
};
new CustomMaterial( AL_VectorLightMaterial )
singleton CustomMaterial( AL_VectorLightMaterial )
{
shader = AL_VectorLightShader;
stateBlock = AL_VectorLightState;
@ -149,7 +149,7 @@ singleton shaderData( AL_PointLightShader )
pixVersion = 3.0;
};
new CustomMaterial( AL_PointLightMaterial )
singleton CustomMaterial( AL_PointLightMaterial )
{
shader = AL_PointLightShader;
stateBlock = AL_ConvexLightState;
@ -186,7 +186,7 @@ singleton shaderData( AL_SpotLightShader )
pixVersion = 3.0;
};
new CustomMaterial( AL_SpotLightMaterial )
singleton CustomMaterial( AL_SpotLightMaterial )
{
shader = AL_SpotLightShader;
stateBlock = AL_ConvexLightState;
@ -205,7 +205,7 @@ new CustomMaterial( AL_SpotLightMaterial )
/// This material is used for generating deferred
/// 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
// won't create a proper material instance.
@ -219,7 +219,7 @@ new Material( AL_DefaultDeferredMaterial )
/// This material is used for generating shadow
/// 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
// won't create a proper material instance.
@ -255,7 +255,7 @@ singleton shaderData( AL_ParticlePointLightShader )
pixVersion = 3.0;
};
new CustomMaterial( AL_ParticlePointLightMaterial )
singleton CustomMaterial( AL_ParticlePointLightMaterial )
{
shader = AL_ParticlePointLightShader;
stateBlock = AL_ConvexLightState;

View file

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

View file

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

View file

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

View file

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

View file

@ -43,11 +43,11 @@ function popFront(%list, %delim)
function parseArgs()
{
for ($i = 1; $i < $Game::argc ; $i++)
for (%i = 1; %i < $Game::argc ; %i++)
{
$arg = $Game::argv[$i];
$nextArg = $Game::argv[$i+1];
$hasNextArg = $Game::argc - $i > 1;
$arg = $Game::argv[%i];
$nextArg = $Game::argv[%i+1];
$hasNextArg = $Game::argc - %i > 1;
$logModeSpecified = false;
// Check for dedicated run
@ -55,7 +55,7 @@ function parseArgs()
{
$userDirs = $defaultGame;
$dirCount = 1;
$isDedicated = true;
%isDedicated = true;
}*/
switch$ ($arg)
@ -64,15 +64,15 @@ function parseArgs()
case "-dedicated":
$userDirs = $defaultGame;
$dirCount = 1;
$isDedicated = true;
%isDedicated = true;
$Server::Dedicated = true;
enableWinConsole(true);
$argUsed[%i]++;
//--------------------
case "-mission":
$argUsed[%i]++;
if ($hasNextArg)
if ($hasNextArg)
{
$missionArg = $nextArg;
$argUsed[%i+1]++;
@ -84,7 +84,7 @@ function parseArgs()
//--------------------
case "-connect":
$argUsed[%i]++;
if ($hasNextArg)
if ($hasNextArg)
{
$JoinGameAddress = $nextArg;
$argUsed[%i+1]++;
@ -93,10 +93,10 @@ function parseArgs()
else
error("Error: Missing Command Line argument. Usage: -connect <ip_address>");
//--------------------
case "-log":
$argUsed[$i]++;
$argUsed[%i]++;
if ($hasNextArg)
{
// Turn on console logging
@ -107,22 +107,22 @@ function parseArgs()
}
setLogMode($nextArg);
$logModeSpecified = true;
$argUsed[$i+1]++;
$i++;
$argUsed[%i+1]++;
%i++;
}
else
error("Error: Missing Command Line argument. Usage: -log <Mode: 0,1,2>");
//--------------------
case "-dir":
$argUsed[$i]++;
$argUsed[%i]++;
if ($hasNextArg)
{
// Append the mod to the end of the current list
$userDirs = strreplace($userDirs, $nextArg, "");
$userDirs = pushFront($userDirs, $nextArg, ";");
$argUsed[$i+1]++;
$i++;
$argUsed[%i+1]++;
%i++;
$dirCount++;
}
else
@ -130,15 +130,15 @@ function parseArgs()
//--------------------
// changed the default behavior of this command line arg. It now
// 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
case "-game":
$argUsed[$i]++;
$argUsed[%i]++;
if ($hasNextArg)
{
// Set the selected dir --NOTE: we no longer allow tools with this argument
/*
if( $isDedicated )
/*
if( %isDedicated )
{
$userDirs = $nextArg;
$dirCount = 1;
@ -151,8 +151,8 @@ function parseArgs()
*/
$userDirs = $nextArg;
$dirCount = 1;
$argUsed[$i+1]++;
$i++;
$argUsed[%i+1]++;
%i++;
error($userDirs);
}
else
@ -161,121 +161,121 @@ function parseArgs()
//--------------------
case "-console":
enableWinConsole(true);
$argUsed[$i]++;
$argUsed[%i]++;
//--------------------
case "-jSave":
$argUsed[$i]++;
$argUsed[%i]++;
if ($hasNextArg)
{
echo("Saving event log to journal: " @ $nextArg);
saveJournal($nextArg);
$argUsed[$i+1]++;
$i++;
$argUsed[%i+1]++;
%i++;
}
else
error("Error: Missing Command Line argument. Usage: -jSave <journal_name>");
//--------------------
case "-jPlay":
$argUsed[$i]++;
$argUsed[%i]++;
if ($hasNextArg)
{
playJournal($nextArg);
$argUsed[$i+1]++;
$i++;
$argUsed[%i+1]++;
%i++;
}
else
error("Error: Missing Command Line argument. Usage: -jPlay <journal_name>");
//--------------------
case "-jPlayToVideo":
$argUsed[$i]++;
$argUsed[%i]++;
if ($hasNextArg)
{
$VideoCapture::journalName = $nextArg;
$VideoCapture::captureFromJournal = true;
$argUsed[$i+1]++;
$i++;
$argUsed[%i+1]++;
%i++;
}
else
error("Error: Missing Command Line argument. Usage: -jPlayToVideo <journal_name>");
//--------------------
case "-vidCapFile":
$argUsed[$i]++;
$argUsed[%i]++;
if ($hasNextArg)
{
$VideoCapture::fileName = $nextArg;
$argUsed[$i+1]++;
$i++;
$argUsed[%i+1]++;
%i++;
}
else
error("Error: Missing Command Line argument. Usage: -vidCapFile <ouput_video_name>");
//--------------------
case "-vidCapFPS":
$argUsed[$i]++;
$argUsed[%i]++;
if ($hasNextArg)
{
$VideoCapture::fps = $nextArg;
$argUsed[$i+1]++;
$i++;
$argUsed[%i+1]++;
%i++;
}
else
error("Error: Missing Command Line argument. Usage: -vidCapFPS <ouput_video_framerate>");
//--------------------
case "-vidCapEncoder":
$argUsed[$i]++;
$argUsed[%i]++;
if ($hasNextArg)
{
$VideoCapture::encoder = $nextArg;
$argUsed[$i+1]++;
$i++;
$argUsed[%i+1]++;
%i++;
}
else
error("Error: Missing Command Line argument. Usage: -vidCapEncoder <ouput_video_encoder>");
//--------------------
case "-vidCapWidth":
$argUsed[$i]++;
$argUsed[%i]++;
if ($hasNextArg)
{
$videoCapture::width = $nextArg;
$argUsed[$i+1]++;
$i++;
$argUsed[%i+1]++;
%i++;
}
else
error("Error: Missing Command Line argument. Usage: -vidCapWidth <ouput_video_width>");
//--------------------
case "-vidCapHeight":
$argUsed[$i]++;
$argUsed[%i]++;
if ($hasNextArg)
{
$videoCapture::height = $nextArg;
$argUsed[$i+1]++;
$i++;
$argUsed[%i+1]++;
%i++;
}
else
error("Error: Missing Command Line argument. Usage: -vidCapHeight <ouput_video_height>");
//--------------------
case "-level":
$argUsed[$i]++;
$argUsed[%i]++;
if ($hasNextArg)
{
%hasExt = strpos($nextArg, ".mis");
if(%hasExt == -1)
{
$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");
if(%hasExt == -1)
{
$levelToLoad = $levelToLoad @ $arg @ " ";
@ -285,14 +285,14 @@ function parseArgs()
break;
}
}
}
}
else
{
$levelToLoad = $nextArg;
}
$argUsed[$i+1]++;
$i++;
$argUsed[%i+1]++;
%i++;
}
else
error("Error: Missing Command Line argument. Usage: -level <level file name (no path), with or without extension>");
@ -300,33 +300,33 @@ function parseArgs()
//-------------------
case "-worldeditor":
$startWorldEditor = true;
$argUsed[$i]++;
$argUsed[%i]++;
//-------------------
case "-guieditor":
$startGUIEditor = true;
$argUsed[$i]++;
$argUsed[%i]++;
//-------------------
case "-help":
$displayHelp = true;
$argUsed[$i]++;
$argUsed[%i]++;
//-------------------
case "-compileAll":
$compileAll = true;
$argUsed[$i]++;
$argUsed[%i]++;
//-------------------
case "-compileTools":
$compileTools = true;
$argUsed[$i]++;
$argUsed[%i]++;
//-------------------
case "-genScript":
$genScript = true;
$argUsed[$i]++;
$argUsed[%i]++;
case "-fullscreen":
$cliFullscreen = true;
$argUsed[%i]++;
@ -357,36 +357,36 @@ function parseArgs()
else
error("Error: Missing Command Line argument. Usage: -prefs <path/script." @ $TorqueScriptFileExtension @ ">");
//-------------------
default:
$argUsed[$i]++;
$argUsed[%i]++;
if($userDirs $= "")
$userDirs = $arg;
}
}
//-----------------------------------------------
// Play journal to video file?
if ($VideoCapture::captureFromJournal && $VideoCapture::journalName !$= "")
{
{
if ($VideoCapture::fileName $= "")
$VideoCapture::fileName = $VideoCapture::journalName;
$VideoCapture::fileName = $VideoCapture::journalName;
if ($VideoCapture::encoder $= "")
$VideoCapture::encoder = "THEORA";
if ($VideoCapture::fps $= "")
$VideoCapture::fps = 30;
if ($videoCapture::width $= "")
$videoCapture::width = 0;
if ($videoCapture::height $= "")
$videoCapture::height = 0;
playJournalToVideo( $VideoCapture::journalName, $VideoCapture::fileName,
$VideoCapture::encoder, $VideoCapture::fps,
playJournalToVideo( $VideoCapture::journalName, $VideoCapture::fileName,
$VideoCapture::encoder, $VideoCapture::fps,
$videoCapture::width SPC $videoCapture::height );
}
}
}

View file

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

View file

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

View file

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

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