mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-02-12 19:31:41 +00:00
Merge pull request #1004 from lukaspj/console-refactor
Console Refactor
This commit is contained in:
commit
ec8a8290b4
89 changed files with 1943 additions and 1733 deletions
|
|
@ -33,12 +33,12 @@ endif (APPLE)
|
|||
|
||||
# When on Windows, we need to link against winsock and windows codecs
|
||||
if (WIN32)
|
||||
set(TORQUE_SOURCE_FILES ${TORQUE_SOURCE_FILES} ${TORQUE_PLATFORM_WIN_SOURCES})
|
||||
set(TORQUE_SOURCE_FILES ${TORQUE_SOURCE_FILES} ${TORQUE_PLATFORM_WIN_SOURCES})
|
||||
endif (WIN32)
|
||||
|
||||
# Linux requires X11 & freetype
|
||||
if (UNIX AND NOT APPLE)
|
||||
set(TORQUE_SOURCE_FILES ${TORQUE_SOURCE_FILES} ${TORQUE_PLATFORM_X11_SOURCES})
|
||||
set(TORQUE_SOURCE_FILES ${TORQUE_SOURCE_FILES} ${TORQUE_PLATFORM_X11_SOURCES})
|
||||
find_package(Freetype REQUIRED)
|
||||
set(TORQUE_INCLUDE_DIRECTORIES ${TORQUE_INCLUDE_DIRECTORIES} ${FREETYPE_INCLUDE_DIRS})
|
||||
endif (UNIX AND NOT APPLE)
|
||||
|
|
@ -50,11 +50,12 @@ torqueAddSourceDirectories("app" "app/net")
|
|||
|
||||
# Handle console
|
||||
torqueAddSourceDirectories("console")
|
||||
torqueAddSourceDirectories("console/torquescript")
|
||||
|
||||
# Handle Platform
|
||||
torqueAddSourceDirectories("platform" "platform/threads" "platform/async"
|
||||
"platform/input" "platform/output")
|
||||
|
||||
|
||||
torqueAddSourceDirectories("platform/nativeDialogs")
|
||||
|
||||
# Handle T3D
|
||||
|
|
@ -291,7 +292,7 @@ endforeach()
|
|||
# Prepare Windows RC file
|
||||
if (WIN32)
|
||||
set(APPLICATION_ICON_PATH "${CMAKE_SOURCE_DIR}/Tools/CMake/torque.ico")
|
||||
|
||||
|
||||
configure_file("${CMAKE_SOURCE_DIR}/Tools/CMake/torque-win.rc.in" "${CMAKE_BINARY_DIR}/temp/torque.rc")
|
||||
set(TORQUE_SOURCE_FILES ${TORQUE_SOURCE_FILES} "${CMAKE_BINARY_DIR}/temp/torque.rc")
|
||||
endif (WIN32)
|
||||
|
|
@ -300,7 +301,7 @@ endif (WIN32)
|
|||
if (APPLE)
|
||||
set(TORQUE_SOURCE_FILES ${TORQUE_SOURCE_FILES} ${TORQUE_PLATFORM_MAC_SOURCES} "${CMAKE_SOURCE_DIR}/Tools/CMake/torque.icns")
|
||||
set_source_files_properties("${CMAKE_SOURCE_DIR}/Tools/CMake/torque.icns" PROPERTIES MACOSX_PACKAGE_LOCATION "Resources")
|
||||
|
||||
|
||||
set(EXECUTABLE_NAME "${TORQUE_APP_NAME}")
|
||||
configure_file("${CMAKE_SOURCE_DIR}/Tools/CMake/Info.plist.in" "${CMAKE_BINARY_DIR}/temp/Info.plist" COPYONLY)
|
||||
endif (APPLE)
|
||||
|
|
@ -348,25 +349,25 @@ if (APPLE)
|
|||
set(CMAKE_XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "@executable_path/../Frameworks")
|
||||
elseif (WIN32)
|
||||
add_executable(${TORQUE_APP_NAME} WIN32 ${TORQUE_SOURCE_FILES})
|
||||
|
||||
|
||||
set(TORQUE_CXX_FLAGS_COMMON_DEFAULT "-DUNICODE -D_UNICODE -D_CRT_SECURE_NO_WARNINGS /MP /Ob2 /Oi /Ot /Oy /GT /Zi /W4 /nologo /GF /EHsc /GS- /Gy- /Qpar- /fp:precise /fp:except- /GR /Zc:wchar_t-" )
|
||||
if( TORQUE_CPU_X32 )
|
||||
set(TORQUE_CXX_FLAGS_COMMON_DEFAULT "${TORQUE_CXX_FLAGS_COMMON_DEFAULT} /arch:SSE2")
|
||||
endif()
|
||||
set(TORQUE_CXX_FLAGS_COMMON ${TORQUE_CXX_FLAGS_COMMON_DEFAULT} CACHE STRING "")
|
||||
mark_as_advanced(TORQUE_CXX_FLAGS_COMMON)
|
||||
|
||||
|
||||
set(TORQUE_CXX_FLAGS_EXECUTABLES "/wd4018 /wd4100 /wd4121 /wd4127 /wd4130 /wd4244 /wd4245 /wd4389 /wd4511 /wd4512 /wd4800 /wd4995" CACHE STRING "")
|
||||
mark_as_advanced(TORQUE_CXX_FLAGS_EXECUTABLES)
|
||||
|
||||
|
||||
set(TORQUE_CXX_FLAGS "${TORQUE_CXX_FLAGS_COMMON_DEFAULT} ${TORQUE_CXX_FLAGS_EXECUTABLES}" CACHE STRING "")
|
||||
mark_as_advanced(TORQUE_CXX_FLAGS)
|
||||
|
||||
|
||||
# NOTE: On Windows, /Zc:wchar_t- is necessary otherwise you get unicode errors
|
||||
set_target_properties(${TORQUE_APP_NAME} PROPERTIES COMPILE_FLAGS "${TORQUE_CXX_FLAGS}")
|
||||
else()
|
||||
add_executable(${TORQUE_APP_NAME} ${TORQUE_SOURCE_FILES})
|
||||
|
||||
|
||||
# NOTE: On Linux, we set the rpath to ./ so that shared objects next to the executable are used
|
||||
set_target_properties(${TORQUE_APP_NAME} PROPERTIES LINK_FLAGS "-Wl,-rpath,./")
|
||||
endif()
|
||||
|
|
@ -423,9 +424,9 @@ if (UNIX)
|
|||
# For eg. OSX some links are not valid targets - for example frameworks provided by OS
|
||||
if (TARGET ${GAME_LINK_LIBRARY})
|
||||
get_target_property(LINK_LIBRARY_TYPE ${GAME_LINK_LIBRARY} TYPE)
|
||||
|
||||
|
||||
# Only pay attention to shared libraries and make them output to the app resources
|
||||
if ("${LINK_LIBRARY_TYPE}" STREQUAL "SHARED_LIBRARY")
|
||||
if ("${LINK_LIBRARY_TYPE}" STREQUAL "SHARED_LIBRARY")
|
||||
if (APPLE)
|
||||
set_target_properties(${GAME_LINK_LIBRARY} PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${TORQUE_APP_GAME_DIRECTORY}/${TORQUE_APP_NAME}.app/Contents/Frameworks")
|
||||
else()
|
||||
|
|
@ -434,4 +435,4 @@ if (UNIX)
|
|||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
endif (UNIX)
|
||||
endif (UNIX)
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@
|
|||
#endif
|
||||
|
||||
// Debug Profiling.
|
||||
#include "console/script.h"
|
||||
#include "platform/profiler.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -140,7 +141,7 @@ void CubemapAsset::initializeAsset()
|
|||
|
||||
mScriptPath = getOwned() ? expandAssetFilePath(mScriptFile) : mScriptPath;
|
||||
|
||||
if (Torque::FS::IsScriptFile(mScriptPath))
|
||||
if (Con::isScriptFile(mScriptPath))
|
||||
Con::executeFile(mScriptPath, false, false);
|
||||
}
|
||||
|
||||
|
|
@ -148,7 +149,7 @@ void CubemapAsset::onAssetRefresh()
|
|||
{
|
||||
mScriptPath = getOwned() ? expandAssetFilePath(mScriptFile) : mScriptPath;
|
||||
|
||||
if (Torque::FS::IsScriptFile(mScriptPath))
|
||||
if (Con::isScriptFile(mScriptPath))
|
||||
Con::executeFile(mScriptPath, false, false);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@
|
|||
#endif
|
||||
|
||||
// Debug Profiling.
|
||||
#include "console/script.h"
|
||||
#include "platform/profiler.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -118,12 +119,12 @@ void GUIAsset::initializeAsset()
|
|||
{
|
||||
mScriptPath = getOwned() ? expandAssetFilePath(mScriptFile) : mScriptPath;
|
||||
|
||||
if (Torque::FS::IsScriptFile(mScriptPath))
|
||||
if (Con::isScriptFile(mScriptPath))
|
||||
Con::executeFile(mScriptPath, false, false);
|
||||
|
||||
mGUIPath = getOwned() ? expandAssetFilePath(mGUIFile) : mGUIPath;
|
||||
|
||||
if (Torque::FS::IsScriptFile(mGUIPath))
|
||||
if (Con::isScriptFile(mGUIPath))
|
||||
Con::executeFile(mGUIPath, false, false);
|
||||
}
|
||||
|
||||
|
|
@ -131,12 +132,12 @@ void GUIAsset::onAssetRefresh()
|
|||
{
|
||||
mScriptPath = getOwned() ? expandAssetFilePath(mScriptFile) : mScriptPath;
|
||||
|
||||
if (Torque::FS::IsScriptFile(mScriptPath))
|
||||
if (Con::isScriptFile(mScriptPath))
|
||||
Con::executeFile(mScriptPath, false, false);
|
||||
|
||||
mGUIPath = getOwned() ? expandAssetFilePath(mGUIFile) : mGUIPath;
|
||||
|
||||
if (Torque::FS::IsScriptFile(mGUIPath))
|
||||
if (Con::isScriptFile(mGUIPath))
|
||||
Con::executeFile(mGUIPath, false, false);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@
|
|||
#endif
|
||||
|
||||
// Debug Profiling.
|
||||
#include "console/script.h"
|
||||
#include "platform/profiler.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -134,7 +135,7 @@ void GameObjectAsset::initializeAsset()
|
|||
//Ensure we have an expanded filepath
|
||||
mScriptPath = getOwned() ? expandAssetFilePath(mScriptFile) : mScriptPath;
|
||||
|
||||
if (Torque::FS::IsScriptFile(mScriptPath))
|
||||
if (Con::isScriptFile(mScriptPath))
|
||||
Con::executeFile(mScriptPath, false, false);
|
||||
|
||||
mTAMLPath = getOwned() ? expandAssetFilePath(mTAMLFile) : mTAMLPath;
|
||||
|
|
@ -145,7 +146,7 @@ void GameObjectAsset::onAssetRefresh()
|
|||
//Ensure we have an expanded filepath
|
||||
mScriptPath = getOwned() ? expandAssetFilePath(mScriptFile) : mScriptPath;
|
||||
|
||||
if (Torque::FS::IsScriptFile(mScriptPath))
|
||||
if (Con::isScriptFile(mScriptPath))
|
||||
Con::executeFile(mScriptPath, false, false);
|
||||
|
||||
mTAMLPath = getOwned() ? expandAssetFilePath(mTAMLFile) : mTAMLPath;
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@
|
|||
#include "assets/assetPtr.h"
|
||||
#endif
|
||||
|
||||
#include "console/script.h"
|
||||
#include "T3D/assets/assetImporter.h"
|
||||
|
||||
StringTableEntry MaterialAsset::smNoMaterialAssetFallback = NULL;
|
||||
|
|
@ -179,7 +180,7 @@ void MaterialAsset::initializeAsset()
|
|||
{
|
||||
mLoadedState = EmbeddedDefinition;
|
||||
}
|
||||
else if (Torque::FS::IsScriptFile(mScriptPath))
|
||||
else if (Con::isScriptFile(mScriptPath))
|
||||
{
|
||||
if (!Sim::findObject(mMatDefinitionName))
|
||||
{
|
||||
|
|
@ -211,7 +212,7 @@ void MaterialAsset::onAssetRefresh()
|
|||
return;
|
||||
}
|
||||
|
||||
if (Torque::FS::IsScriptFile(mScriptPath))
|
||||
if (Con::isScriptFile(mScriptPath))
|
||||
{
|
||||
//Since we're refreshing, we can assume that the file we're executing WILL have an existing definition.
|
||||
//But that definition, whatever it is, is the 'correct' one, so we enable the Replace Existing behavior
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@
|
|||
#endif
|
||||
|
||||
// Debug Profiling.
|
||||
#include "console/script.h"
|
||||
#include "platform/profiler.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -137,7 +138,7 @@ void PostEffectAsset::initializeAsset()
|
|||
mHLSLShaderPath = getOwned() ? expandAssetFilePath(mHLSLShaderFile) : mHLSLShaderPath;
|
||||
mGLSLShaderPath = getOwned() ? expandAssetFilePath(mGLSLShaderFile) : mGLSLShaderPath;
|
||||
|
||||
if (Torque::FS::IsScriptFile(mScriptPath))
|
||||
if (Con::isScriptFile(mScriptPath))
|
||||
Con::executeFile(mScriptPath, false, false);
|
||||
}
|
||||
|
||||
|
|
@ -147,7 +148,7 @@ void PostEffectAsset::onAssetRefresh()
|
|||
mHLSLShaderPath = getOwned() ? expandAssetFilePath(mHLSLShaderFile) : mHLSLShaderPath;
|
||||
mGLSLShaderPath = getOwned() ? expandAssetFilePath(mGLSLShaderFile) : mGLSLShaderPath;
|
||||
|
||||
if (Torque::FS::IsScriptFile(mScriptPath))
|
||||
if (Con::isScriptFile(mScriptPath))
|
||||
Con::executeFile(mScriptPath, false, false);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@
|
|||
#endif
|
||||
|
||||
// Debug Profiling.
|
||||
#include "console/script.h"
|
||||
#include "platform/profiler.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -140,7 +141,7 @@ void ScriptAsset::initializeAsset()
|
|||
|
||||
mScriptPath = getOwned() ? expandAssetFilePath(mScriptFile) : mScriptPath;
|
||||
|
||||
if (Torque::FS::IsScriptFile(mScriptPath))
|
||||
if (Con::isScriptFile(mScriptPath))
|
||||
{
|
||||
//We're initialized properly, so we'll go ahead and kick along any dependencies we may have as well
|
||||
AssetManager::typeAssetDependsOnHash::Iterator assetDependenciesItr = mpOwningAssetManager->getDependedOnAssets()->find(mpAssetDefinition->mAssetId);
|
||||
|
|
@ -170,7 +171,7 @@ void ScriptAsset::onAssetRefresh()
|
|||
{
|
||||
mScriptPath = getOwned() ? expandAssetFilePath(mScriptFile) : mScriptPath;
|
||||
|
||||
if (Torque::FS::IsScriptFile(mScriptPath))
|
||||
if (Con::isScriptFile(mScriptPath))
|
||||
{
|
||||
//Refresh any dependencies we may have
|
||||
for (U32 i = 0; i < mScriptAssetDependencies.size(); i++)
|
||||
|
|
@ -215,7 +216,7 @@ bool ScriptAsset::execScript()
|
|||
if (handle)
|
||||
return true;
|
||||
|
||||
if (Torque::FS::IsScriptFile(mScriptPath))
|
||||
if (Con::isScriptFile(mScriptPath))
|
||||
{
|
||||
return Con::executeFile(mScriptPath, false, false);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@
|
|||
#include "assets/assetPtr.h"
|
||||
#endif
|
||||
|
||||
#include "console/script.h"
|
||||
#include "T3D/assets/assetImporter.h"
|
||||
|
||||
StringTableEntry TerrainMaterialAsset::smNoTerrainMaterialAssetFallback = NULL;
|
||||
|
|
@ -182,7 +183,7 @@ void TerrainMaterialAsset::initializeAsset()
|
|||
{
|
||||
mLoadedState = EmbeddedDefinition;
|
||||
}
|
||||
else if (Torque::FS::IsScriptFile(mScriptPath))
|
||||
else if (Con::isScriptFile(mScriptPath))
|
||||
{
|
||||
if (!Sim::findObject(mMatDefinitionName))
|
||||
{
|
||||
|
|
@ -214,7 +215,7 @@ void TerrainMaterialAsset::onAssetRefresh()
|
|||
return;
|
||||
}
|
||||
|
||||
if (Torque::FS::IsScriptFile(mScriptPath))
|
||||
if (Con::isScriptFile(mScriptPath))
|
||||
{
|
||||
//Since we're refreshing, we can assume that the file we're executing WILL have an existing definition.
|
||||
//But that definition, whatever it is, is the 'correct' one, so we enable the Replace Existing behavior
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#include "console/consoleTypes.h"
|
||||
#include "core/volume.h"
|
||||
#include "console/engineAPI.h"
|
||||
#include "console/script.h"
|
||||
#include "T3D/physics/physicsShape.h"
|
||||
#include "core/util/path.h"
|
||||
|
||||
|
|
@ -344,7 +345,7 @@ void Prefab::_loadFile( bool addFileNotify )
|
|||
if ( mFilename == StringTable->EmptyString())
|
||||
return;
|
||||
|
||||
if ( !Torque::FS::IsScriptFile( mFilename ) )
|
||||
if ( !Con::isScriptFile( mFilename ) )
|
||||
{
|
||||
Con::errorf( "Prefab::_loadFile() - file %s was not found.", mFilename );
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include "console/consoleTypes.h"
|
||||
#include "console/engineAPI.h"
|
||||
#include "collision/boxConvex.h"
|
||||
#include "console/script.h"
|
||||
|
||||
#include "core/stream/bitStream.h"
|
||||
#include "math/mathIO.h"
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
#include "Verve/Core/VDataTable.h"
|
||||
|
||||
#include "console/script.h"
|
||||
#include "console/simObject.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -228,7 +229,7 @@ bool VDataTable::getValue( SimObject *pObject, const String &pFieldName, String
|
|||
case VDataTable::k_TypeExpression :
|
||||
{
|
||||
// Evaluate.
|
||||
pValue = Con::evaluate( fieldValue, false ).getString();
|
||||
pValue = Con::evaluate( fieldValue, false ).value.getString();
|
||||
|
||||
} break;
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#include "Verve/Extension/Script/VScriptEvent.h"
|
||||
|
||||
#include "console/consoleTypes.h"
|
||||
#include "console/script.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
IMPLEMENT_CONOBJECT( VScriptEvent );
|
||||
|
|
|
|||
|
|
@ -26,9 +26,9 @@
|
|||
#include "afx/arcaneFX.h"
|
||||
|
||||
#include "console/engineAPI.h"
|
||||
#include "console/script.h"
|
||||
#include "T3D/gameBase/gameConnection.h"
|
||||
#include "math/mathIO.h"
|
||||
#include "console/compiler.h"
|
||||
|
||||
#include "afx/afxConstraint.h"
|
||||
#include "afx/afxChoreographer.h"
|
||||
|
|
@ -108,12 +108,11 @@ bool afxChoreographerData::preload(bool server, String &errorStr)
|
|||
|
||||
if (!server && client_script_file != ST_NULLSTRING)
|
||||
{
|
||||
Compiler::gSyntaxError = false;
|
||||
Con::evaluate(avar("exec(\"%s\");", client_script_file), false, 0);
|
||||
if (Compiler::gSyntaxError)
|
||||
Con::EvalResult result = Con::evaluate(avar("exec(\"%s\");", client_script_file), false, 0);
|
||||
|
||||
if (!result.valid)
|
||||
{
|
||||
Con::errorf("afxChoreographerData: failed to exec clientScriptFile \"%s\" -- syntax error", client_script_file);
|
||||
Compiler::gSyntaxError = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -31,8 +31,9 @@
|
|||
#include "T3D/gameBase/gameProcess.h"
|
||||
#include "T3D/player.h"
|
||||
#include "math/mathUtils.h"
|
||||
#include "console/compiler.h"
|
||||
|
||||
#include "console/engineAPI.h"
|
||||
#include "console/script.h"
|
||||
|
||||
#include "afx/afxChoreographer.h"
|
||||
#include "afx/afxSelectron.h"
|
||||
|
|
@ -672,7 +673,7 @@ DefineEngineFunction(wasSyntaxError, bool, (),,
|
|||
"for detecting syntax errors after reloading a script.\n\n"
|
||||
"@ingroup AFX")
|
||||
{
|
||||
return Compiler::gSyntaxError;
|
||||
return Con::getLastEvalResult().valid == false;
|
||||
}
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//
|
||||
|
|
|
|||
|
|
@ -26,8 +26,8 @@
|
|||
#include <typeinfo>
|
||||
#include "afx/arcaneFX.h"
|
||||
|
||||
#include "console/compiler.h"
|
||||
#include "T3D/player.h"
|
||||
#include "console/script.h"
|
||||
|
||||
#include "afx/afxEffectDefs.h"
|
||||
#include "afx/afxPhrase.h"
|
||||
|
|
@ -314,13 +314,10 @@ void afxEA_PhraseEffect::trigger_new_phrase()
|
|||
}
|
||||
b[0] = '\0';
|
||||
|
||||
Compiler::gSyntaxError = false;
|
||||
//Con::errorf("EVAL [%s]", avar("%s;", buffer));
|
||||
Con::evaluate(avar("%s;", buffer), false, 0);
|
||||
if (Compiler::gSyntaxError)
|
||||
Con::EvalResult result = Con::evaluate(avar("%s;", buffer), false, 0);
|
||||
if (!result.valid)
|
||||
{
|
||||
Con::errorf("onTriggerCommand \"%s\" -- syntax error", phrase_fx_data->on_trig_cmd);
|
||||
Compiler::gSyntaxError = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@
|
|||
// For the TickMs define... fix this for T2D...
|
||||
#include "T3D/gameBase/processList.h"
|
||||
#include "cinterface/cinterface.h"
|
||||
#include "console/script.h"
|
||||
|
||||
#ifdef TORQUE_ENABLE_VFS
|
||||
#include "platform/platformVFS.h"
|
||||
|
|
|
|||
|
|
@ -107,6 +107,7 @@
|
|||
#include "sim/netInterface.h"
|
||||
|
||||
// cafTODO: breaks T2D
|
||||
#include "console/script.h"
|
||||
#include "T3D/gameBase/gameConnection.h"
|
||||
|
||||
// This is basically the server query protocol version now:
|
||||
|
|
@ -2020,7 +2021,7 @@ static void handleGameInfoRequest( const NetAddress* address, U32 key, U8 flags
|
|||
out->writeString( Con::getVariable( "pref::Server::Info" ) );
|
||||
else
|
||||
writeCString( out, Con::getVariable( "pref::Server::Info" ) );
|
||||
writeLongCString( out, Con::evaluate( "onServerInfoQuery();" ) );
|
||||
writeLongCString( out, Con::executef( "onServerInfoQuery" ) );
|
||||
|
||||
BitStream::sendPacketStream(address);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#include "c_controlInterface.h"
|
||||
|
||||
#include "console/consoleInternal.h"
|
||||
#include "console/engineAPI.h"
|
||||
#include "console/simSet.h"
|
||||
#include "app/mainLoop.h"
|
||||
#include "windowManager/platformWindow.h"
|
||||
|
|
@ -50,7 +51,7 @@ extern "C" {
|
|||
// reset the engine, unloading any current level and returning to the main menu
|
||||
void torque_reset()
|
||||
{
|
||||
Con::evaluate("disconnect();");
|
||||
Con::executef("disconnect");
|
||||
}
|
||||
|
||||
// initialize Torque 3D including argument handling
|
||||
|
|
@ -119,7 +120,7 @@ extern "C" {
|
|||
// signal an engine shutdown (as with the quit(); console command)
|
||||
void torque_enginesignalshutdown()
|
||||
{
|
||||
Con::evaluate("quit();");
|
||||
Con::executef("quit");
|
||||
}
|
||||
|
||||
// shutdown the engine
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
#include "cinterface.h"
|
||||
|
||||
#include "console/compiler.h"
|
||||
#include "windowManager/platformWindow.h"
|
||||
|
||||
CInterface& CInterface::GetCInterface()
|
||||
|
|
|
|||
|
|
@ -28,16 +28,16 @@
|
|||
#include "console/consoleObject.h"
|
||||
#include "console/consoleParser.h"
|
||||
#include "core/stream/fileStream.h"
|
||||
#include "console/ast.h"
|
||||
#include "core/tAlgorithm.h"
|
||||
#include "console/consoleTypes.h"
|
||||
#include "console/telnetDebugger.h"
|
||||
#include "console/simBase.h"
|
||||
#include "console/compiler.h"
|
||||
#include "console/stringStack.h"
|
||||
#include "console/ICallMethod.h"
|
||||
#include "console/engineAPI.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "returnBuffer.h"
|
||||
#include "platform/threads/mutex.h"
|
||||
#include "core/util/journal/journal.h"
|
||||
#include "cinterface/cinterface.h"
|
||||
|
|
@ -72,13 +72,10 @@ char* ConsoleValue::convertToBuffer() const
|
|||
|
||||
const char* ConsoleValue::getConsoleData() const
|
||||
{
|
||||
return Con::getData(type, ct->dataPtr, 0, ct->enumTable);
|
||||
return Con::getData(ct->consoleType, ct->dataPtr, 0, ct->enumTable);
|
||||
}
|
||||
|
||||
ConsoleDocFragment* ConsoleDocFragment::smFirst;
|
||||
ExprEvalState gEvalState;
|
||||
StmtNode *gStatementList;
|
||||
StmtNode *gAnonFunctionList;
|
||||
U32 gAnonFunctionID = 0;
|
||||
ConsoleConstructor *ConsoleConstructor::mFirst = NULL;
|
||||
bool gWarnUndefinedScriptVariables;
|
||||
|
|
@ -565,7 +562,7 @@ U32 tabComplete(char* inputBuffer, U32 cursorPos, U32 maxResultLength, bool forw
|
|||
// In the global namespace, we can complete on global vars as well as functions.
|
||||
if (inputBuffer[completionBaseStart] == '$')
|
||||
{
|
||||
newText = gEvalState.globalVars.tabComplete(inputBuffer + completionBaseStart, completionBaseLen, forwardTab);
|
||||
newText = gGlobalVars.tabComplete(inputBuffer + completionBaseStart, completionBaseLen, forwardTab);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -665,9 +662,9 @@ static void _printf(ConsoleLogEntry::Level level, ConsoleLogEntry::Type type, co
|
|||
|
||||
char buffer[8192] = {};
|
||||
U32 offset = 0;
|
||||
if( gEvalState.traceOn && gEvalState.getStackDepth() > 0 )
|
||||
if( gTraceOn && !getFrameStack().empty())
|
||||
{
|
||||
offset = gEvalState.getStackDepth() * 3;
|
||||
offset = getFrameStack().size() * 3;
|
||||
for(U32 i = 0; i < offset; i++)
|
||||
buffer[i] = ' ';
|
||||
}
|
||||
|
|
@ -831,41 +828,25 @@ bool getVariableObjectField(const char *name, SimObject **object, const char **f
|
|||
return false;
|
||||
}
|
||||
|
||||
Dictionary::Entry *getLocalVariableEntry(const char *name)
|
||||
{
|
||||
name = prependPercent(name);
|
||||
return gEvalState.getCurrentFrame().lookup(StringTable->insert(name));
|
||||
}
|
||||
|
||||
Dictionary::Entry *getVariableEntry(const char *name)
|
||||
{
|
||||
name = prependDollar(name);
|
||||
return gEvalState.globalVars.lookup(StringTable->insert(name));
|
||||
return gGlobalVars.lookup(StringTable->insert(name));
|
||||
}
|
||||
|
||||
Dictionary::Entry *addVariableEntry(const char *name)
|
||||
{
|
||||
name = prependDollar(name);
|
||||
return gEvalState.globalVars.add(StringTable->insert(name));
|
||||
return gGlobalVars.add(StringTable->insert(name));
|
||||
}
|
||||
|
||||
Dictionary::Entry *getAddVariableEntry(const char *name)
|
||||
{
|
||||
name = prependDollar(name);
|
||||
StringTableEntry stName = StringTable->insert(name);
|
||||
Dictionary::Entry *entry = gEvalState.globalVars.lookup(stName);
|
||||
Dictionary::Entry *entry = gGlobalVars.lookup(stName);
|
||||
if (!entry)
|
||||
entry = gEvalState.globalVars.add(stName);
|
||||
return entry;
|
||||
}
|
||||
|
||||
Dictionary::Entry *getAddLocalVariableEntry(const char *name)
|
||||
{
|
||||
name = prependPercent(name);
|
||||
StringTableEntry stName = StringTable->insert(name);
|
||||
Dictionary::Entry *entry = gEvalState.getCurrentFrame().lookup(stName);
|
||||
if (!entry)
|
||||
entry = gEvalState.getCurrentFrame().add(stName);
|
||||
entry = gGlobalVars.add(stName);
|
||||
return entry;
|
||||
}
|
||||
|
||||
|
|
@ -881,7 +862,7 @@ void setVariable(const char *name, const char *value)
|
|||
else
|
||||
{
|
||||
name = prependDollar(name);
|
||||
gEvalState.globalVars.setVariable(StringTable->insert(name), value);
|
||||
gGlobalVars.setVariable(StringTable->insert(name), value);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -988,7 +969,7 @@ void stripColorChars(char* line)
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
const char *getObjectTokenField(const char *name)
|
||||
{
|
||||
const char *dot = dStrchr(name, '.');
|
||||
|
|
@ -1046,7 +1027,7 @@ const char *getLocalVariable(const char *name)
|
|||
{
|
||||
name = prependPercent(name);
|
||||
|
||||
return gEvalState.getCurrentFrame().getVariable(StringTable->insert(name));
|
||||
return Con::getCurrentStackFrame()->getVariable(StringTable->insert(name));
|
||||
}
|
||||
|
||||
bool getBoolVariable(const char *varName, bool def)
|
||||
|
|
@ -1099,7 +1080,7 @@ void addVariable( const char *name,
|
|||
void *dptr,
|
||||
const char* usage )
|
||||
{
|
||||
gEvalState.globalVars.addVariable( name, type, dptr, usage );
|
||||
gGlobalVars.addVariable( name, type, dptr, usage );
|
||||
}
|
||||
|
||||
void addConstant( const char *name,
|
||||
|
|
@ -1107,24 +1088,24 @@ void addConstant( const char *name,
|
|||
const void *dptr,
|
||||
const char* usage )
|
||||
{
|
||||
Dictionary::Entry* entry = gEvalState.globalVars.addVariable( name, type, const_cast< void* >( dptr ), usage );
|
||||
Dictionary::Entry* entry = gGlobalVars.addVariable( name, type, const_cast< void* >( dptr ), usage );
|
||||
entry->mIsConstant = true;
|
||||
}
|
||||
|
||||
bool removeVariable(const char *name)
|
||||
{
|
||||
name = StringTable->lookup(prependDollar(name));
|
||||
return name!=0 && gEvalState.globalVars.removeVariable(name);
|
||||
return name!=0 && gGlobalVars.removeVariable(name);
|
||||
}
|
||||
|
||||
void addVariableNotify( const char *name, const NotifyDelegate &callback )
|
||||
{
|
||||
gEvalState.globalVars.addVariableNotify( name, callback );
|
||||
gGlobalVars.addVariableNotify( name, callback );
|
||||
}
|
||||
|
||||
void removeVariableNotify( const char *name, const NotifyDelegate &callback )
|
||||
{
|
||||
gEvalState.globalVars.removeVariableNotify( name, callback );
|
||||
gGlobalVars.removeVariableNotify( name, callback );
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
|
@ -1206,359 +1187,6 @@ void addCommand( const char *name,BoolCallback cb,const char *usage, S32 minArgs
|
|||
Namespace::global()->addCommand( StringTable->insert(name), cb, usage, minArgs, maxArgs, isToolOnly, header );
|
||||
}
|
||||
|
||||
bool executeFile(const char* fileName, bool noCalls, bool journalScript)
|
||||
{
|
||||
bool journal = false;
|
||||
|
||||
char scriptFilenameBuffer[1024];
|
||||
U32 execDepth = 0;
|
||||
U32 journalDepth = 1;
|
||||
|
||||
execDepth++;
|
||||
if (journalDepth >= execDepth)
|
||||
journalDepth = execDepth + 1;
|
||||
else
|
||||
journal = true;
|
||||
|
||||
bool ret = false;
|
||||
|
||||
if (journalScript && !journal)
|
||||
{
|
||||
journal = true;
|
||||
journalDepth = execDepth;
|
||||
}
|
||||
|
||||
// Determine the filename we actually want...
|
||||
Con::expandScriptFilename(scriptFilenameBuffer, sizeof(scriptFilenameBuffer), fileName);
|
||||
|
||||
// since this function expects a script file reference, if it's a .dso
|
||||
// lets terminate the string before the dso so it will act like a .tscript
|
||||
if (dStrEndsWith(scriptFilenameBuffer, ".dso"))
|
||||
{
|
||||
scriptFilenameBuffer[dStrlen(scriptFilenameBuffer) - dStrlen(".dso")] = '\0';
|
||||
}
|
||||
|
||||
// Figure out where to put DSOs
|
||||
StringTableEntry dsoPath = Con::getDSOPath(scriptFilenameBuffer);
|
||||
|
||||
const char *ext = dStrrchr(scriptFilenameBuffer, '.');
|
||||
|
||||
if (!ext)
|
||||
{
|
||||
// Try appending the default script extension and see if that succeeds
|
||||
|
||||
if (executeFile(fileName + String("." TORQUE_SCRIPT_EXTENSION), noCalls, journalScript))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// We need an extension!
|
||||
Con::errorf(ConsoleLogEntry::Script, "exec: invalid script file name %s.", scriptFilenameBuffer);
|
||||
execDepth--;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check Editor Extensions
|
||||
bool isEditorScript = false;
|
||||
|
||||
// If the script file extension is '.ed.tscript' then compile it to a different compiled extension
|
||||
if (dStricmp(ext, "." TORQUE_SCRIPT_EXTENSION) == 0)
|
||||
{
|
||||
const char* ext2 = ext - 3;
|
||||
if (dStricmp(ext2, ".ed." TORQUE_SCRIPT_EXTENSION) == 0)
|
||||
isEditorScript = true;
|
||||
}
|
||||
else if (dStricmp(ext, ".gui") == 0)
|
||||
{
|
||||
const char* ext2 = ext - 3;
|
||||
if (dStricmp(ext2, ".ed.gui") == 0)
|
||||
isEditorScript = true;
|
||||
}
|
||||
|
||||
StringTableEntry scriptFileName = StringTable->insert(scriptFilenameBuffer);
|
||||
|
||||
// Is this a file we should compile? (anything in the prefs path should not be compiled)
|
||||
StringTableEntry prefsPath = Platform::getPrefsPath();
|
||||
bool compiled = dStricmp(ext, ".mis") && !journal && !Con::getBoolVariable("Scripts::ignoreDSOs");
|
||||
|
||||
// [tom, 12/5/2006] stripBasePath() fucks up if the filename is not in the exe
|
||||
// path, current directory or prefs path. Thus, getDSOFilename() will also screw
|
||||
// up and so this allows the scripts to still load but without a DSO.
|
||||
if (Platform::isFullPath(Platform::stripBasePath(scriptFilenameBuffer)))
|
||||
compiled = false;
|
||||
|
||||
// [tom, 11/17/2006] It seems to make sense to not compile scripts that are in the
|
||||
// prefs directory. However, getDSOPath() can handle this situation and will put
|
||||
// the dso along with the script to avoid name clashes with tools/game dsos.
|
||||
if ((dsoPath && *dsoPath == 0) || (prefsPath && prefsPath[0] && dStrnicmp(scriptFileName, prefsPath, dStrlen(prefsPath)) == 0))
|
||||
compiled = false;
|
||||
|
||||
// If we're in a journaling mode, then we will read the script
|
||||
// from the journal file.
|
||||
if (journal && Journal::IsPlaying())
|
||||
{
|
||||
char fileNameBuf[256];
|
||||
bool fileRead = false;
|
||||
U32 fileSize;
|
||||
|
||||
Journal::ReadString(fileNameBuf);
|
||||
Journal::Read(&fileRead);
|
||||
|
||||
if (!fileRead)
|
||||
{
|
||||
Con::errorf(ConsoleLogEntry::Script, "Journal script read (failed) for %s", fileNameBuf);
|
||||
execDepth--;
|
||||
return false;
|
||||
}
|
||||
Journal::Read(&fileSize);
|
||||
char *script = new char[fileSize + 1];
|
||||
Journal::Read(fileSize, script);
|
||||
script[fileSize] = 0;
|
||||
Con::printf("Executing (journal-read) %s.", scriptFileName);
|
||||
CodeBlock *newCodeBlock = new CodeBlock();
|
||||
newCodeBlock->compileExec(scriptFileName, script, noCalls, 0);
|
||||
delete[] script;
|
||||
delete newCodeBlock;
|
||||
|
||||
execDepth--;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Ok, we let's try to load and compile the script.
|
||||
Torque::FS::FileNodeRef scriptFile = Torque::FS::GetFileNode(scriptFileName);
|
||||
Torque::FS::FileNodeRef dsoFile;
|
||||
|
||||
// ResourceObject *rScr = gResourceManager->find(scriptFileName);
|
||||
// ResourceObject *rCom = NULL;
|
||||
|
||||
char nameBuffer[512];
|
||||
char* script = NULL;
|
||||
U32 version;
|
||||
|
||||
Stream *compiledStream = NULL;
|
||||
Torque::Time scriptModifiedTime, dsoModifiedTime;
|
||||
|
||||
// Check here for .edso
|
||||
bool edso = false;
|
||||
if (dStricmp(ext, ".edso") == 0 && scriptFile != NULL)
|
||||
{
|
||||
edso = true;
|
||||
dsoFile = scriptFile;
|
||||
scriptFile = NULL;
|
||||
|
||||
dsoModifiedTime = dsoFile->getModifiedTime();
|
||||
dStrcpy(nameBuffer, scriptFileName, 512);
|
||||
}
|
||||
|
||||
// If we're supposed to be compiling this file, check to see if there's a DSO
|
||||
if (compiled && !edso)
|
||||
{
|
||||
const char *filenameOnly = dStrrchr(scriptFileName, '/');
|
||||
if (filenameOnly)
|
||||
++filenameOnly;
|
||||
else
|
||||
filenameOnly = scriptFileName;
|
||||
|
||||
char pathAndFilename[1024];
|
||||
Platform::makeFullPathName(filenameOnly, pathAndFilename, sizeof(pathAndFilename), dsoPath);
|
||||
|
||||
if (isEditorScript)
|
||||
dStrcpyl(nameBuffer, sizeof(nameBuffer), pathAndFilename, ".edso", NULL);
|
||||
else
|
||||
dStrcpyl(nameBuffer, sizeof(nameBuffer), pathAndFilename, ".dso", NULL);
|
||||
|
||||
dsoFile = Torque::FS::GetFileNode(nameBuffer);
|
||||
|
||||
if (scriptFile != NULL)
|
||||
scriptModifiedTime = scriptFile->getModifiedTime();
|
||||
|
||||
if (dsoFile != NULL)
|
||||
dsoModifiedTime = dsoFile->getModifiedTime();
|
||||
}
|
||||
|
||||
// Let's do a sanity check to complain about DSOs in the future.
|
||||
//
|
||||
// MM: This doesn't seem to be working correctly for now so let's just not issue
|
||||
// the warning until someone knows how to resolve it.
|
||||
//
|
||||
//if(compiled && rCom && rScr && Platform::compareFileTimes(comModifyTime, scrModifyTime) < 0)
|
||||
//{
|
||||
//Con::warnf("exec: Warning! Found a DSO from the future! (%s)", nameBuffer);
|
||||
//}
|
||||
|
||||
// If we had a DSO, let's check to see if we should be reading from it.
|
||||
//MGT: fixed bug with dsos not getting recompiled correctly
|
||||
//Note: Using Nathan Martin's version from the forums since its easier to read and understand
|
||||
if (compiled && dsoFile != NULL && (scriptFile == NULL || (dsoModifiedTime >= scriptModifiedTime)))
|
||||
{ //MGT: end
|
||||
compiledStream = FileStream::createAndOpen(nameBuffer, Torque::FS::File::Read);
|
||||
if (compiledStream)
|
||||
{
|
||||
// Check the version!
|
||||
compiledStream->read(&version);
|
||||
if (version != Con::DSOVersion)
|
||||
{
|
||||
Con::warnf("exec: Found an old DSO (%s, ver %d < %d), ignoring.", nameBuffer, version, Con::DSOVersion);
|
||||
delete compiledStream;
|
||||
compiledStream = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we're journalling, let's write some info out.
|
||||
if (journal && Journal::IsRecording())
|
||||
Journal::WriteString(scriptFileName);
|
||||
|
||||
if (scriptFile != NULL && !compiledStream)
|
||||
{
|
||||
// If we have source but no compiled version, then we need to compile
|
||||
// (and journal as we do so, if that's required).
|
||||
|
||||
void *data;
|
||||
U32 dataSize = 0;
|
||||
Torque::FS::ReadFile(scriptFileName, data, dataSize, true);
|
||||
|
||||
if (journal && Journal::IsRecording())
|
||||
Journal::Write(bool(data != NULL));
|
||||
|
||||
if (data == NULL)
|
||||
{
|
||||
Con::errorf(ConsoleLogEntry::Script, "exec: invalid script file %s.", scriptFileName);
|
||||
execDepth--;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!dataSize)
|
||||
{
|
||||
execDepth--;
|
||||
return false;
|
||||
}
|
||||
|
||||
script = (char *)data;
|
||||
|
||||
if (journal && Journal::IsRecording())
|
||||
{
|
||||
Journal::Write(dataSize);
|
||||
Journal::Write(dataSize, data);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef TORQUE_NO_DSO_GENERATION
|
||||
if (compiled)
|
||||
{
|
||||
// compile this baddie.
|
||||
#ifdef TORQUE_DEBUG
|
||||
Con::printf("Compiling %s...", scriptFileName);
|
||||
#endif
|
||||
|
||||
CodeBlock *code = new CodeBlock();
|
||||
code->compile(nameBuffer, scriptFileName, script);
|
||||
delete code;
|
||||
code = NULL;
|
||||
|
||||
compiledStream = FileStream::createAndOpen(nameBuffer, Torque::FS::File::Read);
|
||||
if (compiledStream)
|
||||
{
|
||||
compiledStream->read(&version);
|
||||
}
|
||||
else
|
||||
{
|
||||
// We have to exit out here, as otherwise we get double error reports.
|
||||
delete[] script;
|
||||
execDepth--;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
if (journal && Journal::IsRecording())
|
||||
Journal::Write(bool(false));
|
||||
}
|
||||
|
||||
if (compiledStream)
|
||||
{
|
||||
// Delete the script object first to limit memory used
|
||||
// during recursive execs.
|
||||
delete[] script;
|
||||
script = 0;
|
||||
|
||||
// We're all compiled, so let's run it.
|
||||
#ifdef TORQUE_DEBUG
|
||||
Con::printf("Loading compiled script %s.", scriptFileName);
|
||||
#endif
|
||||
CodeBlock *code = new CodeBlock;
|
||||
code->read(scriptFileName, *compiledStream);
|
||||
delete compiledStream;
|
||||
code->exec(0, scriptFileName, NULL, 0, NULL, noCalls, NULL, 0);
|
||||
delete code;
|
||||
ret = true;
|
||||
}
|
||||
else
|
||||
if (scriptFile)
|
||||
{
|
||||
// No compiled script, let's just try executing it
|
||||
// directly... this is either a mission file, or maybe
|
||||
// we're on a readonly volume.
|
||||
#ifdef TORQUE_DEBUG
|
||||
Con::printf("Executing %s.", scriptFileName);
|
||||
#endif
|
||||
|
||||
CodeBlock *newCodeBlock = new CodeBlock();
|
||||
StringTableEntry name = StringTable->insert(scriptFileName);
|
||||
|
||||
newCodeBlock->compileExec(name, script, noCalls, 0);
|
||||
ret = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Don't have anything.
|
||||
Con::warnf(ConsoleLogEntry::Script, "Missing file: %s!", scriptFileName);
|
||||
ret = false;
|
||||
}
|
||||
|
||||
delete[] script;
|
||||
execDepth--;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ConsoleValue evaluate(const char* string, bool echo, const char *fileName)
|
||||
{
|
||||
ConsoleStackFrameSaver stackSaver;
|
||||
stackSaver.save();
|
||||
|
||||
if (echo)
|
||||
{
|
||||
if (string[0] == '%')
|
||||
Con::printf("%s", string);
|
||||
else
|
||||
Con::printf("%s%s", getVariable( "$Con::Prompt" ), string);
|
||||
}
|
||||
|
||||
if(fileName)
|
||||
fileName = StringTable->insert(fileName);
|
||||
|
||||
CodeBlock *newCodeBlock = new CodeBlock();
|
||||
return std::move(newCodeBlock->compileExec(fileName, string, false, fileName ? -1 : 0));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
ConsoleValue evaluatef(const char* string, ...)
|
||||
{
|
||||
ConsoleStackFrameSaver stackSaver;
|
||||
stackSaver.save();
|
||||
|
||||
char buffer[4096];
|
||||
va_list args;
|
||||
va_start(args, string);
|
||||
dVsprintf(buffer, sizeof(buffer), string, args);
|
||||
va_end(args);
|
||||
CodeBlock *newCodeBlock = new CodeBlock();
|
||||
return newCodeBlock->compileExec(NULL, buffer, false, 0);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Internal execute for global function which does not save the stack
|
||||
|
|
@ -1598,7 +1226,7 @@ ConsoleValue _internalExecute(S32 argc, ConsoleValue argv[])
|
|||
return std::move(ConsoleValue());
|
||||
}
|
||||
|
||||
return std::move(ent->execute(argc, argv, &gEvalState));
|
||||
return std::move(ent->execute(argc, argv, NULL));
|
||||
}
|
||||
|
||||
ConsoleValue execute(S32 argc, ConsoleValue argv[])
|
||||
|
|
@ -1701,10 +1329,7 @@ static ConsoleValue _internalExecute(SimObject *object, S32 argc, ConsoleValue a
|
|||
// Twiddle %this argument
|
||||
argv[1].setInt(ident);
|
||||
|
||||
SimObject *save = gEvalState.thisObject;
|
||||
gEvalState.thisObject = object;
|
||||
ConsoleValue ret = std::move(ent->execute(argc, argv, &gEvalState));
|
||||
gEvalState.thisObject = save;
|
||||
ConsoleValue ret = std::move(ent->execute(argc, argv, object));
|
||||
|
||||
// Twiddle it back
|
||||
argv[1].setString(oldIdent);
|
||||
|
|
@ -1810,6 +1435,84 @@ void setLogMode(S32 newMode)
|
|||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
ReturnBuffer retBuffer;
|
||||
|
||||
char* getReturnBuffer(U32 bufferSize)
|
||||
{
|
||||
return retBuffer.getBuffer(bufferSize);
|
||||
}
|
||||
|
||||
char* getReturnBuffer(const char* stringToCopy)
|
||||
{
|
||||
U32 len = dStrlen(stringToCopy) + 1;
|
||||
char* ret = retBuffer.getBuffer(len);
|
||||
dMemcpy(ret, stringToCopy, len);
|
||||
return ret;
|
||||
}
|
||||
|
||||
char* getReturnBuffer(const String& str)
|
||||
{
|
||||
const U32 size = str.size();
|
||||
char* ret = retBuffer.getBuffer(size);
|
||||
dMemcpy(ret, str.c_str(), size);
|
||||
return ret;
|
||||
}
|
||||
|
||||
char* getReturnBuffer(const StringBuilder& str)
|
||||
{
|
||||
char* buffer = Con::getReturnBuffer(str.length() + 1);
|
||||
str.copy(buffer);
|
||||
buffer[str.length()] = '\0';
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
char* getArgBuffer(U32 bufferSize)
|
||||
{
|
||||
return STR.getArgBuffer(bufferSize);
|
||||
}
|
||||
|
||||
char* getFloatArg(F64 arg)
|
||||
{
|
||||
char* ret = STR.getArgBuffer(32);
|
||||
dSprintf(ret, 32, "%g", arg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
char* getIntArg(S32 arg)
|
||||
{
|
||||
char* ret = STR.getArgBuffer(32);
|
||||
dSprintf(ret, 32, "%d", arg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
char* getBoolArg(bool arg)
|
||||
{
|
||||
char* ret = STR.getArgBuffer(32);
|
||||
dSprintf(ret, 32, "%d", arg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
char* getStringArg(const char* arg)
|
||||
{
|
||||
U32 len = dStrlen(arg) + 1;
|
||||
char* ret = STR.getArgBuffer(len);
|
||||
dMemcpy(ret, arg, len);
|
||||
return ret;
|
||||
}
|
||||
|
||||
char* getStringArg(const String& arg)
|
||||
{
|
||||
const U32 size = arg.size();
|
||||
char* ret = STR.getArgBuffer(size);
|
||||
dMemcpy(ret, arg.c_str(), size);
|
||||
return ret;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
Namespace *lookupNamespace(const char *ns)
|
||||
{
|
||||
if(!ns)
|
||||
|
|
@ -1911,7 +1614,7 @@ bool isCurrentScriptToolScript()
|
|||
#ifndef TORQUE_TOOLS
|
||||
return false;
|
||||
#else
|
||||
const StringTableEntry cbFullPath = CodeBlock::getCurrentCodeBlockFullPath();
|
||||
const StringTableEntry cbFullPath = getCurrentScriptModulePath();
|
||||
if(cbFullPath == NULL)
|
||||
return false;
|
||||
const StringTableEntry exePath = Platform::getMainDotCsDir();
|
||||
|
|
@ -1922,6 +1625,20 @@ bool isCurrentScriptToolScript()
|
|||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
bool isScriptFile(const char* pFilePath)
|
||||
{
|
||||
return (Torque::FS::IsFile(pFilePath)
|
||||
|| Torque::FS::IsFile(pFilePath + String(".dso"))
|
||||
|| Torque::FS::IsFile(pFilePath + String(".mis"))
|
||||
|| Torque::FS::IsFile(pFilePath + String(".mis.dso"))
|
||||
|| Torque::FS::IsFile(pFilePath + String(".gui"))
|
||||
|| Torque::FS::IsFile(pFilePath + String(".gui.dso"))
|
||||
|| Torque::FS::IsFile(pFilePath + String("." TORQUE_SCRIPT_EXTENSION))
|
||||
|| Torque::FS::IsFile(pFilePath + String("." TORQUE_SCRIPT_EXTENSION) + String(".dso")));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
StringTableEntry getModNameFromPath(const char *path)
|
||||
{
|
||||
if(path == NULL || *path == 0)
|
||||
|
|
@ -2248,7 +1965,7 @@ bool expandPath(char* pDstPath, U32 size, const char* pSrcPath, const char* pWor
|
|||
if (leadingToken == '.')
|
||||
{
|
||||
// Fetch the code-block file-path.
|
||||
const StringTableEntry codeblockFullPath = CodeBlock::getCurrentCodeBlockFullPath();
|
||||
const StringTableEntry codeblockFullPath = getCurrentScriptModulePath();
|
||||
|
||||
// Do we have a code block full path?
|
||||
if (codeblockFullPath == NULL)
|
||||
|
|
|
|||
|
|
@ -128,6 +128,7 @@ enum ConsoleValueType
|
|||
|
||||
struct ConsoleValueConsoleType
|
||||
{
|
||||
S32 consoleType;
|
||||
void* dataPtr;
|
||||
EnumTable* enumTable;
|
||||
};
|
||||
|
|
@ -340,8 +341,8 @@ public:
|
|||
TORQUE_FORCEINLINE void setConsoleData(S32 consoleType, void* dataPtr, const EnumTable* enumTable)
|
||||
{
|
||||
cleanupData();
|
||||
type = ConsoleValueType::cvSTEntry;
|
||||
ct = new ConsoleValueConsoleType{ dataPtr, const_cast<EnumTable*>(enumTable) };
|
||||
type = ConsoleValueType::cvConsoleValueType;
|
||||
ct = new ConsoleValueConsoleType{ consoleType, dataPtr, const_cast<EnumTable*>(enumTable) };
|
||||
}
|
||||
|
||||
TORQUE_FORCEINLINE S32 getType() const
|
||||
|
|
@ -364,6 +365,18 @@ public:
|
|||
return type >= ConsoleValueType::cvConsoleValueType;
|
||||
}
|
||||
|
||||
TORQUE_FORCEINLINE ConsoleValueConsoleType* getConsoleType() const
|
||||
{
|
||||
if(type >= ConsoleValueType::cvConsoleValueType)
|
||||
{
|
||||
return ct;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
TORQUE_FORCEINLINE void setFastFloat(F64 flt)
|
||||
{
|
||||
type = ConsoleValueType::cvFloat;
|
||||
|
|
@ -626,6 +639,7 @@ namespace Con
|
|||
StringTableEntry getPathExpandoValue(U32 expandoIndex);
|
||||
|
||||
bool isCurrentScriptToolScript();
|
||||
bool isScriptFile(const char* path);
|
||||
|
||||
StringTableEntry getModNameFromPath(const char *path);
|
||||
|
||||
|
|
@ -918,30 +932,6 @@ namespace Con
|
|||
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.
|
||||
///
|
||||
/// @param string File name that is the script to be executed and compiled.
|
||||
/// @param fileName Path to the file to execute
|
||||
/// @param noCalls Deprecated
|
||||
/// @param journalScript Deprecated
|
||||
///
|
||||
/// @return True if the script was successfully executed, false if not.
|
||||
bool executeFile(const char* fileName, bool noCalls, bool journalScript);
|
||||
|
||||
/// Evaluate an arbitrary chunk of code.
|
||||
///
|
||||
/// @param string Buffer containing code to execute.
|
||||
/// @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.
|
||||
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.
|
||||
ConsoleValue evaluatef(const char* string, ...);
|
||||
|
||||
/// @}
|
||||
|
||||
/// @name Console Function Implementation Helpers
|
||||
|
|
|
|||
|
|
@ -23,14 +23,12 @@
|
|||
#include "platform/platform.h"
|
||||
#include "console/console.h"
|
||||
|
||||
#include "console/ast.h"
|
||||
#include "core/tAlgorithm.h"
|
||||
|
||||
#include "core/strings/findMatch.h"
|
||||
#include "console/consoleInternal.h"
|
||||
#include "console/consoleObject.h"
|
||||
#include "core/stream/fileStream.h"
|
||||
#include "console/compiler.h"
|
||||
#include "core/frameAllocator.h"
|
||||
#include "console/engineAPI.h"
|
||||
|
||||
|
|
@ -272,7 +270,7 @@ void Namespace::printNamespaceEntries(Namespace * g, bool dumpScript, bool dumpE
|
|||
}
|
||||
else if(ewalk->mFunctionOffset) // If it's a builtin function...
|
||||
{
|
||||
String args = ewalk->mCode->getFunctionArgs(ewalk->mFunctionOffset);
|
||||
String args = ewalk->mModule->getFunctionArgs(ewalk->mFunctionName, ewalk->mFunctionOffset);
|
||||
printClassMethod(false, typeNames[ewalk->mType], ewalk->mFunctionName, args, "");
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -24,18 +24,17 @@
|
|||
#include "console/console.h"
|
||||
#include "console/consoleInternal.h"
|
||||
#include "console/engineAPI.h"
|
||||
#include "console/ast.h"
|
||||
|
||||
#ifndef _CONSOLFUNCTIONS_H_
|
||||
#include "console/consoleFunctions.h"
|
||||
#endif
|
||||
|
||||
#include "script.h"
|
||||
#include "cinterface/cinterface.h"
|
||||
#include "core/strings/findMatch.h"
|
||||
#include "core/strings/stringUnit.h"
|
||||
#include "core/strings/unicode.h"
|
||||
#include "core/stream/fileStream.h"
|
||||
#include "console/compiler.h"
|
||||
#include "platform/platformInput.h"
|
||||
#include "core/util/journal/journal.h"
|
||||
#include "gfx/gfxEnums.h"
|
||||
|
|
@ -43,6 +42,7 @@
|
|||
#include "core/color.h"
|
||||
#include "math/mPoint3.h"
|
||||
#include "math/mathTypes.h"
|
||||
#include "torquescript/runtime.h"
|
||||
|
||||
// This is a temporary hack to get tools using the library to
|
||||
// link in this module which contains no other references.
|
||||
|
|
@ -2330,63 +2330,7 @@ DefineEngineFunction( compile, bool, ( const char* fileName, bool overrideNoDSO
|
|||
"@see exec\n"
|
||||
"@ingroup Scripting" )
|
||||
{
|
||||
Con::expandScriptFilename( scriptFilenameBuffer, sizeof( scriptFilenameBuffer ), fileName );
|
||||
|
||||
// Figure out where to put DSOs
|
||||
StringTableEntry dsoPath = Con::getDSOPath(scriptFilenameBuffer);
|
||||
if(dsoPath && *dsoPath == 0)
|
||||
return false;
|
||||
|
||||
// If the script file extention is '.ed.tscript' then compile it to a different compiled extention
|
||||
bool isEditorScript = false;
|
||||
const char *ext = dStrrchr( scriptFilenameBuffer, '.' );
|
||||
if( ext && ( dStricmp( ext, "." TORQUE_SCRIPT_EXTENSION) == 0 ) )
|
||||
{
|
||||
const char* ext2 = ext - 3;
|
||||
if( dStricmp( ext2, ".ed." TORQUE_SCRIPT_EXTENSION) == 0 )
|
||||
isEditorScript = true;
|
||||
}
|
||||
else if( ext && ( dStricmp( ext, ".gui" ) == 0 ) )
|
||||
{
|
||||
const char* ext2 = ext - 3;
|
||||
if( dStricmp( ext2, ".ed.gui" ) == 0 )
|
||||
isEditorScript = true;
|
||||
}
|
||||
|
||||
const char *filenameOnly = dStrrchr(scriptFilenameBuffer, '/');
|
||||
if(filenameOnly)
|
||||
++filenameOnly;
|
||||
else
|
||||
filenameOnly = scriptFilenameBuffer;
|
||||
|
||||
char nameBuffer[512];
|
||||
|
||||
if( isEditorScript )
|
||||
dStrcpyl(nameBuffer, sizeof(nameBuffer), dsoPath, "/", filenameOnly, ".edso", NULL);
|
||||
else
|
||||
dStrcpyl(nameBuffer, sizeof(nameBuffer), dsoPath, "/", filenameOnly, ".dso", NULL);
|
||||
|
||||
void *data = NULL;
|
||||
U32 dataSize = 0;
|
||||
Torque::FS::ReadFile(scriptFilenameBuffer, data, dataSize, true);
|
||||
if(data == NULL)
|
||||
{
|
||||
Con::errorf(ConsoleLogEntry::Script, "compile: invalid script file %s.", scriptFilenameBuffer);
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *script = static_cast<const char *>(data);
|
||||
|
||||
#ifdef TORQUE_DEBUG
|
||||
Con::printf("Compiling %s...", scriptFilenameBuffer);
|
||||
#endif
|
||||
|
||||
CodeBlock *code = new CodeBlock();
|
||||
code->compile(nameBuffer, scriptFilenameBuffer, script, overrideNoDSO);
|
||||
delete code;
|
||||
delete[] script;
|
||||
|
||||
return true;
|
||||
return TorqueScript::getRuntime()->compile(fileName, overrideNoDSO);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -2410,12 +2354,12 @@ DefineEngineFunction( exec, bool, ( const char* fileName, bool noCalls, bool jou
|
|||
|
||||
DefineEngineFunction( eval, const char*, ( const char* consoleString ), , "eval(consoleString)" )
|
||||
{
|
||||
ConsoleValue returnValue = Con::evaluate(consoleString, false, NULL);
|
||||
Con::EvalResult returnValue = Con::evaluate(consoleString, false, NULL);
|
||||
|
||||
return Con::getReturnBuffer(returnValue.getString());
|
||||
return Con::getReturnBuffer(returnValue.value.getString());
|
||||
}
|
||||
|
||||
DefineEngineFunction( getVariable, const char*, ( const char* varName ), , "(string varName)\n"
|
||||
DefineEngineFunction( getVariable, const char*, ( const char* varName ), , "(string varName)\n"
|
||||
"@brief Returns the value of the named variable or an empty string if not found.\n\n"
|
||||
"@varName Name of the variable to search for\n"
|
||||
"@return Value contained by varName, \"\" if the variable does not exist\n"
|
||||
|
|
@ -2589,15 +2533,15 @@ DefineEngineFunction( isDefined, bool, ( const char* varName, const char* varVal
|
|||
else if (name[0] == '%')
|
||||
{
|
||||
// Look up a local variable
|
||||
if( gEvalState.getStackDepth() > 0 )
|
||||
if( Con::getFrameStack().size() > 0 )
|
||||
{
|
||||
Dictionary::Entry* ent = gEvalState.getCurrentFrame().lookup(name);
|
||||
Dictionary::Entry* ent = Con::getCurrentStackFrame()->lookup(name);
|
||||
|
||||
if (ent)
|
||||
return true;
|
||||
else if (!String::isEmpty(varValue))
|
||||
{
|
||||
gEvalState.getCurrentFrame().setVariable(name, varValue);
|
||||
Con::getCurrentStackFrame()->setVariable(name, varValue);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -2606,13 +2550,13 @@ DefineEngineFunction( isDefined, bool, ( const char* varName, const char* varVal
|
|||
else if (name[0] == '$')
|
||||
{
|
||||
// Look up a global value
|
||||
Dictionary::Entry* ent = gEvalState.globalVars.lookup(name);
|
||||
Dictionary::Entry* ent = Con::gGlobalVars.lookup(name);
|
||||
|
||||
if (ent)
|
||||
return true;
|
||||
else if (!String::isEmpty(varValue))
|
||||
{
|
||||
gEvalState.globalVars.setVariable(name, varValue);
|
||||
Con::gGlobalVars.setVariable(name, varValue);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -2739,7 +2683,7 @@ DefineEngineFunction( export, void, ( const char* pattern, const char* filename,
|
|||
else
|
||||
filename = NULL;
|
||||
|
||||
gEvalState.globalVars.exportVariables( pattern, filename, append );
|
||||
Con::gGlobalVars.exportVariables( pattern, filename, append );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -2756,7 +2700,7 @@ DefineEngineFunction( deleteVariables, void, ( const char* pattern ),,
|
|||
"@see strIsMatchExpr\n"
|
||||
"@ingroup Scripting" )
|
||||
{
|
||||
gEvalState.globalVars.deleteVariables( pattern );
|
||||
Con::gGlobalVars.deleteVariables( pattern );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -2769,8 +2713,8 @@ DefineEngineFunction( trace, void, ( bool enable ), ( true ),
|
|||
"@param enable New setting for script trace execution, on by default.\n"
|
||||
"@ingroup Debugging" )
|
||||
{
|
||||
gEvalState.traceOn = enable;
|
||||
Con::printf( "Console trace %s", gEvalState.traceOn ? "enabled." : "disabled." );
|
||||
Con::gTraceOn = enable;
|
||||
Con::printf( "Console trace %s", Con::gTraceOn ? "enabled." : "disabled." );
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -25,13 +25,11 @@
|
|||
#include "platform/platform.h"
|
||||
#include "console/console.h"
|
||||
|
||||
#include "console/ast.h"
|
||||
#include "core/tAlgorithm.h"
|
||||
|
||||
#include "core/strings/findMatch.h"
|
||||
#include "console/consoleInternal.h"
|
||||
#include "core/stream/fileStream.h"
|
||||
#include "console/compiler.h"
|
||||
#include "console/engineAPI.h"
|
||||
|
||||
//#define DEBUG_SPEW
|
||||
|
|
@ -183,13 +181,13 @@ void Dictionary::exportVariables(const char *varString, const char *fileName, bo
|
|||
|
||||
for (s = sortList.begin(); s != sortList.end(); s++)
|
||||
{
|
||||
switch ((*s)->type)
|
||||
switch ((*s)->value.getType())
|
||||
{
|
||||
case Entry::TypeInternalInt:
|
||||
dSprintf(buffer, sizeof(buffer), "%s = %d;%s", (*s)->name, (*s)->ival, cat);
|
||||
case ConsoleValueType::cvInteger:
|
||||
dSprintf(buffer, sizeof(buffer), "%s = %d;%s", (*s)->name, (*s)->getIntValue(), cat);
|
||||
break;
|
||||
case Entry::TypeInternalFloat:
|
||||
dSprintf(buffer, sizeof(buffer), "%s = %g;%s", (*s)->name, (*s)->fval, cat);
|
||||
case ConsoleValueType::cvFloat:
|
||||
dSprintf(buffer, sizeof(buffer), "%s = %g;%s", (*s)->name, (*s)->getFloatValue(), cat);
|
||||
break;
|
||||
default:
|
||||
expandEscape(expandBuffer, (*s)->getStringValue());
|
||||
|
|
@ -243,7 +241,7 @@ void Dictionary::exportVariables(const char *varString, Vector<String> *names, V
|
|||
|
||||
if (values)
|
||||
{
|
||||
switch ((*s)->type)
|
||||
switch ((*s)->value.getType())
|
||||
{
|
||||
case ConsoleValueType::cvInteger:
|
||||
case ConsoleValueType::cvFloat:
|
||||
|
|
@ -375,18 +373,16 @@ Dictionary::Dictionary()
|
|||
#pragma warning( disable : 4355 )
|
||||
ownHashTable(this), // Warning with VC++ but this is safe.
|
||||
#pragma warning( default : 4355 )
|
||||
exprState(NULL),
|
||||
scopeName(NULL),
|
||||
scopeNamespace(NULL),
|
||||
code(NULL),
|
||||
module(NULL),
|
||||
ip(0)
|
||||
{
|
||||
setState(NULL);
|
||||
}
|
||||
|
||||
void Dictionary::setState(ExprEvalState *state, Dictionary* ref)
|
||||
void Dictionary::setState(Dictionary* ref)
|
||||
{
|
||||
exprState = state;
|
||||
|
||||
if (ref)
|
||||
{
|
||||
hashTable = ref->hashTable;
|
||||
|
|
@ -439,7 +435,7 @@ void Dictionary::reset()
|
|||
|
||||
scopeName = NULL;
|
||||
scopeNamespace = NULL;
|
||||
code = NULL;
|
||||
module = NULL;
|
||||
ip = 0;
|
||||
}
|
||||
|
||||
|
|
@ -465,19 +461,11 @@ const char *Dictionary::tabComplete(const char *prevText, S32 baseLen, bool fFor
|
|||
Dictionary::Entry::Entry(StringTableEntry in_name)
|
||||
{
|
||||
name = in_name;
|
||||
type = TypeInternalString;
|
||||
notify = NULL;
|
||||
nextEntry = NULL;
|
||||
mUsage = NULL;
|
||||
mIsConstant = false;
|
||||
mNext = NULL;
|
||||
|
||||
ival = 0;
|
||||
fval = 0;
|
||||
sval = NULL;
|
||||
bufferLen = 0;
|
||||
dataPtr = NULL;
|
||||
enumTable = NULL;
|
||||
}
|
||||
|
||||
Dictionary::Entry::~Entry()
|
||||
|
|
@ -488,73 +476,11 @@ Dictionary::Entry::~Entry()
|
|||
void Dictionary::Entry::reset()
|
||||
{
|
||||
name = NULL;
|
||||
if (type <= TypeInternalString && sval != NULL)
|
||||
dFree(sval);
|
||||
value.reset();
|
||||
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 == NULL)
|
||||
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);
|
||||
|
|
@ -630,17 +556,12 @@ Dictionary::Entry* Dictionary::addVariable(const char *name,
|
|||
|
||||
Entry *ent = add(StringTable->insert(name));
|
||||
|
||||
if (ent->type <= Entry::TypeInternalString && ent->sval != NULL)
|
||||
dFree(ent->sval);
|
||||
|
||||
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->enumTable = conType->getEnumTable();
|
||||
ent->value.setConsoleData(type, dataPtr, conType->getEnumTable());
|
||||
|
||||
return ent;
|
||||
}
|
||||
|
|
@ -680,158 +601,15 @@ void Dictionary::validate()
|
|||
"Dictionary::validate() - Dictionary not owner of own hashtable!");
|
||||
}
|
||||
|
||||
void ExprEvalState::pushFrame(StringTableEntry frameName, Namespace *ns, S32 registerCount)
|
||||
Con::Module* Con::findScriptModuleForFile(const char* fileName)
|
||||
{
|
||||
#ifdef DEBUG_SPEW
|
||||
validate();
|
||||
|
||||
Platform::outputDebugString("[ConsoleInternal] Pushing new frame for '%s' at %i",
|
||||
frameName, mStackDepth);
|
||||
#endif
|
||||
|
||||
if (mStackDepth + 1 > stack.size())
|
||||
for (Con::Module* module : gScriptModules)
|
||||
{
|
||||
#ifdef DEBUG_SPEW
|
||||
Platform::outputDebugString("[ConsoleInternal] Growing stack by one frame");
|
||||
#endif
|
||||
|
||||
stack.push_back(new Dictionary);
|
||||
if (module->getName() == fileName) {
|
||||
return module;
|
||||
}
|
||||
}
|
||||
|
||||
Dictionary& newFrame = *(stack[mStackDepth]);
|
||||
newFrame.setState(this);
|
||||
|
||||
newFrame.scopeName = frameName;
|
||||
newFrame.scopeNamespace = ns;
|
||||
|
||||
mStackDepth++;
|
||||
currentVariable = NULL;
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
void ExprEvalState::popFrame()
|
||||
{
|
||||
AssertFatal(mStackDepth > 0, "ExprEvalState::popFrame - Stack Underflow!");
|
||||
|
||||
#ifdef DEBUG_SPEW
|
||||
validate();
|
||||
|
||||
Platform::outputDebugString("[ConsoleInternal] Popping %sframe at %i",
|
||||
getCurrentFrame().isOwner() ? "" : "shared ", mStackDepth - 1);
|
||||
#endif
|
||||
|
||||
mStackDepth--;
|
||||
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
|
||||
}
|
||||
|
||||
void ExprEvalState::pushFrameRef(S32 stackIndex)
|
||||
{
|
||||
AssertFatal(stackIndex >= 0 && stackIndex < mStackDepth, "You must be asking for a valid frame!");
|
||||
|
||||
#ifdef DEBUG_SPEW
|
||||
validate();
|
||||
|
||||
Platform::outputDebugString("[ConsoleInternal] Cloning frame from %i to %i",
|
||||
stackIndex, mStackDepth);
|
||||
#endif
|
||||
|
||||
if (mStackDepth + 1 > stack.size())
|
||||
{
|
||||
#ifdef DEBUG_SPEW
|
||||
Platform::outputDebugString("[ConsoleInternal] Growing stack by one frame");
|
||||
#endif
|
||||
|
||||
stack.push_back(new Dictionary);
|
||||
}
|
||||
|
||||
Dictionary& newFrame = *(stack[mStackDepth]);
|
||||
newFrame.setState(this, stack[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);
|
||||
globalVars.setState(this);
|
||||
thisObject = NULL;
|
||||
traceOn = false;
|
||||
currentVariable = NULL;
|
||||
mStackDepth = 0;
|
||||
stack.reserve(64);
|
||||
mShouldReset = false;
|
||||
mResetLocked = false;
|
||||
copyVariable = NULL;
|
||||
currentRegisterArray = NULL;
|
||||
}
|
||||
|
||||
ExprEvalState::~ExprEvalState()
|
||||
{
|
||||
// Delete callframes.
|
||||
|
||||
while (!stack.empty())
|
||||
{
|
||||
delete stack.last();
|
||||
stack.decrement();
|
||||
}
|
||||
}
|
||||
|
||||
void ExprEvalState::validate()
|
||||
{
|
||||
AssertFatal(mStackDepth <= stack.size(),
|
||||
"ExprEvalState::validate() - Stack depth pointing beyond last stack frame!");
|
||||
|
||||
for (U32 i = 0; i < stack.size(); ++i)
|
||||
stack[i]->validate();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DefineEngineFunction(backtrace, void, (), ,
|
||||
|
|
@ -842,35 +620,37 @@ DefineEngineFunction(backtrace, void, (), ,
|
|||
{
|
||||
U32 totalSize = 1;
|
||||
|
||||
for (U32 i = 0; i < gEvalState.getStackDepth(); i++)
|
||||
for (U32 i = 0; i < Con::getFrameStack().size(); i++)
|
||||
{
|
||||
if (gEvalState.stack[i]->scopeNamespace && gEvalState.stack[i]->scopeNamespace->mEntryList->mPackage)
|
||||
totalSize += dStrlen(gEvalState.stack[i]->scopeNamespace->mEntryList->mPackage) + 2;
|
||||
if (gEvalState.stack[i]->scopeName)
|
||||
totalSize += dStrlen(gEvalState.stack[i]->scopeName) + 3;
|
||||
if (gEvalState.stack[i]->scopeNamespace && gEvalState.stack[i]->scopeNamespace->mName)
|
||||
totalSize += dStrlen(gEvalState.stack[i]->scopeNamespace->mName) + 2;
|
||||
const Con::ConsoleFrame* frame = Con::getStackFrame(i);
|
||||
if (frame->scopeNamespace && frame->scopeNamespace->mEntryList->mPackage)
|
||||
totalSize += dStrlen(frame->scopeNamespace->mEntryList->mPackage) + 2;
|
||||
if (frame->scopeName)
|
||||
totalSize += dStrlen(frame->scopeName) + 3;
|
||||
if (frame->scopeNamespace && frame->scopeNamespace->mName)
|
||||
totalSize += dStrlen(frame->scopeNamespace->mName) + 2;
|
||||
}
|
||||
|
||||
char *buf = Con::getReturnBuffer(totalSize);
|
||||
buf[0] = 0;
|
||||
for (U32 i = 0; i < gEvalState.getStackDepth(); i++)
|
||||
for (U32 i = 0; i < Con::getFrameStack().size(); i++)
|
||||
{
|
||||
const Con::ConsoleFrame* frame = Con::getStackFrame(i);
|
||||
dStrcat(buf, "->", totalSize);
|
||||
|
||||
if (gEvalState.stack[i]->scopeNamespace && gEvalState.stack[i]->scopeNamespace->mEntryList->mPackage)
|
||||
if (frame->scopeNamespace && frame->scopeNamespace->mEntryList->mPackage)
|
||||
{
|
||||
dStrcat(buf, "[", totalSize);
|
||||
dStrcat(buf, gEvalState.stack[i]->scopeNamespace->mEntryList->mPackage, totalSize);
|
||||
dStrcat(buf, frame->scopeNamespace->mEntryList->mPackage, totalSize);
|
||||
dStrcat(buf, "]", totalSize);
|
||||
}
|
||||
if (gEvalState.stack[i]->scopeNamespace && gEvalState.stack[i]->scopeNamespace->mName)
|
||||
if (frame->scopeNamespace && frame->scopeNamespace->mName)
|
||||
{
|
||||
dStrcat(buf, gEvalState.stack[i]->scopeNamespace->mName, totalSize);
|
||||
dStrcat(buf, frame->scopeNamespace->mName, totalSize);
|
||||
dStrcat(buf, "::", totalSize);
|
||||
}
|
||||
if (gEvalState.stack[i]->scopeName)
|
||||
dStrcat(buf, gEvalState.stack[i]->scopeName, totalSize);
|
||||
if (frame->scopeName)
|
||||
dStrcat(buf, frame->scopeName, totalSize);
|
||||
}
|
||||
|
||||
Con::printf("BackTrace: %s", buf);
|
||||
|
|
@ -878,7 +658,7 @@ DefineEngineFunction(backtrace, void, (), ,
|
|||
|
||||
Namespace::Entry::Entry()
|
||||
{
|
||||
mCode = NULL;
|
||||
mModule = NULL;
|
||||
mType = InvalidFunctionType;
|
||||
mUsage = NULL;
|
||||
mHeader = NULL;
|
||||
|
|
@ -896,10 +676,10 @@ Namespace::Entry::Entry()
|
|||
|
||||
void Namespace::Entry::clear()
|
||||
{
|
||||
if (mCode)
|
||||
if (mModule)
|
||||
{
|
||||
mCode->decRefCount();
|
||||
mCode = NULL;
|
||||
mModule->decRefCount();
|
||||
mModule = NULL;
|
||||
}
|
||||
|
||||
// Clean up usage strings generated for script functions.
|
||||
|
|
@ -1233,15 +1013,15 @@ Namespace::Entry *Namespace::createLocalEntry(StringTableEntry name)
|
|||
return ent;
|
||||
}
|
||||
|
||||
void Namespace::addFunction(StringTableEntry name, CodeBlock *cb, U32 functionOffset, const char* usage, U32 lineNumber)
|
||||
void Namespace::addFunction(StringTableEntry name, Con::Module *cb, U32 functionOffset, const char* usage, U32 lineNumber)
|
||||
{
|
||||
Entry *ent = createLocalEntry(name);
|
||||
trashCache();
|
||||
|
||||
ent->mUsage = usage;
|
||||
ent->mCode = cb;
|
||||
ent->mModule = cb;
|
||||
ent->mFunctionOffset = functionOffset;
|
||||
ent->mCode->incRefCount();
|
||||
ent->mModule->incRefCount();
|
||||
ent->mType = Entry::ConsoleFunctionType;
|
||||
ent->mFunctionLineNumber = lineNumber;
|
||||
}
|
||||
|
|
@ -1366,9 +1146,7 @@ void Namespace::markGroup(const char* name, const char* usage)
|
|||
ent->cb.mGroupName = name;
|
||||
}
|
||||
|
||||
extern S32 executeBlock(StmtNode *block, ExprEvalState *state);
|
||||
|
||||
ConsoleValue Namespace::Entry::execute(S32 argc, ConsoleValue *argv, ExprEvalState *state)
|
||||
ConsoleValue Namespace::Entry::execute(S32 argc, ConsoleValue *argv, SimObject *thisObj)
|
||||
{
|
||||
STR.clearFunctionOffset();
|
||||
|
||||
|
|
@ -1376,7 +1154,7 @@ ConsoleValue Namespace::Entry::execute(S32 argc, ConsoleValue *argv, ExprEvalSta
|
|||
{
|
||||
if (mFunctionOffset)
|
||||
{
|
||||
return std::move(mCode->exec(mFunctionOffset, argv[0].getString(), mNamespace, argc, argv, false, mPackage));
|
||||
return std::move(mModule->exec(mFunctionOffset, argv[0].getString(), mNamespace, argc, argv, false, mPackage).value);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1406,21 +1184,21 @@ ConsoleValue Namespace::Entry::execute(S32 argc, ConsoleValue *argv, ExprEvalSta
|
|||
{
|
||||
case StringCallbackType:
|
||||
{
|
||||
const char* str = cb.mStringCallbackFunc(state->thisObject, argc, argv);
|
||||
const char* str = cb.mStringCallbackFunc(thisObj, argc, argv);
|
||||
result.setString(str);
|
||||
break;
|
||||
}
|
||||
case IntCallbackType:
|
||||
result.setInt(cb.mIntCallbackFunc(state->thisObject, argc, argv));
|
||||
result.setInt(cb.mIntCallbackFunc(thisObj, argc, argv));
|
||||
break;
|
||||
case FloatCallbackType:
|
||||
result.setFloat(cb.mFloatCallbackFunc(state->thisObject, argc, argv));
|
||||
result.setFloat(cb.mFloatCallbackFunc(thisObj, argc, argv));
|
||||
break;
|
||||
case VoidCallbackType:
|
||||
cb.mVoidCallbackFunc(state->thisObject, argc, argv);
|
||||
cb.mVoidCallbackFunc(thisObj, argc, argv);
|
||||
break;
|
||||
case BoolCallbackType:
|
||||
result.setBool(cb.mBoolCallbackFunc(state->thisObject, argc, argv));
|
||||
result.setBool(cb.mBoolCallbackFunc(thisObj, argc, argv));
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -1704,7 +1482,7 @@ String Namespace::Entry::getArgumentsString() const
|
|||
|
||||
if (sFindArgumentListSubstring(mUsage, argListStart, argListEnd))
|
||||
str.append(argListStart, argListEnd - argListStart);
|
||||
else if (mType == ConsoleFunctionType && mCode)
|
||||
else if (mType == ConsoleFunctionType && mModule)
|
||||
{
|
||||
// This isn't correct but the nonsense console stuff is set up such that all
|
||||
// functions that have no function bodies are keyed to offset 0 to indicate "no code."
|
||||
|
|
@ -1716,7 +1494,7 @@ String Namespace::Entry::getArgumentsString() const
|
|||
if (!mFunctionOffset)
|
||||
return "()";
|
||||
|
||||
String args = mCode->getFunctionArgs(mFunctionOffset);
|
||||
String args = mModule->getFunctionArgs(mFunctionName, mFunctionOffset);
|
||||
if (args.isEmpty())
|
||||
return "()";
|
||||
|
||||
|
|
|
|||
|
|
@ -38,12 +38,12 @@
|
|||
#ifndef _DATACHUNKER_H_
|
||||
#include "core/dataChunker.h"
|
||||
#endif
|
||||
#include "module.h"
|
||||
|
||||
/// @ingroup console_system Console System
|
||||
/// @{
|
||||
|
||||
|
||||
class ExprEvalState;
|
||||
struct FunctionDecl;
|
||||
class CodeBlock;
|
||||
class AbstractClassRep;
|
||||
|
|
@ -125,7 +125,7 @@ public:
|
|||
ConsoleFunctionHeader* mHeader;
|
||||
|
||||
/// The compiled script code if this is a script function.
|
||||
CodeBlock* mCode;
|
||||
Con::Module* mModule;
|
||||
|
||||
/// The offset in the compiled script code at which this function begins.
|
||||
U32 mFunctionOffset;
|
||||
|
|
@ -150,7 +150,7 @@ public:
|
|||
void clear();
|
||||
|
||||
///
|
||||
ConsoleValue execute(S32 argc, ConsoleValue* argv, ExprEvalState* state);
|
||||
ConsoleValue execute(S32 argc, ConsoleValue* argv, SimObject* thisObj);
|
||||
|
||||
/// Return a one-line documentation text string for the function.
|
||||
String getBriefDescription(String* outRemainingDocText = NULL) const;
|
||||
|
|
@ -181,7 +181,7 @@ public:
|
|||
Namespace();
|
||||
~Namespace();
|
||||
|
||||
void addFunction(StringTableEntry name, CodeBlock* cb, U32 functionOffset, const char* usage = NULL, U32 lineNumber = 0);
|
||||
void addFunction(StringTableEntry name, Con::Module* cb, U32 functionOffset, const char* usage = NULL, U32 lineNumber = 0);
|
||||
void addCommand(StringTableEntry name, StringCallback, const char *usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL);
|
||||
void addCommand(StringTableEntry name, IntCallback, const char *usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL);
|
||||
void addCommand(StringTableEntry name, FloatCallback, const char *usage, S32 minArgs, S32 maxArgs, bool toolOnly = false, ConsoleFunctionHeader* header = NULL);
|
||||
|
|
@ -286,16 +286,8 @@ public:
|
|||
{
|
||||
friend class Dictionary;
|
||||
|
||||
enum
|
||||
{
|
||||
TypeInternalInt = -3,
|
||||
TypeInternalFloat = -2,
|
||||
TypeInternalString = -1,
|
||||
};
|
||||
|
||||
StringTableEntry name;
|
||||
Entry *nextEntry;
|
||||
S32 type;
|
||||
|
||||
typedef Signal<void()> NotifySignal;
|
||||
|
||||
|
|
@ -309,58 +301,17 @@ 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
|
||||
ConsoleValue value;
|
||||
|
||||
public:
|
||||
|
||||
Entry() {
|
||||
name = NULL;
|
||||
type = TypeInternalString;
|
||||
notify = NULL;
|
||||
nextEntry = NULL;
|
||||
mUsage = NULL;
|
||||
mIsConstant = false;
|
||||
mNext = NULL;
|
||||
|
||||
ival = 0;
|
||||
fval = 0;
|
||||
sval = NULL;
|
||||
bufferLen = 0;
|
||||
dataPtr = NULL;
|
||||
enumTable = NULL;
|
||||
}
|
||||
|
||||
Entry(StringTableEntry name);
|
||||
|
|
@ -370,32 +321,21 @@ public:
|
|||
|
||||
void reset();
|
||||
|
||||
inline ConsoleValue getValue() { return std::move(value); }
|
||||
|
||||
inline U32 getIntValue()
|
||||
{
|
||||
if (type <= TypeInternalString)
|
||||
return ival;
|
||||
else
|
||||
return dAtoi(Con::getData(type, dataPtr, 0, enumTable));
|
||||
return value.getInt();
|
||||
}
|
||||
|
||||
inline F32 getFloatValue()
|
||||
{
|
||||
if (type <= TypeInternalString)
|
||||
return fval;
|
||||
else
|
||||
return dAtof(Con::getData(type, dataPtr, 0, enumTable));
|
||||
return value.getFloat();
|
||||
}
|
||||
|
||||
inline const char *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);
|
||||
return value.getString();
|
||||
}
|
||||
|
||||
void setIntValue(U32 val)
|
||||
|
|
@ -406,21 +346,15 @@ public:
|
|||
return;
|
||||
}
|
||||
|
||||
if (type <= TypeInternalString)
|
||||
if (value.isConsoleType())
|
||||
{
|
||||
fval = (F32)val;
|
||||
ival = val;
|
||||
if (sval != NULL)
|
||||
{
|
||||
dFree(sval);
|
||||
sval = NULL;
|
||||
}
|
||||
type = TypeInternalInt;
|
||||
const char* dptr = Con::getData(TypeS32, &val, 0);
|
||||
ConsoleValueConsoleType* cvt = value.getConsoleType();
|
||||
Con::setData(cvt->consoleType, cvt->dataPtr, 0, 1, &dptr, cvt->enumTable);
|
||||
}
|
||||
else
|
||||
{
|
||||
const char* dptr = Con::getData(TypeS32, &val, 0);
|
||||
Con::setData(type, dataPtr, 0, 1, &dptr, enumTable);
|
||||
value.setInt(val);
|
||||
}
|
||||
|
||||
// Fire off the notification if we have one.
|
||||
|
|
@ -436,21 +370,15 @@ public:
|
|||
return;
|
||||
}
|
||||
|
||||
if (type <= TypeInternalString)
|
||||
if (value.isConsoleType())
|
||||
{
|
||||
fval = val;
|
||||
ival = static_cast<U32>(val);
|
||||
if (sval != NULL)
|
||||
{
|
||||
dFree(sval);
|
||||
sval = NULL;
|
||||
}
|
||||
type = TypeInternalFloat;
|
||||
const char* dptr = Con::getData(TypeF32, &val, 0);
|
||||
ConsoleValueConsoleType* cvt = value.getConsoleType();
|
||||
Con::setData(cvt->consoleType, cvt->dataPtr, 0, 1, &dptr, cvt->enumTable);
|
||||
}
|
||||
else
|
||||
{
|
||||
const char* dptr = Con::getData(TypeF32, &val, 0);
|
||||
Con::setData(type, dataPtr, 0, 1, &dptr, enumTable);
|
||||
value.setFloat(val);
|
||||
}
|
||||
|
||||
// Fire off the notification if we have one.
|
||||
|
|
@ -458,7 +386,29 @@ public:
|
|||
notify->trigger();
|
||||
}
|
||||
|
||||
void setStringValue(const char* value);
|
||||
|
||||
void setStringValue(const char* val)
|
||||
{
|
||||
if (mIsConstant)
|
||||
{
|
||||
Con::errorf("Cannot assign value to constant '%s'.", name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (value.isConsoleType())
|
||||
{
|
||||
ConsoleValueConsoleType* cvt = value.getConsoleType();
|
||||
Con::setData(cvt->consoleType, cvt->dataPtr, 0, 1, &val, cvt->enumTable);
|
||||
}
|
||||
else
|
||||
{
|
||||
value.setString(val);
|
||||
}
|
||||
|
||||
// Fire off the notification if we have one.
|
||||
if (notify)
|
||||
notify->trigger();
|
||||
}
|
||||
};
|
||||
|
||||
struct HashTableData
|
||||
|
|
@ -475,11 +425,10 @@ public:
|
|||
|
||||
HashTableData* hashTable;
|
||||
HashTableData ownHashTable;
|
||||
ExprEvalState *exprState;
|
||||
|
||||
StringTableEntry scopeName;
|
||||
Namespace *scopeNamespace;
|
||||
CodeBlock *code;
|
||||
Con::Module *module;
|
||||
U32 ip;
|
||||
|
||||
Dictionary();
|
||||
|
|
@ -487,7 +436,7 @@ public:
|
|||
|
||||
Entry *lookup(StringTableEntry name);
|
||||
Entry *add(StringTableEntry name);
|
||||
void setState(ExprEvalState *state, Dictionary* ref = NULL);
|
||||
void setState(Dictionary* ref = NULL);
|
||||
void remove(Entry *);
|
||||
void reset();
|
||||
|
||||
|
|
@ -547,126 +496,35 @@ struct ConsoleValueFrame
|
|||
}
|
||||
};
|
||||
|
||||
class ExprEvalState
|
||||
{
|
||||
public:
|
||||
/// @name Expression Evaluation
|
||||
/// @{
|
||||
|
||||
///
|
||||
SimObject *thisObject;
|
||||
Dictionary::Entry *currentVariable;
|
||||
Dictionary::Entry *copyVariable;
|
||||
bool traceOn;
|
||||
|
||||
U32 mStackDepth;
|
||||
bool mShouldReset; ///< Designates if the value stack should be reset
|
||||
bool mResetLocked; ///< mShouldReset will be set at the end
|
||||
|
||||
ExprEvalState();
|
||||
~ExprEvalState();
|
||||
|
||||
/// @}
|
||||
|
||||
/// @name Stack Management
|
||||
/// @{
|
||||
|
||||
/// The stack of callframes. The extra redirection is necessary since Dictionary holds
|
||||
/// an interior pointer that will become invalid when the object changes address.
|
||||
Vector< Dictionary* > stack;
|
||||
|
||||
S32 getTopOfStack() { return (S32)mStackDepth; }
|
||||
|
||||
Vector< ConsoleValueFrame > localStack;
|
||||
ConsoleValueFrame* currentRegisterArray; // contains array at to top of localStack
|
||||
|
||||
///
|
||||
Dictionary globalVars;
|
||||
|
||||
void setCurVarName(StringTableEntry name);
|
||||
void setCurVarNameCreate(StringTableEntry name);
|
||||
|
||||
S32 getIntVariable();
|
||||
F64 getFloatVariable();
|
||||
const char *getStringVariable();
|
||||
void setIntVariable(S32 val);
|
||||
void setFloatVariable(F64 val);
|
||||
void setStringVariable(const char *str);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
Dictionary& getCurrentFrame()
|
||||
{
|
||||
return *(stack[mStackDepth - 1]);
|
||||
}
|
||||
|
||||
Dictionary& getFrameAt(S32 depth)
|
||||
{
|
||||
return *(stack[depth]);
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
/// Run integrity checks for debugging.
|
||||
void validate();
|
||||
};
|
||||
|
||||
namespace Con
|
||||
{
|
||||
/// The current $instantGroup setting.
|
||||
extern String gInstantGroup;
|
||||
|
||||
/// Global variable storage
|
||||
inline Dictionary gGlobalVars;
|
||||
|
||||
typedef Dictionary ConsoleFrame;
|
||||
typedef Vector<ConsoleFrame*> ConsoleStack;
|
||||
|
||||
inline ConsoleStack gFrameStack;
|
||||
|
||||
inline ConsoleStack getFrameStack() { return gFrameStack; }
|
||||
inline void pushStackFrame(ConsoleFrame* frame) { gFrameStack.push_back(frame); }
|
||||
inline ConsoleFrame* popStackFrame() { ConsoleFrame* last = gFrameStack.last(); gFrameStack.pop_back(); return last; }
|
||||
inline ConsoleFrame* getCurrentStackFrame() { return getFrameStack().empty() ? NULL : gFrameStack.last(); }
|
||||
inline ConsoleFrame* getStackFrame(S32 idx) { return gFrameStack[idx]; }
|
||||
|
||||
inline Vector<Con::Module*> gScriptModules;
|
||||
|
||||
inline Vector<Con::Module*> getAllScriptModules() { return gScriptModules; }
|
||||
Con::Module* findScriptModuleForFile(const char* fileName);
|
||||
// Convenience functions for getting the execution context
|
||||
inline const char* getCurrentScriptModulePath() { return getCurrentStackFrame() && getCurrentStackFrame()->module ? getCurrentStackFrame()->module->getPath() : NULL; }
|
||||
inline const char* getCurrentScriptModuleName() { return getCurrentStackFrame() && getCurrentStackFrame()->module ? getCurrentStackFrame()->module->getName() : NULL; }
|
||||
inline Con::Module* getCurrentScriptModule() { return getCurrentStackFrame() ? getCurrentStackFrame()->module : NULL; }
|
||||
|
||||
inline bool gTraceOn;
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@
|
|||
#include "console/engineAPI.h"
|
||||
#include "core/stream/fileStream.h"
|
||||
#include "console/consoleInternal.h"
|
||||
#include "console/compiler.h"
|
||||
|
||||
#define USE_UNDOCUMENTED_GROUP
|
||||
|
||||
|
|
@ -113,10 +112,10 @@ static void dumpVariable( Stream& stream,
|
|||
const char* inClass = NULL )
|
||||
{
|
||||
// Skip variables defined in script.
|
||||
|
||||
if( entry->type <= Dictionary::Entry::TypeInternalString )
|
||||
|
||||
if( entry->value.getType() <= ConsoleValueType::cvString )
|
||||
return;
|
||||
|
||||
|
||||
// Skip internals... don't export them.
|
||||
if ( entry->mUsage &&
|
||||
( dStrstr( entry->mUsage, "@hide" ) || dStrstr( entry->mUsage, "@internal" ) ) )
|
||||
|
|
@ -146,10 +145,10 @@ static void dumpVariable( Stream& stream,
|
|||
if( nameComponents.size() > 1 && Con::lookupNamespace( nameComponents.first().c_str() + 1 )->mClassRep )
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Skip variables for which we can't decipher their type.
|
||||
|
||||
ConsoleBaseType* type = ConsoleBaseType::getType( entry->type );
|
||||
ConsoleBaseType* type = ConsoleBaseType::getType( entry->value.getConsoleType()->consoleType );
|
||||
if( !type )
|
||||
{
|
||||
Con::errorf( "Can't find type for variable '%s'", entry->name );
|
||||
|
|
@ -204,9 +203,9 @@ static void dumpVariable( Stream& stream,
|
|||
|
||||
static void dumpVariables( Stream& stream, const char* inClass = NULL )
|
||||
{
|
||||
const U32 hashTableSize = gEvalState.globalVars.hashTable->size;
|
||||
const U32 hashTableSize = Con::gGlobalVars.hashTable->size;
|
||||
for( U32 i = 0; i < hashTableSize; ++ i )
|
||||
for( Dictionary::Entry* entry = gEvalState.globalVars.hashTable->data[ i ]; entry != NULL; entry = entry->nextEntry )
|
||||
for( Dictionary::Entry* entry = Con::gGlobalVars.hashTable->data[ i ]; entry != NULL; entry = entry->nextEntry )
|
||||
dumpVariable( stream, entry, inClass );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,9 +24,7 @@
|
|||
#include "console/console.h"
|
||||
#include "console/consoleInternal.h"
|
||||
#include "console/engineAPI.h"
|
||||
#include "console/ast.h"
|
||||
#include "core/stream/fileStream.h"
|
||||
#include "console/compiler.h"
|
||||
#include "platform/platformInput.h"
|
||||
#include "torqueConfig.h"
|
||||
#include "core/frameAllocator.h"
|
||||
|
|
@ -420,7 +418,7 @@ DefineEngineFunction(isScriptFile, bool, (const char* fileName), ,
|
|||
|
||||
"@ingroup FileSystem")
|
||||
{
|
||||
return Torque::FS::IsScriptFile(fileName);
|
||||
return Con::isScriptFile(fileName);
|
||||
}
|
||||
|
||||
DefineEngineFunction( IsDirectory, bool, ( const char* directory ),,
|
||||
|
|
|
|||
45
Engine/source/console/module.h
Normal file
45
Engine/source/console/module.h
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
#ifndef _SCRIPT_MODULE_H_
|
||||
#define _SCRIPT_MODULE_H_
|
||||
#include "runtime.h"
|
||||
#include "console/console.h"
|
||||
#include "platform/types.h"
|
||||
|
||||
namespace Con
|
||||
{
|
||||
class Module
|
||||
{
|
||||
private:
|
||||
S32 mRefCount = 0;
|
||||
public:
|
||||
Module() = default;
|
||||
virtual ~Module() = default;
|
||||
|
||||
void incRefCount() { mRefCount++; }
|
||||
void decRefCount() { mRefCount--; if (!mRefCount) delete this; }
|
||||
virtual const char* getFunctionArgs(StringTableEntry functionName, U32 functionOffset) = 0;
|
||||
virtual const char* getPath() = 0;
|
||||
virtual const char* getName() = 0;
|
||||
|
||||
virtual EvalResult exec(U32 offset, const char* fnName, Namespace* ns, U32 argc,
|
||||
ConsoleValue* argv, bool noCalls, StringTableEntry packageName,
|
||||
S32 setFrame = -1) = 0;
|
||||
virtual void findBreakLine(U32 ip, U32& line, U32& instruction) = 0;
|
||||
virtual const char *getFileLine(U32 ip) = 0;
|
||||
|
||||
/// Returns the first breakable line or 0 if none was found.
|
||||
/// @param lineNumber The one based line number.
|
||||
virtual U32 findFirstBreakLine(U32 lineNumber) = 0;
|
||||
|
||||
/// Set a OP_BREAK instruction on a line. If a break
|
||||
/// is not possible on that line it returns false.
|
||||
/// @param lineNumber The one based line number.
|
||||
virtual bool setBreakpoint(U32 lineNumber) = 0;
|
||||
|
||||
virtual void setAllBreaks() = 0;
|
||||
virtual void clearAllBreaks() = 0;
|
||||
virtual void clearBreakpoint(U32 lineNumber) = 0;
|
||||
virtual Vector<U32> getBreakableLines() = 0;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -35,8 +35,6 @@
|
|||
// Property system includes:
|
||||
#include "console/propertyParsing.h"
|
||||
|
||||
extern ExprEvalState gEvalState;
|
||||
|
||||
namespace PropertyInfo
|
||||
{
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
|||
112
Engine/source/console/runtime.h
Normal file
112
Engine/source/console/runtime.h
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
#ifndef _RUNTIME_H_
|
||||
#define _RUNTIME_H_
|
||||
|
||||
#include "console/console.h"
|
||||
|
||||
namespace Con
|
||||
{
|
||||
struct EvalResult
|
||||
{
|
||||
bool valid;
|
||||
ConsoleValue value;
|
||||
String error;
|
||||
|
||||
public:
|
||||
EvalResult() {}
|
||||
|
||||
EvalResult(ConsoleValue&& pValue)
|
||||
{
|
||||
valid = true;
|
||||
value = (ConsoleValue&&)pValue;
|
||||
}
|
||||
|
||||
EvalResult(String errorMessage)
|
||||
{
|
||||
valid = false;
|
||||
error = errorMessage;
|
||||
}
|
||||
};
|
||||
|
||||
struct Error
|
||||
{
|
||||
const char* message;
|
||||
};
|
||||
|
||||
struct SyntaxError : Error {};
|
||||
|
||||
class Stack
|
||||
{
|
||||
class Frame
|
||||
{
|
||||
public:
|
||||
ConsoleValue* lookup(const char*);
|
||||
};
|
||||
|
||||
public:
|
||||
S32 getDepth();
|
||||
Frame getFrame(S32 idx);
|
||||
};
|
||||
|
||||
class Runtime
|
||||
{
|
||||
private:
|
||||
Stack mStack;
|
||||
public:
|
||||
virtual ~Runtime() = default;
|
||||
virtual Stack getStack() { return mStack; }
|
||||
|
||||
/// Convert from a relative script path to an absolute script path.
|
||||
///
|
||||
/// This is used in (among other places) the exec() script function, which
|
||||
/// takes a parameter indicating a script file and executes it. Script paths
|
||||
/// can be one of:
|
||||
/// - <b>Absolute:</b> <i>fps/foo/bar.tscript</i> Paths of this sort are passed
|
||||
/// through.
|
||||
/// - <b>Mod-relative:</b> <i>~/foo/bar.tscript</i> Paths of this sort have their
|
||||
/// replaced with the name of the current mod.
|
||||
/// - <b>File-relative:</b> <i>./baz/blip.tscript</i> Paths of this sort are
|
||||
/// calculated relative to the path of the current scripting file.
|
||||
///
|
||||
/// @note This function determines paths relative to the currently executing
|
||||
/// CodeBlock. Calling it outside of script execution will result in
|
||||
/// it directly copying src to filename, since it won't know to what the
|
||||
/// path is relative!
|
||||
///
|
||||
/// @param filename Pointer to string buffer to fill with absolute path.
|
||||
/// @param size Size of buffer pointed to by filename.
|
||||
/// @param src Original, possibly relative script path.
|
||||
bool expandScriptFilename(char *filename, U32 size, const char *src);
|
||||
bool expandToolScriptFilename(char *filename, U32 size, const char *src);
|
||||
bool collapseScriptFilename(char *filename, U32 size, const char *src);
|
||||
|
||||
virtual void expandEscapedCharacters(char* dest, const char* src) = 0;
|
||||
virtual bool collapseEscapedCharacters(char* buf) = 0;
|
||||
|
||||
/// Evaluate an arbitrary chunk of code.
|
||||
///
|
||||
/// @param string Buffer containing code to execute.
|
||||
/// @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.
|
||||
virtual EvalResult evaluate(const char* string, bool echo = false, const char *fileName = NULL) = 0;
|
||||
|
||||
virtual EvalResult evaluate(const char* string, S32 frame, bool echo = false, const char *fileName = NULL) = 0;
|
||||
|
||||
/// 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.
|
||||
virtual EvalResult evaluatef(const char* string, ...) = 0;
|
||||
|
||||
/// Executes a script file and compiles it for use in script.
|
||||
///
|
||||
/// @param fileName File name that is the script to be executed and compiled.
|
||||
/// @param noCalls Deprecated
|
||||
/// @param journalScript Deprecated
|
||||
///
|
||||
/// @return True if the script was successfully executed, false if not.
|
||||
virtual bool executeFile(const char* fileName, bool noCalls, bool journalScript) = 0;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
71
Engine/source/console/script.h
Normal file
71
Engine/source/console/script.h
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
#ifndef _SCRIPT_H_
|
||||
#define _SCRIPT_H_
|
||||
|
||||
#include "runtime.h"
|
||||
#include "core/stream/stream.h"
|
||||
#include "module.h"
|
||||
#include "core/util/tDictionary.h"
|
||||
|
||||
namespace Con
|
||||
{
|
||||
inline EvalResult gLastEvalResult;
|
||||
inline EvalResult setLastEvalResult(EvalResult pLastEvalResult)
|
||||
{
|
||||
gLastEvalResult.valid = pLastEvalResult.valid;
|
||||
gLastEvalResult.error = pLastEvalResult.error;
|
||||
gLastEvalResult.value.setString(pLastEvalResult.value.getString());
|
||||
return std::move(pLastEvalResult);
|
||||
}
|
||||
inline EvalResult getLastEvalResult() { return setLastEvalResult(std::move(gLastEvalResult)); };
|
||||
|
||||
bool runStream(Stream* byteCode, const char* fileName);
|
||||
|
||||
bool isCurrentScriptToolScript();
|
||||
|
||||
|
||||
Module* getCurrentModule();
|
||||
|
||||
inline HashMap<S32, Runtime*> gRuntimes;
|
||||
inline Runtime* getRuntime(S32 pRuntimeId = 0) { return gRuntimes[pRuntimeId]; }
|
||||
inline void registerRuntime(S32 pRuntimeId, Runtime* pRuntime)
|
||||
{
|
||||
AssertFatal(gRuntimes[pRuntimeId] == NULL, "A runtime with that ID already exists");
|
||||
gRuntimes[pRuntimeId] = pRuntime;
|
||||
}
|
||||
|
||||
|
||||
/// Evaluate an arbitrary chunk of code.
|
||||
///
|
||||
/// @param script Buffer containing code to execute.
|
||||
/// @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.
|
||||
inline EvalResult evaluate(const char* script, bool echo = false, const char *fileName = NULL) { return setLastEvalResult(getRuntime()->evaluate(script, echo, fileName)); };
|
||||
|
||||
inline EvalResult evaluate(const char* script, S32 frame, bool echo = false, const char *fileName = NULL) { return setLastEvalResult(getRuntime()->evaluate(script, frame, echo, fileName)); };
|
||||
|
||||
/// 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.
|
||||
inline EvalResult evaluatef(const char* string, ...)
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, string);
|
||||
EvalResult result = setLastEvalResult(getRuntime()->evaluatef(string, args));
|
||||
va_end(args);
|
||||
return result;
|
||||
};
|
||||
|
||||
/// Executes a script file and compiles it for use in script.
|
||||
///
|
||||
/// @param string File name that is the script to be executed and compiled.
|
||||
/// @param fileName Path to the file to execute
|
||||
/// @param noCalls Deprecated
|
||||
/// @param journalScript Deprecated
|
||||
///
|
||||
/// @return True if the script was successfully executed, false if not.
|
||||
inline bool executeFile(const char* fileName, bool noCalls, bool journalScript) { return getRuntime()->executeFile(fileName, noCalls, journalScript); };
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -23,12 +23,12 @@
|
|||
#include "platform/platform.h"
|
||||
#include "console/scriptFilename.h"
|
||||
|
||||
#include "consoleInternal.h"
|
||||
#include "core/frameAllocator.h"
|
||||
#include "core/tSimpleHashTable.h"
|
||||
#include "core/strings/stringFunctions.h"
|
||||
#include "core/stringTable.h"
|
||||
#include "console/engineAPI.h"
|
||||
#include "console/compiler.h"
|
||||
|
||||
|
||||
namespace Con
|
||||
|
|
@ -88,8 +88,8 @@ bool expandToolScriptFilename(char *filename, U32 size, const char *src)
|
|||
// same way the old code did as it is now possible that something could
|
||||
// be expanded if the name or mod is NULL. This was previously not the case.
|
||||
|
||||
const StringTableEntry cbMod = CodeBlock::getCurrentCodeBlockModName();
|
||||
const StringTableEntry cbFullPath = CodeBlock::getCurrentCodeBlockFullPath();
|
||||
const StringTableEntry cbMod = Con::getCurrentScriptModuleName();
|
||||
const StringTableEntry cbFullPath = Con::getCurrentScriptModulePath();
|
||||
|
||||
char varBuf[1024], modBuf[1024];
|
||||
const char *ptr = src;
|
||||
|
|
@ -216,7 +216,8 @@ bool expandToolScriptFilename(char *filename, U32 size, const char *src)
|
|||
|
||||
bool expandOldScriptFilename(char *filename, U32 size, const char *src)
|
||||
{
|
||||
const StringTableEntry cbName = CodeBlock::getCurrentCodeBlockName();
|
||||
const StringTableEntry cbName = Con::getCurrentScriptModuleName();
|
||||
|
||||
if (!cbName)
|
||||
{
|
||||
dStrcpy(filename, src, size);
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include "platform/platform.h"
|
||||
#include "console/simDatablock.h"
|
||||
|
||||
#include "script.h"
|
||||
#include "console/console.h"
|
||||
#include "console/consoleInternal.h"
|
||||
#include "console/engineAPI.h"
|
||||
|
|
@ -34,7 +35,6 @@
|
|||
#include "T3D/gameBase/gameConnection.h"
|
||||
|
||||
#include "core/stream/bitStream.h"
|
||||
#include "console/compiler.h"
|
||||
|
||||
IMPLEMENT_CO_DATABLOCK_V1(SimDataBlock);
|
||||
SimObjectId SimDataBlock::sNextObjectId = DataBlockObjectIdFirst;
|
||||
|
|
@ -252,17 +252,14 @@ void SimDataBlock::performSubstitutions(SimDataBlock* dblock, const SimObject* o
|
|||
|
||||
b[0] = '\0';
|
||||
|
||||
// perform the statement evaluation
|
||||
Compiler::gSyntaxError = false;
|
||||
//Con::errorf("EVAL [%s]", avar("return %s;", buffer));
|
||||
const char *result = Con::evaluate(avar("return %s;", buffer), false, 0);
|
||||
if (Compiler::gSyntaxError)
|
||||
Con::EvalResult evalResult = Con::evaluate(avar("return %s;", buffer), false, 0);
|
||||
if (evalResult.valid)
|
||||
{
|
||||
Con::errorf("Field Substitution Failed: field=\"%s\" substitution=\"%s\" -- syntax error",
|
||||
substitutions[i]->mSlot, substitutions[i]->mValue);
|
||||
Compiler::gSyntaxError = false;
|
||||
return;
|
||||
}
|
||||
const char* result = evalResult.value;
|
||||
|
||||
// output a runtime console error when a substitution produces and empty result.
|
||||
if (result == 0 || result[0] == '\0')
|
||||
|
|
|
|||
|
|
@ -25,9 +25,6 @@
|
|||
#include "platform/threads/semaphore.h"
|
||||
#include "console/simEvents.h"
|
||||
|
||||
// Stupid globals not declared in a header
|
||||
extern ExprEvalState gEvalState;
|
||||
|
||||
SimConsoleEvent::SimConsoleEvent(S32 argc, ConsoleValue *argv, bool onObject)
|
||||
{
|
||||
mOnObject = onObject;
|
||||
|
|
@ -79,7 +76,7 @@ void SimConsoleEvent::process(SimObject* object)
|
|||
Namespace::Entry* nse = ns->lookup( StringTable->insert( func ) );
|
||||
if( nse )
|
||||
// Execute.
|
||||
nse->execute( mArgc, mArgv, &gEvalState );
|
||||
nse->execute( mArgc, mArgv, object );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "script.h"
|
||||
#include "platform/platform.h"
|
||||
#include "platform/threads/mutex.h"
|
||||
#include "console/simBase.h"
|
||||
|
|
@ -36,8 +37,6 @@
|
|||
#include "platform/profiler.h"
|
||||
#include "math/mMathFn.h"
|
||||
|
||||
extern ExprEvalState gEvalState;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
|
@ -341,9 +340,9 @@ SimObject* findObject(const char* name)
|
|||
|
||||
if (c == '%')
|
||||
{
|
||||
if (gEvalState.getStackDepth())
|
||||
if (!Con::getFrameStack().empty())
|
||||
{
|
||||
Dictionary::Entry* ent = gEvalState.getCurrentFrame().lookup(StringTable->insert(name));
|
||||
Dictionary::Entry* ent = Con::getCurrentStackFrame()->lookup(StringTable->insert(name));
|
||||
|
||||
if (ent)
|
||||
return Sim::findObject(ent->getIntValue());
|
||||
|
|
|
|||
|
|
@ -35,7 +35,6 @@
|
|||
#include "console/simPersistID.h"
|
||||
#include "console/typeValidators.h"
|
||||
#include "console/arrayObject.h"
|
||||
#include "console/codeBlock.h"
|
||||
#include "core/frameAllocator.h"
|
||||
#include "core/stream/fileStream.h"
|
||||
#include "core/fileObject.h"
|
||||
|
|
@ -2479,7 +2478,7 @@ static void sEnumCallback( EngineObject* object )
|
|||
if( !simObject )
|
||||
return;
|
||||
|
||||
Con::evaluatef( "%s( %i );", sEnumCallbackFunction, simObject->getId() );
|
||||
Con::executef(sEnumCallbackFunction, simObject->getId());
|
||||
}
|
||||
|
||||
DefineEngineFunction( debugEnumInstances, void, ( const char* className, const char* functionName ),,
|
||||
|
|
@ -2645,10 +2644,10 @@ DefineEngineMethod( SimObject, dumpMethods, ArrayObject*, (),,
|
|||
str.append( e->getPrototypeString() );
|
||||
|
||||
str.append( '\n' );
|
||||
if( e->mCode && e->mCode->fullPath )
|
||||
str.append( e->mCode->fullPath );
|
||||
if( e->mModule && e->mModule->getPath() )
|
||||
str.append( e->mModule->getPath() );
|
||||
str.append( '\n' );
|
||||
if( e->mCode )
|
||||
if( e->mModule )
|
||||
str.append( String::ToString( e->mFunctionLineNumber ) );
|
||||
|
||||
str.append( '\n' );
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#include "platform/platform.h"
|
||||
#include "console/simObjectMemento.h"
|
||||
|
||||
#include "script.h"
|
||||
#include "console/simObject.h"
|
||||
#include "console/simDatablock.h"
|
||||
#include "core/stream/memStream.h"
|
||||
|
|
@ -95,7 +96,7 @@ SimObject *SimObjectMemento::restore() const
|
|||
|
||||
// Read the object.
|
||||
|
||||
const UTF8* result = Con::evaluate( mState );
|
||||
const UTF8* result = Con::evaluate( mState ).value;
|
||||
|
||||
// Restore the redefine behavior.
|
||||
|
||||
|
|
|
|||
|
|
@ -28,10 +28,9 @@
|
|||
#include "console/engineAPI.h"
|
||||
#include "core/stringTable.h"
|
||||
#include "console/consoleInternal.h"
|
||||
#include "console/ast.h"
|
||||
#include "console/compiler.h"
|
||||
#include "core/util/journal/process.h"
|
||||
#include "core/module.h"
|
||||
#include "script.h"
|
||||
|
||||
|
||||
MODULE_BEGIN( TelnetDebugger )
|
||||
|
|
@ -169,7 +168,7 @@ TelnetDebugger::TelnetDebugger()
|
|||
// Add the version number in a global so that
|
||||
// scripts can detect the presence of the
|
||||
// "enhanced" debugger features.
|
||||
Con::evaluatef( "$dbgVersion = %d;", Version );
|
||||
Con::setIntVariable("dbgVersion", Version);
|
||||
}
|
||||
|
||||
TelnetDebugger::Breakpoint **TelnetDebugger::findBreakpoint(StringTableEntry fileName, S32 lineNumber)
|
||||
|
|
@ -380,7 +379,7 @@ void TelnetDebugger::checkDebugRecv()
|
|||
}
|
||||
}
|
||||
|
||||
void TelnetDebugger::executionStopped(CodeBlock *code, U32 lineNumber)
|
||||
void TelnetDebugger::executionStopped(Con::Module *module, U32 lineNumber)
|
||||
{
|
||||
if(mProgramPaused)
|
||||
return;
|
||||
|
|
@ -392,13 +391,13 @@ void TelnetDebugger::executionStopped(CodeBlock *code, U32 lineNumber)
|
|||
return;
|
||||
}
|
||||
|
||||
Breakpoint **bp = findBreakpoint(code->name, lineNumber);
|
||||
Breakpoint **bp = findBreakpoint(module->getName(), lineNumber);
|
||||
if(!bp)
|
||||
return;
|
||||
|
||||
Breakpoint *brk = *bp;
|
||||
mProgramPaused = true;
|
||||
Con::evaluatef("$Debug::result = %s;", brk->testExpression);
|
||||
Con::setVariable("$Debug::result", brk->testExpression);
|
||||
if(Con::getBoolVariable("$Debug::result"))
|
||||
{
|
||||
brk->curCount++;
|
||||
|
|
@ -406,7 +405,7 @@ void TelnetDebugger::executionStopped(CodeBlock *code, U32 lineNumber)
|
|||
{
|
||||
brk->curCount = 0;
|
||||
if(brk->clearOnHit)
|
||||
removeBreakpoint(code->name, lineNumber);
|
||||
removeBreakpoint(module->getName(), lineNumber);
|
||||
breakProcess();
|
||||
}
|
||||
}
|
||||
|
|
@ -418,8 +417,8 @@ void TelnetDebugger::pushStackFrame()
|
|||
if(mState == NotConnected)
|
||||
return;
|
||||
|
||||
if(mBreakOnNextStatement && mStackPopBreakIndex > -1 &&
|
||||
gEvalState.getStackDepth() > mStackPopBreakIndex)
|
||||
if(mBreakOnNextStatement && mStackPopBreakIndex > -1 &&
|
||||
Con::getFrameStack().size() > mStackPopBreakIndex)
|
||||
setBreakOnNextStatement( false );
|
||||
}
|
||||
|
||||
|
|
@ -428,7 +427,7 @@ void TelnetDebugger::popStackFrame()
|
|||
if(mState == NotConnected)
|
||||
return;
|
||||
|
||||
if(mStackPopBreakIndex > -1 && gEvalState.getStackDepth()-1 <= mStackPopBreakIndex)
|
||||
if(mStackPopBreakIndex > -1 && Con::getFrameStack().size()-1 <= mStackPopBreakIndex)
|
||||
setBreakOnNextStatement( true );
|
||||
}
|
||||
|
||||
|
|
@ -461,14 +460,14 @@ void TelnetDebugger::sendBreak()
|
|||
|
||||
S32 last = 0;
|
||||
|
||||
for(S32 i = (S32) gEvalState.getStackDepth() - 1; i >= last; i--)
|
||||
for(S32 i = (S32) Con::getFrameStack().size() - 1; i >= last; i--)
|
||||
{
|
||||
CodeBlock *code = gEvalState.stack[i]->code;
|
||||
Con::Module *module = Con::getStackFrame(i)->module;
|
||||
const char *file = "<none>";
|
||||
if (code && code->name && code->name[0])
|
||||
file = code->name;
|
||||
if (module && module->getName() && module->getName()[0])
|
||||
file = module->getName();
|
||||
|
||||
Namespace *ns = gEvalState.stack[i]->scopeNamespace;
|
||||
Namespace *ns = Con::getStackFrame(i)->scopeNamespace;
|
||||
scope[0] = 0;
|
||||
if ( ns ) {
|
||||
|
||||
|
|
@ -482,15 +481,15 @@ void TelnetDebugger::sendBreak()
|
|||
}
|
||||
}
|
||||
|
||||
const char *function = gEvalState.stack[i]->scopeName;
|
||||
const char *function = Con::getStackFrame(i)->scopeName;
|
||||
if ((!function) || (!function[0]))
|
||||
function = "<none>";
|
||||
dStrcat( scope, function, MaxCommandSize );
|
||||
|
||||
U32 line=0, inst;
|
||||
U32 ip = gEvalState.stack[i]->ip;
|
||||
if (code)
|
||||
code->findBreakLine(ip, line, inst);
|
||||
U32 ip = Con::getStackFrame(i)->ip;
|
||||
if (module)
|
||||
module->findBreakLine(ip, line, inst);
|
||||
dSprintf(buffer, MaxCommandSize, " %s %d %s", file, line, scope);
|
||||
send(buffer);
|
||||
}
|
||||
|
|
@ -579,7 +578,7 @@ void TelnetDebugger::removeVariableBreakpoint(const char*)
|
|||
send("removeVariableBreakpoint\r\n");
|
||||
}
|
||||
|
||||
void TelnetDebugger::addAllBreakpoints(CodeBlock *code)
|
||||
void TelnetDebugger::addAllBreakpoints(Con::Module *module)
|
||||
{
|
||||
if(mState == NotConnected)
|
||||
return;
|
||||
|
|
@ -590,14 +589,14 @@ void TelnetDebugger::addAllBreakpoints(CodeBlock *code)
|
|||
{
|
||||
// TODO: This assumes that the OS file names are case
|
||||
// insensitive... Torque needs a dFilenameCmp() function.
|
||||
if( dStricmp( cur->fileName, code->name ) == 0 )
|
||||
if( dStricmp( cur->fileName, module->getName() ) == 0 )
|
||||
{
|
||||
cur->code = code;
|
||||
cur->module = module;
|
||||
|
||||
// Find the fist breakline starting from and
|
||||
// including the requested breakline.
|
||||
S32 newLine = code->findFirstBreakLine(cur->lineNumber);
|
||||
if (newLine <= 0)
|
||||
S32 newLine = module->findFirstBreakLine(cur->lineNumber);
|
||||
if (newLine <= 0)
|
||||
{
|
||||
char buffer[MaxCommandSize];
|
||||
dSprintf(buffer, MaxCommandSize, "BRKCLR %s %d\r\n", cur->fileName, cur->lineNumber);
|
||||
|
|
@ -638,7 +637,7 @@ void TelnetDebugger::addAllBreakpoints(CodeBlock *code)
|
|||
cur->lineNumber = newLine;
|
||||
}
|
||||
|
||||
code->setBreakpoint(cur->lineNumber);
|
||||
module->setBreakpoint(cur->lineNumber);
|
||||
}
|
||||
|
||||
cur = cur->next;
|
||||
|
|
@ -646,7 +645,7 @@ void TelnetDebugger::addAllBreakpoints(CodeBlock *code)
|
|||
|
||||
// Enable all breaks if a break next was set.
|
||||
if (mBreakOnNextStatement)
|
||||
code->setAllBreaks();
|
||||
module->setAllBreaks();
|
||||
}
|
||||
|
||||
void TelnetDebugger::addBreakpoint(const char *fileName, S32 line, bool clear, S32 passCount, const char *evalString)
|
||||
|
|
@ -668,12 +667,12 @@ void TelnetDebugger::addBreakpoint(const char *fileName, S32 line, bool clear, S
|
|||
{
|
||||
// Note that if the code block is not already
|
||||
// loaded it is handled by addAllBreakpoints.
|
||||
CodeBlock* code = CodeBlock::find(fileName);
|
||||
if (code)
|
||||
Con::Module* module = Con::findScriptModuleForFile(fileName);
|
||||
if (module)
|
||||
{
|
||||
// Find the fist breakline starting from and
|
||||
// including the requested breakline.
|
||||
S32 newLine = code->findFirstBreakLine(line);
|
||||
S32 newLine = module->findFirstBreakLine(line);
|
||||
if (newLine <= 0)
|
||||
{
|
||||
char buffer[MaxCommandSize];
|
||||
|
|
@ -703,11 +702,11 @@ void TelnetDebugger::addBreakpoint(const char *fileName, S32 line, bool clear, S
|
|||
line = newLine;
|
||||
}
|
||||
|
||||
code->setBreakpoint(line);
|
||||
module->setBreakpoint(line);
|
||||
}
|
||||
|
||||
Breakpoint *brk = new Breakpoint;
|
||||
brk->code = code;
|
||||
brk->module = module;
|
||||
brk->fileName = fileName;
|
||||
brk->lineNumber = line;
|
||||
brk->passCount = passCount;
|
||||
|
|
@ -719,13 +718,13 @@ void TelnetDebugger::addBreakpoint(const char *fileName, S32 line, bool clear, S
|
|||
}
|
||||
}
|
||||
|
||||
void TelnetDebugger::removeBreakpointsFromCode(CodeBlock *code)
|
||||
void TelnetDebugger::removeBreakpointsFromCode(Con::Module *code)
|
||||
{
|
||||
Breakpoint **walk = &mBreakpoints;
|
||||
Breakpoint *cur;
|
||||
while((cur = *walk) != NULL)
|
||||
{
|
||||
if(cur->code == code)
|
||||
if(cur->module == code)
|
||||
{
|
||||
dFree(cur->testExpression);
|
||||
*walk = cur->next;
|
||||
|
|
@ -744,8 +743,8 @@ void TelnetDebugger::removeBreakpoint(const char *fileName, S32 line)
|
|||
{
|
||||
Breakpoint *brk = *bp;
|
||||
*bp = brk->next;
|
||||
if ( brk->code )
|
||||
brk->code->clearBreakpoint(brk->lineNumber);
|
||||
if ( brk->module )
|
||||
brk->module->clearBreakpoint(brk->lineNumber);
|
||||
dFree(brk->testExpression);
|
||||
delete brk;
|
||||
}
|
||||
|
|
@ -757,8 +756,8 @@ void TelnetDebugger::removeAllBreakpoints()
|
|||
while(walk)
|
||||
{
|
||||
Breakpoint *temp = walk->next;
|
||||
if ( walk->code )
|
||||
walk->code->clearBreakpoint(walk->lineNumber);
|
||||
if ( walk->module )
|
||||
walk->module->clearBreakpoint(walk->lineNumber);
|
||||
dFree(walk->testExpression);
|
||||
delete walk;
|
||||
walk = temp;
|
||||
|
|
@ -781,23 +780,24 @@ void TelnetDebugger::debugContinue()
|
|||
|
||||
void TelnetDebugger::setBreakOnNextStatement( bool enabled )
|
||||
{
|
||||
Vector<Con::Module*> modules = Con::getAllScriptModules();
|
||||
if ( enabled )
|
||||
{
|
||||
// Apply breaks on all the code blocks.
|
||||
for(CodeBlock *walk = CodeBlock::getCodeBlockList(); walk; walk = walk->nextFile)
|
||||
walk->setAllBreaks();
|
||||
for(Con::Module** walk = modules.begin(); walk != modules.end(); walk++)
|
||||
(*walk)->setAllBreaks();
|
||||
mBreakOnNextStatement = true;
|
||||
}
|
||||
else if ( !enabled )
|
||||
{
|
||||
// Clear all the breaks on the codeblocks
|
||||
// then go reapply the breakpoints.
|
||||
for(CodeBlock *walk = CodeBlock::getCodeBlockList(); walk; walk = walk->nextFile)
|
||||
walk->clearAllBreaks();
|
||||
for(Con::Module** walk = modules.begin(); walk != modules.end(); walk++)
|
||||
(*walk)->clearAllBreaks();
|
||||
for(Breakpoint *w = mBreakpoints; w; w = w->next)
|
||||
{
|
||||
if ( w->code )
|
||||
w->code->setBreakpoint(w->lineNumber);
|
||||
if ( w->module )
|
||||
w->module->setBreakpoint(w->lineNumber);
|
||||
}
|
||||
mBreakOnNextStatement = false;
|
||||
}
|
||||
|
|
@ -838,7 +838,7 @@ void TelnetDebugger::debugStepOver()
|
|||
return;
|
||||
|
||||
setBreakOnNextStatement( true );
|
||||
mStackPopBreakIndex = gEvalState.getStackDepth();
|
||||
mStackPopBreakIndex = Con::getFrameStack().size();
|
||||
mProgramPaused = false;
|
||||
send("RUNNING\r\n");
|
||||
}
|
||||
|
|
@ -849,7 +849,7 @@ void TelnetDebugger::debugStepOut()
|
|||
return;
|
||||
|
||||
setBreakOnNextStatement( false );
|
||||
mStackPopBreakIndex = gEvalState.getStackDepth() - 1;
|
||||
mStackPopBreakIndex = Con::getFrameStack().size() - 1;
|
||||
if ( mStackPopBreakIndex == 0 )
|
||||
mStackPopBreakIndex = -1;
|
||||
mProgramPaused = false;
|
||||
|
|
@ -858,84 +858,39 @@ void TelnetDebugger::debugStepOut()
|
|||
|
||||
void TelnetDebugger::evaluateExpression(const char *tag, S32 frame, const char *evalBuffer)
|
||||
{
|
||||
// Make sure we're passing a valid frame to the eval.
|
||||
if ( frame > gEvalState.getStackDepth() )
|
||||
frame = gEvalState.getStackDepth() - 1;
|
||||
if ( frame < 0 )
|
||||
frame = 0;
|
||||
// Build a buffer just big enough for this eval.
|
||||
const char* format = "return %s;";
|
||||
S32 len = dStrlen( format ) + dStrlen( evalBuffer );
|
||||
char* buffer = new char[ len ];
|
||||
dSprintf( buffer, len, format, evalBuffer );
|
||||
Con::EvalResult evalResult = Con::evaluate(buffer, frame);
|
||||
delete buffer;
|
||||
|
||||
// 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)
|
||||
if (!evalResult.valid)
|
||||
{
|
||||
// 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;
|
||||
|
||||
// ERROR, can't read the variable!
|
||||
send("EVALOUT \"\" \"\"");
|
||||
return;
|
||||
}
|
||||
|
||||
// Build a buffer just big enough for this eval.
|
||||
const char* format = "return %s;";
|
||||
dsize_t len = dStrlen( format ) + dStrlen( evalBuffer );
|
||||
char* buffer = new char[ len ];
|
||||
dSprintf( buffer, len, format, evalBuffer );
|
||||
|
||||
// Execute the eval.
|
||||
CodeBlock *newCodeBlock = new CodeBlock();
|
||||
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.getString() );
|
||||
buffer = new char[ len ];
|
||||
dSprintf( buffer, len, format, tag, result.getString()[0] ? result.getString() : "\"\"" );
|
||||
|
||||
send( buffer );
|
||||
delete newCodeBlock;
|
||||
delete [] buffer;
|
||||
len = dStrlen(format) + dStrlen(tag) + dStrlen(evalResult.value);
|
||||
buffer = new char[len];
|
||||
dSprintf(buffer, len, format, tag, evalResult.value[0] ? evalResult.value : "\"\"");
|
||||
|
||||
send(buffer);
|
||||
delete[] buffer;
|
||||
}
|
||||
|
||||
void TelnetDebugger::dumpFileList()
|
||||
{
|
||||
send("FILELISTOUT ");
|
||||
for(CodeBlock *walk = CodeBlock::getCodeBlockList(); walk; walk = walk->nextFile)
|
||||
Vector<Con::Module*> modules = Con::getAllScriptModules();
|
||||
for(Con::Module** walk = modules.begin(); walk != modules.end(); walk++)
|
||||
{
|
||||
send(walk->name);
|
||||
if(walk->nextFile)
|
||||
send((*walk)->getName());
|
||||
if((walk + 1) != modules.end())
|
||||
send(" ");
|
||||
}
|
||||
send("\r\n");
|
||||
|
|
@ -944,15 +899,15 @@ void TelnetDebugger::dumpFileList()
|
|||
void TelnetDebugger::dumpBreakableList(const char *fileName)
|
||||
{
|
||||
fileName = StringTable->insert(fileName);
|
||||
CodeBlock *file = CodeBlock::find(fileName);
|
||||
Con::Module *file = Con::findScriptModuleForFile(fileName);
|
||||
char buffer[MaxCommandSize];
|
||||
if(file)
|
||||
{
|
||||
dSprintf(buffer, MaxCommandSize, "BREAKLISTOUT %s %d", fileName, file->breakListSize >> 1);
|
||||
dSprintf(buffer, MaxCommandSize, "BREAKLISTOUT %s %d", fileName, file->getBreakableLines().size() >> 1);
|
||||
send(buffer);
|
||||
for(U32 i = 0; i < file->breakListSize; i += 2)
|
||||
for(U32 i = 0; i < file->getBreakableLines().size(); i += 2)
|
||||
{
|
||||
dSprintf(buffer, MaxCommandSize, " %d %d", file->breakList[i], file->breakList[i+1]);
|
||||
dSprintf(buffer, MaxCommandSize, " %d %d", file->getBreakableLines()[i], file->getBreakableLines()[i+1]);
|
||||
send(buffer);
|
||||
}
|
||||
send("\r\n");
|
||||
|
|
@ -962,14 +917,14 @@ void TelnetDebugger::dumpBreakableList(const char *fileName)
|
|||
}
|
||||
|
||||
|
||||
void TelnetDebugger::clearCodeBlockPointers(CodeBlock *code)
|
||||
void TelnetDebugger::clearCodeBlockPointers(Con::Module *code)
|
||||
{
|
||||
Breakpoint **walk = &mBreakpoints;
|
||||
Breakpoint *cur;
|
||||
while((cur = *walk) != NULL)
|
||||
{
|
||||
if(cur->code == code)
|
||||
cur->code = NULL;
|
||||
if(cur->module == code)
|
||||
cur->module = NULL;
|
||||
|
||||
walk = &cur->next;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,8 +26,7 @@
|
|||
#ifndef _PLATFORM_PLATFORMNET_H_
|
||||
#include "platform/platformNet.h"
|
||||
#endif
|
||||
|
||||
class CodeBlock;
|
||||
#include "module.h"
|
||||
|
||||
/// Telnet debug service implementation.
|
||||
///
|
||||
|
|
@ -75,7 +74,7 @@ class TelnetDebugger
|
|||
struct Breakpoint
|
||||
{
|
||||
StringTableEntry fileName;
|
||||
CodeBlock *code;
|
||||
Con::Module *module;
|
||||
U32 lineNumber;
|
||||
S32 passCount;
|
||||
S32 curCount;
|
||||
|
|
@ -105,7 +104,7 @@ class TelnetDebugger
|
|||
void evaluateExpression(const char *tag, S32 frame, const char *evalBuffer);
|
||||
void dumpFileList();
|
||||
void dumpBreakableList(const char *fileName);
|
||||
void removeBreakpointsFromCode(CodeBlock *code);
|
||||
void removeBreakpointsFromCode(Con::Module *code);
|
||||
|
||||
void checkDebugRecv();
|
||||
void processLineBuffer(S32);
|
||||
|
|
@ -121,13 +120,13 @@ public:
|
|||
void process();
|
||||
void popStackFrame();
|
||||
void pushStackFrame();
|
||||
void addAllBreakpoints(CodeBlock *code);
|
||||
void addAllBreakpoints(Con::Module *module);
|
||||
|
||||
void clearCodeBlockPointers(CodeBlock *code);
|
||||
void clearCodeBlockPointers(Con::Module *code);
|
||||
|
||||
void breakProcess();
|
||||
|
||||
void executionStopped(CodeBlock *code, U32 lineNumber);
|
||||
void executionStopped(Con::Module *module, U32 lineNumber);
|
||||
void send(const char *s);
|
||||
void setDebugParameters(S32 port, const char *password, bool waitForClient);
|
||||
void processConsoleLine(const char *consoleLine);
|
||||
|
|
|
|||
|
|
@ -29,6 +29,10 @@
|
|||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "compiler.h"
|
||||
#include "runtime.h"
|
||||
#include "console/script.h"
|
||||
|
||||
|
||||
/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
|
||||
#ifdef c_plusplus
|
||||
|
|
@ -551,11 +555,9 @@ char *yytext;
|
|||
#define YYLMAX 4096
|
||||
#define YY_NO_UNISTD_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include "platform/platform.h"
|
||||
#include "core/stringTable.h"
|
||||
#include "console/console.h"
|
||||
#include "console/compiler.h"
|
||||
#include "console/dynamicTypes.h"
|
||||
#include "core/strings/stringFunctions.h"
|
||||
|
||||
|
|
@ -576,10 +578,7 @@ inline Token< T > MakeToken( T value, U32 lineNumber )
|
|||
return result;
|
||||
}
|
||||
|
||||
#include "console/cmdgram.h"
|
||||
|
||||
// HACK: C++17 and beyond can't use register keyword
|
||||
#define register
|
||||
#include "cmdgram.h"
|
||||
|
||||
using namespace Compiler;
|
||||
|
||||
|
|
@ -634,7 +633,7 @@ void CMDerror(const char * s, ...);
|
|||
// Reset the parser.
|
||||
void CMDrestart(FILE *in);
|
||||
|
||||
#line 638 "CMDscan.cpp"
|
||||
#line 635 "CMDscan.cpp"
|
||||
|
||||
/* Macros after this point can all be overridden by user definitions in
|
||||
* section 1.
|
||||
|
|
@ -777,14 +776,14 @@ YY_MALLOC_DECL
|
|||
|
||||
YY_DECL
|
||||
{
|
||||
register yy_state_type yy_current_state;
|
||||
register char *yy_cp, *yy_bp;
|
||||
register int yy_act;
|
||||
yy_state_type yy_current_state;
|
||||
char *yy_cp, *yy_bp;
|
||||
int yy_act;
|
||||
|
||||
#line 108 "CMDscan.l"
|
||||
#line 105 "CMDscan.l"
|
||||
|
||||
;
|
||||
#line 788 "CMDscan.cpp"
|
||||
#line 785 "CMDscan.cpp"
|
||||
|
||||
if ( yy_init )
|
||||
{
|
||||
|
|
@ -826,7 +825,7 @@ YY_DECL
|
|||
yy_match:
|
||||
do
|
||||
{
|
||||
register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
|
||||
YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
|
||||
if ( yy_accept[yy_current_state] )
|
||||
{
|
||||
yy_last_accepting_state = yy_current_state;
|
||||
|
|
@ -869,187 +868,187 @@ do_action: /* This label is used only to access EOF actions. */
|
|||
|
||||
case 1:
|
||||
YY_RULE_SETUP
|
||||
#line 110 "CMDscan.l"
|
||||
#line 107 "CMDscan.l"
|
||||
{ }
|
||||
YY_BREAK
|
||||
case 2:
|
||||
YY_RULE_SETUP
|
||||
#line 111 "CMDscan.l"
|
||||
#line 108 "CMDscan.l"
|
||||
{ return(Sc_ScanDocBlock()); }
|
||||
YY_BREAK
|
||||
case 3:
|
||||
YY_RULE_SETUP
|
||||
#line 112 "CMDscan.l"
|
||||
#line 109 "CMDscan.l"
|
||||
;
|
||||
YY_BREAK
|
||||
case 4:
|
||||
YY_RULE_SETUP
|
||||
#line 113 "CMDscan.l"
|
||||
#line 110 "CMDscan.l"
|
||||
;
|
||||
YY_BREAK
|
||||
case 5:
|
||||
YY_RULE_SETUP
|
||||
#line 114 "CMDscan.l"
|
||||
#line 111 "CMDscan.l"
|
||||
{lineIndex++;}
|
||||
YY_BREAK
|
||||
case 6:
|
||||
YY_RULE_SETUP
|
||||
#line 115 "CMDscan.l"
|
||||
#line 112 "CMDscan.l"
|
||||
{ return(Sc_ScanString(STRATOM)); }
|
||||
YY_BREAK
|
||||
case 7:
|
||||
YY_RULE_SETUP
|
||||
#line 116 "CMDscan.l"
|
||||
#line 113 "CMDscan.l"
|
||||
{ return(Sc_ScanString(TAGATOM)); }
|
||||
YY_BREAK
|
||||
case 8:
|
||||
YY_RULE_SETUP
|
||||
#line 117 "CMDscan.l"
|
||||
#line 114 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( opEQ, lineIndex ); return opEQ; }
|
||||
YY_BREAK
|
||||
case 9:
|
||||
YY_RULE_SETUP
|
||||
#line 118 "CMDscan.l"
|
||||
#line 115 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( opNE, lineIndex ); return opNE; }
|
||||
YY_BREAK
|
||||
case 10:
|
||||
YY_RULE_SETUP
|
||||
#line 119 "CMDscan.l"
|
||||
#line 116 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( opGE, lineIndex ); return opGE; }
|
||||
YY_BREAK
|
||||
case 11:
|
||||
YY_RULE_SETUP
|
||||
#line 120 "CMDscan.l"
|
||||
#line 117 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( opLE, lineIndex ); return opLE; }
|
||||
YY_BREAK
|
||||
case 12:
|
||||
YY_RULE_SETUP
|
||||
#line 121 "CMDscan.l"
|
||||
#line 118 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( opAND, lineIndex ); return opAND; }
|
||||
YY_BREAK
|
||||
case 13:
|
||||
YY_RULE_SETUP
|
||||
#line 122 "CMDscan.l"
|
||||
#line 119 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( opOR, lineIndex ); return opOR; }
|
||||
YY_BREAK
|
||||
case 14:
|
||||
YY_RULE_SETUP
|
||||
#line 123 "CMDscan.l"
|
||||
#line 120 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( opCOLONCOLON, lineIndex ); return opCOLONCOLON; }
|
||||
YY_BREAK
|
||||
case 15:
|
||||
YY_RULE_SETUP
|
||||
#line 124 "CMDscan.l"
|
||||
#line 121 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( opMINUSMINUS, lineIndex ); return opMINUSMINUS; }
|
||||
YY_BREAK
|
||||
case 16:
|
||||
YY_RULE_SETUP
|
||||
#line 125 "CMDscan.l"
|
||||
#line 122 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( opPLUSPLUS, lineIndex ); return opPLUSPLUS; }
|
||||
YY_BREAK
|
||||
case 17:
|
||||
YY_RULE_SETUP
|
||||
#line 126 "CMDscan.l"
|
||||
#line 123 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( opSTREQ, lineIndex ); return opSTREQ; }
|
||||
YY_BREAK
|
||||
case 18:
|
||||
YY_RULE_SETUP
|
||||
#line 127 "CMDscan.l"
|
||||
#line 124 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( opSTRNE, lineIndex ); return opSTRNE; }
|
||||
YY_BREAK
|
||||
case 19:
|
||||
YY_RULE_SETUP
|
||||
#line 128 "CMDscan.l"
|
||||
#line 125 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( opSHL, lineIndex ); return opSHL; }
|
||||
YY_BREAK
|
||||
case 20:
|
||||
YY_RULE_SETUP
|
||||
#line 129 "CMDscan.l"
|
||||
#line 126 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( opSHR, lineIndex ); return opSHR; }
|
||||
YY_BREAK
|
||||
case 21:
|
||||
YY_RULE_SETUP
|
||||
#line 130 "CMDscan.l"
|
||||
#line 127 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( opPLASN, lineIndex ); return opPLASN; }
|
||||
YY_BREAK
|
||||
case 22:
|
||||
YY_RULE_SETUP
|
||||
#line 131 "CMDscan.l"
|
||||
#line 128 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( opMIASN, lineIndex ); return opMIASN; }
|
||||
YY_BREAK
|
||||
case 23:
|
||||
YY_RULE_SETUP
|
||||
#line 132 "CMDscan.l"
|
||||
#line 129 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( opMLASN, lineIndex ); return opMLASN; }
|
||||
YY_BREAK
|
||||
case 24:
|
||||
YY_RULE_SETUP
|
||||
#line 133 "CMDscan.l"
|
||||
#line 130 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( opDVASN, lineIndex ); return opDVASN; }
|
||||
YY_BREAK
|
||||
case 25:
|
||||
YY_RULE_SETUP
|
||||
#line 134 "CMDscan.l"
|
||||
#line 131 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( opMODASN, lineIndex ); return opMODASN; }
|
||||
YY_BREAK
|
||||
case 26:
|
||||
YY_RULE_SETUP
|
||||
#line 135 "CMDscan.l"
|
||||
#line 132 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( opANDASN, lineIndex ); return opANDASN; }
|
||||
YY_BREAK
|
||||
case 27:
|
||||
YY_RULE_SETUP
|
||||
#line 136 "CMDscan.l"
|
||||
#line 133 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( opXORASN, lineIndex ); return opXORASN; }
|
||||
YY_BREAK
|
||||
case 28:
|
||||
YY_RULE_SETUP
|
||||
#line 137 "CMDscan.l"
|
||||
#line 134 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( opORASN, lineIndex ); return opORASN; }
|
||||
YY_BREAK
|
||||
case 29:
|
||||
YY_RULE_SETUP
|
||||
#line 138 "CMDscan.l"
|
||||
#line 135 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( opSLASN, lineIndex ); return opSLASN; }
|
||||
YY_BREAK
|
||||
case 30:
|
||||
YY_RULE_SETUP
|
||||
#line 139 "CMDscan.l"
|
||||
#line 136 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( opSRASN, lineIndex ); return opSRASN; }
|
||||
YY_BREAK
|
||||
case 31:
|
||||
YY_RULE_SETUP
|
||||
#line 140 "CMDscan.l"
|
||||
#line 137 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( opINTNAME, lineIndex ); return opINTNAME; }
|
||||
YY_BREAK
|
||||
case 32:
|
||||
YY_RULE_SETUP
|
||||
#line 141 "CMDscan.l"
|
||||
#line 138 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( opINTNAMER, lineIndex ); return opINTNAMER; }
|
||||
YY_BREAK
|
||||
case 33:
|
||||
YY_RULE_SETUP
|
||||
#line 142 "CMDscan.l"
|
||||
#line 139 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( '\n', lineIndex ); return '@'; }
|
||||
YY_BREAK
|
||||
case 34:
|
||||
YY_RULE_SETUP
|
||||
#line 143 "CMDscan.l"
|
||||
#line 140 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( '\t', lineIndex ); return '@'; }
|
||||
YY_BREAK
|
||||
case 35:
|
||||
YY_RULE_SETUP
|
||||
#line 144 "CMDscan.l"
|
||||
#line 141 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( ' ', lineIndex ); return '@'; }
|
||||
YY_BREAK
|
||||
case 36:
|
||||
YY_RULE_SETUP
|
||||
#line 145 "CMDscan.l"
|
||||
#line 142 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( 0, lineIndex ); return '@'; }
|
||||
YY_BREAK
|
||||
case 37:
|
||||
YY_RULE_SETUP
|
||||
#line 146 "CMDscan.l"
|
||||
#line 143 "CMDscan.l"
|
||||
{ /* this comment stops syntax highlighting from getting messed up when editing the lexer in TextPad */
|
||||
int c = 0, l;
|
||||
for ( ; ; )
|
||||
|
|
@ -1075,222 +1074,222 @@ YY_RULE_SETUP
|
|||
}
|
||||
YY_BREAK
|
||||
case 38:
|
||||
#line 170 "CMDscan.l"
|
||||
#line 167 "CMDscan.l"
|
||||
case 39:
|
||||
#line 171 "CMDscan.l"
|
||||
#line 168 "CMDscan.l"
|
||||
case 40:
|
||||
#line 172 "CMDscan.l"
|
||||
#line 169 "CMDscan.l"
|
||||
case 41:
|
||||
#line 173 "CMDscan.l"
|
||||
#line 170 "CMDscan.l"
|
||||
case 42:
|
||||
#line 174 "CMDscan.l"
|
||||
#line 171 "CMDscan.l"
|
||||
case 43:
|
||||
#line 175 "CMDscan.l"
|
||||
#line 172 "CMDscan.l"
|
||||
case 44:
|
||||
#line 176 "CMDscan.l"
|
||||
#line 173 "CMDscan.l"
|
||||
case 45:
|
||||
#line 177 "CMDscan.l"
|
||||
#line 174 "CMDscan.l"
|
||||
case 46:
|
||||
#line 178 "CMDscan.l"
|
||||
#line 175 "CMDscan.l"
|
||||
case 47:
|
||||
#line 179 "CMDscan.l"
|
||||
#line 176 "CMDscan.l"
|
||||
case 48:
|
||||
#line 180 "CMDscan.l"
|
||||
#line 177 "CMDscan.l"
|
||||
case 49:
|
||||
#line 181 "CMDscan.l"
|
||||
#line 178 "CMDscan.l"
|
||||
case 50:
|
||||
#line 182 "CMDscan.l"
|
||||
#line 179 "CMDscan.l"
|
||||
case 51:
|
||||
#line 183 "CMDscan.l"
|
||||
#line 180 "CMDscan.l"
|
||||
case 52:
|
||||
#line 184 "CMDscan.l"
|
||||
#line 181 "CMDscan.l"
|
||||
case 53:
|
||||
#line 185 "CMDscan.l"
|
||||
#line 182 "CMDscan.l"
|
||||
case 54:
|
||||
#line 186 "CMDscan.l"
|
||||
#line 183 "CMDscan.l"
|
||||
case 55:
|
||||
#line 187 "CMDscan.l"
|
||||
#line 184 "CMDscan.l"
|
||||
case 56:
|
||||
#line 188 "CMDscan.l"
|
||||
#line 185 "CMDscan.l"
|
||||
case 57:
|
||||
#line 189 "CMDscan.l"
|
||||
#line 186 "CMDscan.l"
|
||||
case 58:
|
||||
#line 190 "CMDscan.l"
|
||||
#line 187 "CMDscan.l"
|
||||
case 59:
|
||||
#line 191 "CMDscan.l"
|
||||
#line 188 "CMDscan.l"
|
||||
case 60:
|
||||
#line 192 "CMDscan.l"
|
||||
#line 189 "CMDscan.l"
|
||||
case 61:
|
||||
YY_RULE_SETUP
|
||||
#line 192 "CMDscan.l"
|
||||
#line 189 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( CMDtext[ 0 ], lineIndex ); return CMDtext[ 0 ]; }
|
||||
YY_BREAK
|
||||
case 62:
|
||||
YY_RULE_SETUP
|
||||
#line 193 "CMDscan.l"
|
||||
#line 190 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( rwIN, lineIndex ); return(rwIN); }
|
||||
YY_BREAK
|
||||
case 63:
|
||||
YY_RULE_SETUP
|
||||
#line 194 "CMDscan.l"
|
||||
#line 191 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( rwCASEOR, lineIndex ); return(rwCASEOR); }
|
||||
YY_BREAK
|
||||
case 64:
|
||||
YY_RULE_SETUP
|
||||
#line 195 "CMDscan.l"
|
||||
#line 192 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( rwBREAK, lineIndex ); return(rwBREAK); }
|
||||
YY_BREAK
|
||||
case 65:
|
||||
YY_RULE_SETUP
|
||||
#line 196 "CMDscan.l"
|
||||
#line 193 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( rwRETURN, lineIndex ); return(rwRETURN); }
|
||||
YY_BREAK
|
||||
case 66:
|
||||
YY_RULE_SETUP
|
||||
#line 197 "CMDscan.l"
|
||||
#line 194 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( rwELSE, lineIndex ); return(rwELSE); }
|
||||
YY_BREAK
|
||||
case 67:
|
||||
YY_RULE_SETUP
|
||||
#line 198 "CMDscan.l"
|
||||
#line 195 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( rwASSERT, lineIndex ); return(rwASSERT); }
|
||||
YY_BREAK
|
||||
case 68:
|
||||
YY_RULE_SETUP
|
||||
#line 199 "CMDscan.l"
|
||||
#line 196 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( rwWHILE, lineIndex ); return(rwWHILE); }
|
||||
YY_BREAK
|
||||
case 69:
|
||||
YY_RULE_SETUP
|
||||
#line 200 "CMDscan.l"
|
||||
#line 197 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( rwDO, lineIndex ); return(rwDO); }
|
||||
YY_BREAK
|
||||
case 70:
|
||||
YY_RULE_SETUP
|
||||
#line 201 "CMDscan.l"
|
||||
#line 198 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( rwIF, lineIndex ); return(rwIF); }
|
||||
YY_BREAK
|
||||
case 71:
|
||||
YY_RULE_SETUP
|
||||
#line 202 "CMDscan.l"
|
||||
#line 199 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( rwFOREACHSTR, lineIndex ); return(rwFOREACHSTR); }
|
||||
YY_BREAK
|
||||
case 72:
|
||||
YY_RULE_SETUP
|
||||
#line 203 "CMDscan.l"
|
||||
#line 200 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( rwFOREACH, lineIndex ); return(rwFOREACH); }
|
||||
YY_BREAK
|
||||
case 73:
|
||||
YY_RULE_SETUP
|
||||
#line 204 "CMDscan.l"
|
||||
#line 201 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( rwFOR, lineIndex ); return(rwFOR); }
|
||||
YY_BREAK
|
||||
case 74:
|
||||
YY_RULE_SETUP
|
||||
#line 205 "CMDscan.l"
|
||||
#line 202 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( rwCONTINUE, lineIndex ); return(rwCONTINUE); }
|
||||
YY_BREAK
|
||||
case 75:
|
||||
YY_RULE_SETUP
|
||||
#line 206 "CMDscan.l"
|
||||
#line 203 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( rwDEFINE, lineIndex ); return(rwDEFINE); }
|
||||
YY_BREAK
|
||||
case 76:
|
||||
YY_RULE_SETUP
|
||||
#line 207 "CMDscan.l"
|
||||
#line 204 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( rwDECLARE, lineIndex ); return(rwDECLARE); }
|
||||
YY_BREAK
|
||||
case 77:
|
||||
YY_RULE_SETUP
|
||||
#line 208 "CMDscan.l"
|
||||
#line 205 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( rwDECLARESINGLETON, lineIndex ); return(rwDECLARESINGLETON); }
|
||||
YY_BREAK
|
||||
case 78:
|
||||
YY_RULE_SETUP
|
||||
#line 209 "CMDscan.l"
|
||||
#line 206 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( rwDATABLOCK, lineIndex ); return(rwDATABLOCK); }
|
||||
YY_BREAK
|
||||
case 79:
|
||||
YY_RULE_SETUP
|
||||
#line 210 "CMDscan.l"
|
||||
#line 207 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( rwCASE, lineIndex ); return(rwCASE); }
|
||||
YY_BREAK
|
||||
case 80:
|
||||
YY_RULE_SETUP
|
||||
#line 211 "CMDscan.l"
|
||||
#line 208 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( rwSWITCHSTR, lineIndex ); return(rwSWITCHSTR); }
|
||||
YY_BREAK
|
||||
case 81:
|
||||
YY_RULE_SETUP
|
||||
#line 212 "CMDscan.l"
|
||||
#line 209 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( rwSWITCH, lineIndex ); return(rwSWITCH); }
|
||||
YY_BREAK
|
||||
case 82:
|
||||
YY_RULE_SETUP
|
||||
#line 213 "CMDscan.l"
|
||||
#line 210 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( rwDEFAULT, lineIndex ); return(rwDEFAULT); }
|
||||
YY_BREAK
|
||||
case 83:
|
||||
YY_RULE_SETUP
|
||||
#line 214 "CMDscan.l"
|
||||
#line 211 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( rwPACKAGE, lineIndex ); return(rwPACKAGE); }
|
||||
YY_BREAK
|
||||
case 84:
|
||||
YY_RULE_SETUP
|
||||
#line 215 "CMDscan.l"
|
||||
#line 212 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( rwNAMESPACE, lineIndex ); return(rwNAMESPACE); }
|
||||
YY_BREAK
|
||||
case 85:
|
||||
YY_RULE_SETUP
|
||||
#line 216 "CMDscan.l"
|
||||
#line 213 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( 1, lineIndex ); return INTCONST; }
|
||||
YY_BREAK
|
||||
case 86:
|
||||
YY_RULE_SETUP
|
||||
#line 217 "CMDscan.l"
|
||||
#line 214 "CMDscan.l"
|
||||
{ CMDlval.i = MakeToken< int >( 0, lineIndex ); return INTCONST; }
|
||||
YY_BREAK
|
||||
case 87:
|
||||
YY_RULE_SETUP
|
||||
#line 218 "CMDscan.l"
|
||||
#line 215 "CMDscan.l"
|
||||
{ return(Sc_ScanVar()); }
|
||||
YY_BREAK
|
||||
case 88:
|
||||
YY_RULE_SETUP
|
||||
#line 220 "CMDscan.l"
|
||||
#line 216 "CMDscan.l"
|
||||
{ return Sc_ScanIdent(); }
|
||||
YY_BREAK
|
||||
case 89:
|
||||
YY_RULE_SETUP
|
||||
#line 221 "CMDscan.l"
|
||||
#line 217 "CMDscan.l"
|
||||
return(Sc_ScanHex());
|
||||
YY_BREAK
|
||||
case 90:
|
||||
YY_RULE_SETUP
|
||||
#line 222 "CMDscan.l"
|
||||
#line 218 "CMDscan.l"
|
||||
{ CMDtext[CMDleng] = 0; CMDlval.i = MakeToken< int >( dAtoi(CMDtext), lineIndex ); return INTCONST; }
|
||||
YY_BREAK
|
||||
case 91:
|
||||
YY_RULE_SETUP
|
||||
#line 223 "CMDscan.l"
|
||||
#line 219 "CMDscan.l"
|
||||
return Sc_ScanNum();
|
||||
YY_BREAK
|
||||
case 92:
|
||||
YY_RULE_SETUP
|
||||
#line 224 "CMDscan.l"
|
||||
#line 220 "CMDscan.l"
|
||||
return(ILLEGAL_TOKEN);
|
||||
YY_BREAK
|
||||
case 93:
|
||||
YY_RULE_SETUP
|
||||
#line 225 "CMDscan.l"
|
||||
#line 221 "CMDscan.l"
|
||||
return(ILLEGAL_TOKEN);
|
||||
YY_BREAK
|
||||
case 94:
|
||||
YY_RULE_SETUP
|
||||
#line 226 "CMDscan.l"
|
||||
#line 222 "CMDscan.l"
|
||||
ECHO;
|
||||
YY_BREAK
|
||||
#line 1294 "CMDscan.cpp"
|
||||
#line 1291 "CMDscan.cpp"
|
||||
case YY_STATE_EOF(INITIAL):
|
||||
yyterminate();
|
||||
|
||||
|
|
@ -1433,9 +1432,9 @@ case YY_STATE_EOF(INITIAL):
|
|||
|
||||
static int yy_get_next_buffer()
|
||||
{
|
||||
register char *dest = yy_current_buffer->yy_ch_buf;
|
||||
register char *source = yytext_ptr;
|
||||
register int number_to_move, i;
|
||||
char *dest = yy_current_buffer->yy_ch_buf;
|
||||
char *source = yytext_ptr;
|
||||
int number_to_move, i;
|
||||
int ret_val;
|
||||
|
||||
if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] )
|
||||
|
|
@ -1563,14 +1562,14 @@ static int yy_get_next_buffer()
|
|||
|
||||
static yy_state_type yy_get_previous_state()
|
||||
{
|
||||
register yy_state_type yy_current_state;
|
||||
register char *yy_cp;
|
||||
yy_state_type yy_current_state;
|
||||
char *yy_cp;
|
||||
|
||||
yy_current_state = yy_start;
|
||||
|
||||
for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp )
|
||||
{
|
||||
register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
|
||||
YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
|
||||
if ( yy_accept[yy_current_state] )
|
||||
{
|
||||
yy_last_accepting_state = yy_current_state;
|
||||
|
|
@ -1602,10 +1601,10 @@ static yy_state_type yy_try_NUL_trans( yy_current_state )
|
|||
yy_state_type yy_current_state;
|
||||
#endif
|
||||
{
|
||||
register int yy_is_jam;
|
||||
register char *yy_cp = yy_c_buf_p;
|
||||
int yy_is_jam;
|
||||
char *yy_cp = yy_c_buf_p;
|
||||
|
||||
register YY_CHAR yy_c = 1;
|
||||
YY_CHAR yy_c = 1;
|
||||
if ( yy_accept[yy_current_state] )
|
||||
{
|
||||
yy_last_accepting_state = yy_current_state;
|
||||
|
|
@ -1626,14 +1625,14 @@ yy_state_type yy_current_state;
|
|||
|
||||
#ifndef YY_NO_UNPUT
|
||||
#ifdef YY_USE_PROTOS
|
||||
static void yyunput( int c, register char *yy_bp )
|
||||
static void yyunput( int c, char *yy_bp )
|
||||
#else
|
||||
static void yyunput( c, yy_bp )
|
||||
int c;
|
||||
register char *yy_bp;
|
||||
char *yy_bp;
|
||||
#endif
|
||||
{
|
||||
register char *yy_cp = yy_c_buf_p;
|
||||
char *yy_cp = yy_c_buf_p;
|
||||
|
||||
/* undo effects of setting up yytext */
|
||||
*yy_cp = yy_hold_char;
|
||||
|
|
@ -1641,10 +1640,10 @@ register char *yy_bp;
|
|||
if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
|
||||
{ /* need to shift things up to make room */
|
||||
/* +2 for EOB chars. */
|
||||
register int number_to_move = yy_n_chars + 2;
|
||||
register char *dest = &yy_current_buffer->yy_ch_buf[
|
||||
int number_to_move = yy_n_chars + 2;
|
||||
char *dest = &yy_current_buffer->yy_ch_buf[
|
||||
yy_current_buffer->yy_buf_size + 2];
|
||||
register char *source =
|
||||
char *source =
|
||||
&yy_current_buffer->yy_ch_buf[number_to_move];
|
||||
|
||||
while ( source > yy_current_buffer->yy_ch_buf )
|
||||
|
|
@ -2098,7 +2097,7 @@ yyconst char *s2;
|
|||
int n;
|
||||
#endif
|
||||
{
|
||||
register int i;
|
||||
int i;
|
||||
for ( i = 0; i < n; ++i )
|
||||
s1[i] = s2[i];
|
||||
}
|
||||
|
|
@ -2150,7 +2149,7 @@ int main()
|
|||
return 0;
|
||||
}
|
||||
#endif
|
||||
#line 226 "CMDscan.l"
|
||||
#line 222 "CMDscan.l"
|
||||
|
||||
|
||||
static const char *scanBuffer;
|
||||
|
|
@ -2341,7 +2340,7 @@ static int Sc_ScanDocBlock()
|
|||
static int Sc_ScanString(int ret)
|
||||
{
|
||||
CMDtext[CMDleng - 1] = 0;
|
||||
if(!collapseEscape(CMDtext+1))
|
||||
if(!TorqueScript::getRuntime()->collapseEscapedCharacters(CMDtext+1))
|
||||
return -1;
|
||||
|
||||
dsize_t bufferLen = dStrlen( CMDtext );
|
||||
|
|
@ -23,8 +23,9 @@
|
|||
#ifndef _AST_H_
|
||||
#define _AST_H_
|
||||
|
||||
class ExprEvalState;
|
||||
class Namespace;
|
||||
#include "evalState.h"
|
||||
#include "platform/types.h"
|
||||
|
||||
class SimObject;
|
||||
class SimGroup;
|
||||
class CodeStream;
|
||||
|
|
@ -101,7 +102,7 @@ struct StmtNode
|
|||
#ifndef DEBUG_AST_NODES
|
||||
# define DBG_STMT_TYPE(s) virtual const char* dbgStmtType() const { return "#s"; }
|
||||
#else
|
||||
# define DBG_STMT_TYPE(s)
|
||||
# define DBG_STMT_TYPE(s)
|
||||
#endif
|
||||
|
||||
struct BreakStmtNode : StmtNode
|
||||
|
|
@ -592,7 +593,14 @@ struct FunctionDeclStmtNode : StmtNode
|
|||
DBG_STMT_TYPE(FunctionDeclStmtNode);
|
||||
};
|
||||
|
||||
extern StmtNode* gStatementList;
|
||||
extern ExprEvalState gEvalState;
|
||||
namespace Script
|
||||
{
|
||||
inline ExprEvalState gEvalState;
|
||||
|
||||
inline StmtNode *gStatementList;
|
||||
inline StmtNode *gAnonFunctionList;
|
||||
inline U32 gAnonFunctionID = 0;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -21,7 +21,7 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "console/console.h"
|
||||
#include "console/compiler.h"
|
||||
#include "compiler.h"
|
||||
#include "console/consoleInternal.h"
|
||||
|
||||
using namespace Compiler;
|
||||
|
|
@ -22,15 +22,10 @@
|
|||
|
||||
#include "platform/platform.h"
|
||||
#include "console/console.h"
|
||||
#include "console/telnetDebugger.h"
|
||||
|
||||
#include "console/ast.h"
|
||||
#include "core/tAlgorithm.h"
|
||||
#include "ast.h"
|
||||
|
||||
#include "core/strings/findMatch.h"
|
||||
#include "console/consoleInternal.h"
|
||||
#include "core/stream/fileStream.h"
|
||||
#include "console/compiler.h"
|
||||
#include "compiler.h"
|
||||
|
||||
#include "console/simBase.h"
|
||||
|
||||
|
|
@ -40,7 +35,7 @@ struct Token
|
|||
T value;
|
||||
S32 lineNumber;
|
||||
};
|
||||
#include "console/cmdgram.h"
|
||||
#include "cmdgram.h"
|
||||
|
||||
namespace Compiler
|
||||
{
|
||||
|
|
@ -95,7 +95,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "console/console.h"
|
||||
#include "console/compiler.h"
|
||||
#include "compiler.h"
|
||||
#include "console/consoleInternal.h"
|
||||
#include "core/strings/stringFunctions.h"
|
||||
|
||||
|
|
@ -1581,7 +1581,7 @@ case 2:
|
|||
break;}
|
||||
case 3:
|
||||
#line 169 "cmdgram.y"
|
||||
{ if(!gStatementList) { gStatementList = yyvsp[0].stmt; } else { gStatementList->append(yyvsp[0].stmt); } ;
|
||||
{ if(!Script::gStatementList) { Script::gStatementList = yyvsp[0].stmt; } else { Script::gStatementList->append(yyvsp[0].stmt); } ;
|
||||
break;}
|
||||
case 4:
|
||||
#line 174 "cmdgram.y"
|
||||
|
|
@ -2390,5 +2390,3 @@ yyerrhandle:
|
|||
goto yynewstate;
|
||||
}
|
||||
#line 617 "cmdgram.y"
|
||||
|
||||
|
||||
|
|
@ -1,3 +1,6 @@
|
|||
#ifndef _CMDGRAM_H_
|
||||
#define _CMDGRAM_H_
|
||||
|
||||
typedef union {
|
||||
Token< char > c;
|
||||
Token< int > i;
|
||||
|
|
@ -90,3 +93,5 @@ typedef union {
|
|||
|
||||
|
||||
extern YYSTYPE CMDlval;
|
||||
|
||||
#endif
|
||||
|
|
@ -21,10 +21,11 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "console/console.h"
|
||||
#include "console/compiler.h"
|
||||
#include "console/codeBlock.h"
|
||||
#include "compiler.h"
|
||||
#include "codeBlock.h"
|
||||
#include "ast.h"
|
||||
|
||||
#include "console/telnetDebugger.h"
|
||||
#include "console/ast.h"
|
||||
#include "core/strings/unicode.h"
|
||||
#include "core/strings/stringFunctions.h"
|
||||
#include "core/stringTable.h"
|
||||
|
|
@ -34,8 +35,7 @@ using namespace Compiler;
|
|||
|
||||
bool CodeBlock::smInFunction = false;
|
||||
CodeBlock * CodeBlock::smCodeBlockList = NULL;
|
||||
CodeBlock * CodeBlock::smCurrentCodeBlock = NULL;
|
||||
ConsoleParser *CodeBlock::smCurrentParser = NULL;
|
||||
TorqueScriptParser *CodeBlock::smCurrentParser = NULL;
|
||||
|
||||
extern FuncVars gEvalFuncVars;
|
||||
extern FuncVars gGlobalScopeFuncVars;
|
||||
|
|
@ -52,8 +52,6 @@ CodeBlock::CodeBlock()
|
|||
globalFloats = NULL;
|
||||
functionFloats = NULL;
|
||||
lineBreakPairs = NULL;
|
||||
breakList = NULL;
|
||||
breakListSize = 0;
|
||||
|
||||
refCount = 0;
|
||||
code = NULL;
|
||||
|
|
@ -68,7 +66,7 @@ CodeBlock::CodeBlock()
|
|||
CodeBlock::~CodeBlock()
|
||||
{
|
||||
// Make sure we aren't lingering in the current code block...
|
||||
AssertFatal(smCurrentCodeBlock != this, "CodeBlock::~CodeBlock - Caught lingering in smCurrentCodeBlock!");
|
||||
AssertFatal(Con::getCurrentScriptModule() != this, "CodeBlock::~CodeBlock - Caught lingering in smCurrentCodeBlock!");
|
||||
|
||||
if (name)
|
||||
removeFromCodeList();
|
||||
|
|
@ -81,35 +79,10 @@ CodeBlock::~CodeBlock()
|
|||
delete[] globalFloats;
|
||||
delete[] functionFloats;
|
||||
delete[] code;
|
||||
delete[] breakList;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
StringTableEntry CodeBlock::getCurrentCodeBlockName()
|
||||
{
|
||||
if (CodeBlock::getCurrentBlock())
|
||||
return CodeBlock::getCurrentBlock()->name;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
StringTableEntry CodeBlock::getCurrentCodeBlockFullPath()
|
||||
{
|
||||
if (CodeBlock::getCurrentBlock())
|
||||
return CodeBlock::getCurrentBlock()->fullPath;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
StringTableEntry CodeBlock::getCurrentCodeBlockModName()
|
||||
{
|
||||
if (CodeBlock::getCurrentBlock())
|
||||
return CodeBlock::getCurrentBlock()->modPath;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CodeBlock *CodeBlock::find(StringTableEntry name)
|
||||
{
|
||||
for (CodeBlock *walk = CodeBlock::getCodeBlockList(); walk; walk = walk->nextFile)
|
||||
|
|
@ -309,8 +282,7 @@ void CodeBlock::calcBreakList()
|
|||
if (seqCount)
|
||||
size++;
|
||||
|
||||
breakList = new U32[size+3]; //lineBreakPairs plus pad
|
||||
breakListSize = size;
|
||||
breakList.setSize(size+3); //lineBreakPairs plus pad
|
||||
line = -1;
|
||||
seqCount = 0;
|
||||
size = 0;
|
||||
|
|
@ -502,10 +474,10 @@ bool CodeBlock::compile(const char *codeFileName, StringTableEntry fileName, con
|
|||
|
||||
STEtoCode = compileSTEtoCode;
|
||||
|
||||
gStatementList = NULL;
|
||||
Script::gStatementList = NULL;
|
||||
|
||||
// Set up the parser.
|
||||
smCurrentParser = getParserForFile(fileName);
|
||||
smCurrentParser = new TorqueScriptParser();
|
||||
AssertISV(smCurrentParser, avar("CodeBlock::compile - no parser available for '%s'!", fileName));
|
||||
|
||||
// Now do some parsing.
|
||||
|
|
@ -536,9 +508,9 @@ bool CodeBlock::compile(const char *codeFileName, StringTableEntry fileName, con
|
|||
|
||||
CodeStream codeStream;
|
||||
U32 lastIp;
|
||||
if (gStatementList)
|
||||
if (Script::gStatementList)
|
||||
{
|
||||
lastIp = compileBlock(gStatementList, codeStream, 0) + 1;
|
||||
lastIp = compileBlock(Script::gStatementList, codeStream, 0) + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -594,7 +566,7 @@ bool CodeBlock::compile(const char *codeFileName, StringTableEntry fileName, con
|
|||
return true;
|
||||
}
|
||||
|
||||
ConsoleValue CodeBlock::compileExec(StringTableEntry fileName, const char *inString, bool noCalls, S32 setFrame)
|
||||
Con::EvalResult CodeBlock::compileExec(StringTableEntry fileName, const char *inString, bool noCalls, S32 setFrame)
|
||||
{
|
||||
AssertFatal(Con::isMainThread(), "Compiling code on a secondary thread");
|
||||
|
||||
|
|
@ -634,14 +606,14 @@ ConsoleValue CodeBlock::compileExec(StringTableEntry fileName, const char *inStr
|
|||
if (name)
|
||||
addToCodeList();
|
||||
|
||||
gStatementList = NULL;
|
||||
|
||||
Script::gStatementList = NULL;
|
||||
|
||||
// we are an eval compile if we don't have a file name associated (no exec)
|
||||
gIsEvalCompile = fileName == NULL;
|
||||
gFuncVars = gIsEvalCompile ? &gEvalFuncVars : &gGlobalScopeFuncVars;
|
||||
|
||||
// Set up the parser.
|
||||
smCurrentParser = getParserForFile(fileName);
|
||||
smCurrentParser = new TorqueScriptParser();
|
||||
AssertISV(smCurrentParser, avar("CodeBlock::compile - no parser available for '%s'!", fileName));
|
||||
|
||||
// Now do some parsing.
|
||||
|
|
@ -649,10 +621,10 @@ ConsoleValue CodeBlock::compileExec(StringTableEntry fileName, const char *inStr
|
|||
smCurrentParser->restart(NULL);
|
||||
smCurrentParser->parse();
|
||||
|
||||
if (!gStatementList)
|
||||
if (!Script::gStatementList)
|
||||
{
|
||||
delete this;
|
||||
return std::move(ConsoleValue());
|
||||
return Con::EvalResult(Con::getVariable("$ScriptError"));
|
||||
}
|
||||
|
||||
resetTables();
|
||||
|
|
@ -660,7 +632,7 @@ ConsoleValue CodeBlock::compileExec(StringTableEntry fileName, const char *inStr
|
|||
smInFunction = false;
|
||||
|
||||
CodeStream codeStream;
|
||||
U32 lastIp = compileBlock(gStatementList, codeStream, 0);
|
||||
U32 lastIp = compileBlock(Script::gStatementList, codeStream, 0);
|
||||
|
||||
lineBreakPairCount = codeStream.getNumLineBreaks();
|
||||
|
||||
|
|
@ -677,7 +649,7 @@ ConsoleValue CodeBlock::compileExec(StringTableEntry fileName, const char *inStr
|
|||
|
||||
codeStream.emit(OP_RETURN_VOID);
|
||||
codeStream.emitCodeStream(&codeSize, &code, &lineBreakPairs);
|
||||
|
||||
|
||||
S32 localRegisterCount = gIsEvalCompile ? gEvalFuncVars.count() : gGlobalScopeFuncVars.count();
|
||||
|
||||
consoleAllocReset();
|
||||
|
|
@ -701,20 +673,6 @@ ConsoleValue CodeBlock::compileExec(StringTableEntry fileName, const char *inStr
|
|||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
void CodeBlock::incRefCount()
|
||||
{
|
||||
refCount++;
|
||||
}
|
||||
|
||||
void CodeBlock::decRefCount()
|
||||
{
|
||||
refCount--;
|
||||
if (!refCount)
|
||||
delete this;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
String CodeBlock::getFunctionArgs(U32 ip)
|
||||
{
|
||||
StringBuilder str;
|
||||
|
|
@ -26,6 +26,9 @@
|
|||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "parser.h"
|
||||
#include "console/runtime.h"
|
||||
|
||||
struct CompilerLocalVariableToRegisterMappingTable
|
||||
{
|
||||
struct RemappingTable
|
||||
|
|
@ -42,8 +45,7 @@ struct CompilerLocalVariableToRegisterMappingTable
|
|||
void write(Stream& stream);
|
||||
};
|
||||
|
||||
#include "console/compiler.h"
|
||||
#include "console/consoleParser.h"
|
||||
#include "compiler.h"
|
||||
|
||||
class Stream;
|
||||
class ConsoleValue;
|
||||
|
|
@ -51,33 +53,24 @@ class ConsoleValue;
|
|||
/// Core TorqueScript code management class.
|
||||
///
|
||||
/// This class represents a block of code, usually mapped directly to a file.
|
||||
class CodeBlock
|
||||
class CodeBlock : Con::Module
|
||||
{
|
||||
private:
|
||||
static CodeBlock* smCodeBlockList;
|
||||
static CodeBlock* smCurrentCodeBlock;
|
||||
|
||||
public:
|
||||
static bool smInFunction;
|
||||
static Compiler::ConsoleParser * smCurrentParser;
|
||||
|
||||
static CodeBlock* getCurrentBlock()
|
||||
{
|
||||
return smCurrentCodeBlock;
|
||||
}
|
||||
static TorqueScriptParser * smCurrentParser;
|
||||
|
||||
static CodeBlock *getCodeBlockList()
|
||||
{
|
||||
return smCodeBlockList;
|
||||
}
|
||||
|
||||
static StringTableEntry getCurrentCodeBlockName();
|
||||
static StringTableEntry getCurrentCodeBlockFullPath();
|
||||
static StringTableEntry getCurrentCodeBlockModName();
|
||||
static CodeBlock *find(StringTableEntry);
|
||||
|
||||
CodeBlock();
|
||||
~CodeBlock();
|
||||
~CodeBlock() override;
|
||||
|
||||
StringTableEntry name;
|
||||
StringTableEntry fullPath;
|
||||
|
|
@ -100,59 +93,55 @@ public:
|
|||
U32 refCount;
|
||||
U32 lineBreakPairCount;
|
||||
U32 *lineBreakPairs;
|
||||
U32 breakListSize;
|
||||
U32 *breakList;
|
||||
Vector<U32> breakList;
|
||||
CodeBlock *nextFile;
|
||||
|
||||
void addToCodeList();
|
||||
void removeFromCodeList();
|
||||
void calcBreakList();
|
||||
void clearAllBreaks();
|
||||
void setAllBreaks();
|
||||
void clearAllBreaks() override;
|
||||
void setAllBreaks() override;
|
||||
void dumpInstructions(U32 startIp = 0, bool upToReturn = false);
|
||||
|
||||
/// Returns the first breakable line or 0 if none was found.
|
||||
/// @param lineNumber The one based line number.
|
||||
U32 findFirstBreakLine(U32 lineNumber);
|
||||
U32 findFirstBreakLine(U32 lineNumber) override;
|
||||
|
||||
void clearBreakpoint(U32 lineNumber);
|
||||
void clearBreakpoint(U32 lineNumber) override;
|
||||
|
||||
/// Set a OP_BREAK instruction on a line. If a break
|
||||
/// Set a OP_BREAK instruction on a line. If a break
|
||||
/// is not possible on that line it returns false.
|
||||
/// @param lineNumber The one based line number.
|
||||
bool setBreakpoint(U32 lineNumber);
|
||||
bool setBreakpoint(U32 lineNumber) override;
|
||||
|
||||
void findBreakLine(U32 ip, U32 &line, U32 &instruction);
|
||||
const char *getFileLine(U32 ip);
|
||||
void findBreakLine(U32 ip, U32 &line, U32 &instruction) override;
|
||||
const char *getFileLine(U32 ip) override;
|
||||
|
||||
///
|
||||
///
|
||||
String getFunctionArgs(U32 offset);
|
||||
|
||||
bool read(StringTableEntry fileName, Stream &st);
|
||||
bool compile(const char *dsoName, StringTableEntry fileName, const char *script, bool overrideNoDso = false);
|
||||
|
||||
void incRefCount();
|
||||
void decRefCount();
|
||||
|
||||
/// Compiles and executes a block of script storing the compiled code in this
|
||||
/// CodeBlock. If there is no filename breakpoints will not be generated and
|
||||
/// the CodeBlock will not be added to the linked list of loaded CodeBlocks.
|
||||
/// CodeBlock. If there is no filename breakpoints will not be generated and
|
||||
/// the CodeBlock will not be added to the linked list of loaded CodeBlocks.
|
||||
/// Note that if the script contains no executable statements the CodeBlock
|
||||
/// will delete itself on return an empty string. The return string is any
|
||||
/// will delete itself on return an empty string. The return string is any
|
||||
/// result of the code executed, if any, or an empty string.
|
||||
///
|
||||
/// @param fileName The file name, including path and extension, for the
|
||||
/// @param fileName The file name, including path and extension, for the
|
||||
/// block of code or an empty string.
|
||||
/// @param script The script code to compile and execute.
|
||||
/// @param noCalls Skips calling functions from the script.
|
||||
/// @param setFrame A zero based index of the stack frame to execute the code
|
||||
/// @param setFrame A zero based index of the stack frame to execute the code
|
||||
/// 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.
|
||||
ConsoleValue compileExec(StringTableEntry fileName, const char *script,
|
||||
Con::EvalResult compileExec(StringTableEntry fileName, const char *script,
|
||||
bool noCalls, S32 setFrame = -1);
|
||||
|
||||
/// Executes the existing code in the CodeBlock. The return string is any
|
||||
/// Executes the existing code in the CodeBlock. The return string is any
|
||||
/// result of the code executed, if any, or an empty string.
|
||||
///
|
||||
/// @param offset The instruction offset to start executing from.
|
||||
|
|
@ -162,14 +151,20 @@ public:
|
|||
/// zero to execute code outside of a function.
|
||||
/// @param argv The function parameter list.
|
||||
/// @param noCalls Skips calling functions from the script.
|
||||
/// @param setFrame A zero based index of the stack frame to execute the code
|
||||
/// @param setFrame A zero based index of the stack frame to execute the code
|
||||
/// 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.
|
||||
/// @param packageName The code package name or null.
|
||||
ConsoleValue exec(U32 offset, const char *fnName, Namespace *ns, U32 argc,
|
||||
ConsoleValue *argv, bool noCalls, StringTableEntry packageName,
|
||||
S32 setFrame = -1);
|
||||
Con::EvalResult exec(U32 offset, const char* fnName, Namespace* ns, U32 argc,
|
||||
ConsoleValue* argv, bool noCalls, StringTableEntry packageName,
|
||||
S32 setFrame = -1) override;
|
||||
|
||||
const char* getFunctionArgs(StringTableEntry functionName, U32 functionOffset) override { return getFunctionArgs(functionOffset); }
|
||||
const char* getPath() override { return fullPath; }
|
||||
const char* getName() override { return name; }
|
||||
Vector<U32> getBreakableLines() override { return breakList; }
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -23,31 +23,25 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "console/console.h"
|
||||
|
||||
#include "console/ast.h"
|
||||
#include "core/tAlgorithm.h"
|
||||
#include "ast.h"
|
||||
#include "compiler.h"
|
||||
|
||||
#include "core/strings/findMatch.h"
|
||||
#include "core/strings/stringUnit.h"
|
||||
#include "console/consoleInternal.h"
|
||||
#include "core/stream/fileStream.h"
|
||||
#include "console/compiler.h"
|
||||
|
||||
#include "console/simBase.h"
|
||||
#include "console/telnetDebugger.h"
|
||||
#include "sim/netStringTable.h"
|
||||
#include "console/ICallMethod.h"
|
||||
#include "console/stringStack.h"
|
||||
#include "util/messaging/message.h"
|
||||
#include "core/frameAllocator.h"
|
||||
|
||||
#include "console/returnBuffer.h"
|
||||
#include "console/consoleValueStack.h"
|
||||
#include "console/telnetDebugger.h"
|
||||
|
||||
#ifndef TORQUE_TGB_ONLY
|
||||
#include "materials/materialDefinition.h"
|
||||
#include "materials/materialManager.h"
|
||||
#endif
|
||||
|
||||
using namespace Compiler;
|
||||
|
|
@ -116,6 +110,13 @@ U32 _ITER = 0; ///< Stack pointer for iterStack.
|
|||
ConsoleValue stack[MaxStackSize];
|
||||
S32 _STK = 0;
|
||||
|
||||
ReturnBuffer retBuffer;
|
||||
|
||||
char *getReturnBuffer(U32 bufferSize)
|
||||
{
|
||||
return retBuffer.getBuffer(bufferSize);
|
||||
}
|
||||
|
||||
const char* tsconcat(const char* strA, const char* strB, S32& outputLen)
|
||||
{
|
||||
S32 lenA = dStrlen(strA);
|
||||
|
|
@ -150,7 +151,7 @@ namespace Con
|
|||
Namespace * walk;
|
||||
for (walk = ns; walk; walk = walk->mParent)
|
||||
size += dStrlen(walk->mName) + 4;
|
||||
char *ret = Con::getReturnBuffer(size);
|
||||
char *ret = getReturnBuffer(size);
|
||||
ret[0] = 0;
|
||||
for (walk = ns; walk; walk = walk->mParent)
|
||||
{
|
||||
|
|
@ -169,9 +170,9 @@ static void getFieldComponent(SimObject* object, StringTableEntry field, const c
|
|||
if (object && field)
|
||||
prevVal = object->getDataField(field, array);
|
||||
else if (currentLocalRegister != -1)
|
||||
prevVal = gEvalState.getLocalStringVariable(currentLocalRegister);
|
||||
else if (gEvalState.currentVariable)
|
||||
prevVal = gEvalState.getStringVariable();
|
||||
prevVal = Script::gEvalState.getLocalStringVariable(currentLocalRegister);
|
||||
else if (Script::gEvalState.currentVariable)
|
||||
prevVal = Script::gEvalState.getStringVariable();
|
||||
|
||||
// Make sure we got a value.
|
||||
if (prevVal && *prevVal)
|
||||
|
|
@ -192,7 +193,7 @@ static void getFieldComponent(SimObject* object, StringTableEntry field, const c
|
|||
StringTable->insert("a")
|
||||
};
|
||||
|
||||
// Translate xyzw and rgba into the indexed component
|
||||
// Translate xyzw and rgba into the indexed component
|
||||
// of the variable or field.
|
||||
if (subField == xyzw[0] || subField == rgba[0])
|
||||
dStrcpy(val, StringUnit::getUnit(prevVal, 0, " \t\n"), 128);
|
||||
|
|
@ -225,10 +226,10 @@ static void setFieldComponent(SimObject* object, StringTableEntry field, const c
|
|||
if (object && field)
|
||||
prevVal = object->getDataField(field, array);
|
||||
else if (currentLocalRegister != -1)
|
||||
prevVal = gEvalState.getLocalStringVariable(currentLocalRegister);
|
||||
prevVal = Script::gEvalState.getLocalStringVariable(currentLocalRegister);
|
||||
// Set the value on a variable.
|
||||
else if (gEvalState.currentVariable)
|
||||
prevVal = gEvalState.getStringVariable();
|
||||
else if (Script::gEvalState.currentVariable)
|
||||
prevVal = Script::gEvalState.getStringVariable();
|
||||
|
||||
// Ensure that the variable has a value
|
||||
if (!prevVal)
|
||||
|
|
@ -250,7 +251,7 @@ static void setFieldComponent(SimObject* object, StringTableEntry field, const c
|
|||
StringTable->insert("a")
|
||||
};
|
||||
|
||||
// Insert the value into the specified
|
||||
// Insert the value into the specified
|
||||
// component of the string.
|
||||
if (subField == xyzw[0] || subField == rgba[0])
|
||||
dStrcpy(val, StringUnit::setUnit(prevVal, 0, strValue, " \t\n"), 128);
|
||||
|
|
@ -270,9 +271,9 @@ static void setFieldComponent(SimObject* object, StringTableEntry field, const c
|
|||
if (object && field)
|
||||
object->setDataField(field, 0, val);
|
||||
else if (currentLocalRegister != -1)
|
||||
gEvalState.setLocalStringVariable(currentLocalRegister, val, dStrlen(val));
|
||||
else if (gEvalState.currentVariable)
|
||||
gEvalState.setStringVariable(val);
|
||||
Script::gEvalState.setLocalStringVariable(currentLocalRegister, val, dStrlen(val));
|
||||
else if (Script::gEvalState.currentVariable)
|
||||
Script::gEvalState.setStringVariable(val);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -295,83 +296,26 @@ F64 consoleStringToNumber(const char *str, StringTableEntry file, U32 line)
|
|||
return 0;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
||||
namespace Con
|
||||
SimObject* getThisObject(ConsoleValue& simObjectLookupValue)
|
||||
{
|
||||
ReturnBuffer retBuffer;
|
||||
SimObject* thisObject = NULL;
|
||||
|
||||
char *getReturnBuffer(U32 bufferSize)
|
||||
// Optimization: If we're an integer, we can lookup the value by SimObjectId
|
||||
if (simObjectLookupValue.getType() == ConsoleValueType::cvInteger)
|
||||
thisObject = Sim::findObject(static_cast<SimObjectId>(simObjectLookupValue.getFastInt()));
|
||||
else
|
||||
{
|
||||
return retBuffer.getBuffer(bufferSize);
|
||||
SimObject *foundObject = Sim::findObject(simObjectLookupValue.getString());
|
||||
|
||||
// Optimization: If we're not an integer, let's make it so that the fast path exists
|
||||
// on the first argument of the method call (speeds up future usage of %this, for example)
|
||||
if (foundObject != NULL)
|
||||
simObjectLookupValue.setInt(static_cast<S64>(foundObject->getId()));
|
||||
|
||||
thisObject = foundObject;
|
||||
}
|
||||
|
||||
char *getReturnBuffer(const char *stringToCopy)
|
||||
{
|
||||
U32 len = dStrlen(stringToCopy) + 1;
|
||||
char *ret = retBuffer.getBuffer(len);
|
||||
dMemcpy(ret, stringToCopy, len);
|
||||
return ret;
|
||||
}
|
||||
|
||||
char* getReturnBuffer(const String& str)
|
||||
{
|
||||
const U32 size = str.size();
|
||||
char* ret = retBuffer.getBuffer(size);
|
||||
dMemcpy(ret, str.c_str(), size);
|
||||
return ret;
|
||||
}
|
||||
|
||||
char* getReturnBuffer(const StringBuilder& str)
|
||||
{
|
||||
char* buffer = Con::getReturnBuffer(str.length() + 1);
|
||||
str.copy(buffer);
|
||||
buffer[str.length()] = '\0';
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
char *getArgBuffer(U32 bufferSize)
|
||||
{
|
||||
return STR.getArgBuffer(bufferSize);
|
||||
}
|
||||
|
||||
char *getFloatArg(F64 arg)
|
||||
{
|
||||
char *ret = STR.getArgBuffer(32);
|
||||
dSprintf(ret, 32, "%g", arg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *getIntArg(S32 arg)
|
||||
{
|
||||
char *ret = STR.getArgBuffer(32);
|
||||
dSprintf(ret, 32, "%d", arg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
char* getBoolArg(bool arg)
|
||||
{
|
||||
char *ret = STR.getArgBuffer(32);
|
||||
dSprintf(ret, 32, "%d", arg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *getStringArg(const char *arg)
|
||||
{
|
||||
U32 len = dStrlen(arg) + 1;
|
||||
char *ret = STR.getArgBuffer(len);
|
||||
dMemcpy(ret, arg, len);
|
||||
return ret;
|
||||
}
|
||||
|
||||
char* getStringArg(const String& arg)
|
||||
{
|
||||
const U32 size = arg.size();
|
||||
char* ret = STR.getArgBuffer(size);
|
||||
dMemcpy(ret, arg.c_str(), size);
|
||||
return ret;
|
||||
}
|
||||
return thisObject;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
|
@ -379,7 +323,7 @@ namespace Con
|
|||
void ExprEvalState::setCurVarName(StringTableEntry name)
|
||||
{
|
||||
if (name[0] == '$')
|
||||
currentVariable = globalVars.lookup(name);
|
||||
currentVariable = Con::gGlobalVars.lookup(name);
|
||||
else if (getStackDepth() > 0)
|
||||
currentVariable = getCurrentFrame().lookup(name);
|
||||
if (!currentVariable && gWarnUndefinedScriptVariables)
|
||||
|
|
@ -389,7 +333,7 @@ void ExprEvalState::setCurVarName(StringTableEntry name)
|
|||
void ExprEvalState::setCurVarNameCreate(StringTableEntry name)
|
||||
{
|
||||
if (name[0] == '$')
|
||||
currentVariable = globalVars.add(name);
|
||||
currentVariable = Con::gGlobalVars.add(name);
|
||||
else if (getStackDepth() > 0)
|
||||
currentVariable = getCurrentFrame().add(name);
|
||||
else
|
||||
|
|
@ -605,7 +549,7 @@ TORQUE_FORCEINLINE void doIntOperation()
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
U32 gExecCount = 0;
|
||||
ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNamespace, U32 argc, ConsoleValue* argv, bool noCalls, StringTableEntry packageName, S32 setFrame)
|
||||
Con::EvalResult CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNamespace, U32 argc, ConsoleValue* argv, bool noCalls, StringTableEntry packageName, S32 setFrame)
|
||||
{
|
||||
#ifdef TORQUE_DEBUG
|
||||
U32 stackStart = _STK;
|
||||
|
|
@ -633,7 +577,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
|
|||
U32 regCount = code[ip + 2 + 7];
|
||||
thisFunctionName = CodeToSTE(code, ip);
|
||||
S32 wantedArgc = getMin(argc - 1, fnArgc); // argv[0] is func name
|
||||
if (gEvalState.traceOn)
|
||||
if (Con::gTraceOn)
|
||||
{
|
||||
traceBuffer[0] = 0;
|
||||
dStrcat(traceBuffer, "Entering ", TRACE_BUFFER_SIZE);
|
||||
|
|
@ -662,13 +606,13 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
|
|||
dStrcat(traceBuffer, ")", TRACE_BUFFER_SIZE);
|
||||
Con::printf("%s", traceBuffer);
|
||||
}
|
||||
gEvalState.pushFrame(thisFunctionName, thisNamespace, regCount);
|
||||
Script::gEvalState.pushFrame(thisFunctionName, thisNamespace, regCount);
|
||||
popFrame = true;
|
||||
for (i = 0; i < wantedArgc; i++)
|
||||
{
|
||||
S32 reg = code[ip + (2 + 6 + 1 + 1) + i];
|
||||
ConsoleValue& value = argv[i + 1];
|
||||
gEvalState.moveConsoleValue(reg, std::move(value));
|
||||
Script::gEvalState.moveConsoleValue(reg, std::move(value));
|
||||
}
|
||||
ip = ip + fnArgc + (2 + 6 + 1 + 1);
|
||||
curFloatTable = functionFloats;
|
||||
|
|
@ -684,7 +628,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
|
|||
// If requested stack frame isn't available, request a new one
|
||||
// (this prevents assert failures when creating local
|
||||
// variables without a stack frame)
|
||||
if (gEvalState.getStackDepth() <= setFrame)
|
||||
if (Script::gEvalState.getStackDepth() <= setFrame)
|
||||
setFrame = -1;
|
||||
|
||||
// Do we want this code to execute using a new stack frame?
|
||||
|
|
@ -692,8 +636,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
|
|||
if (setFrame <= 0)
|
||||
{
|
||||
// argc is the local count for eval
|
||||
gEvalState.pushFrame(NULL, NULL, argc);
|
||||
popFrame = true;
|
||||
Script::gEvalState.pushFrame(NULL, NULL, argc);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -701,12 +644,16 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
|
|||
// on to the top of the stack. Any change that occurs to
|
||||
// the locals during this new frame will also occur in the
|
||||
// original frame.
|
||||
S32 stackIndex = gEvalState.getTopOfStack() - setFrame - 1;
|
||||
gEvalState.pushFrameRef(stackIndex);
|
||||
popFrame = true;
|
||||
S32 stackIndex = Script::gEvalState.getTopOfStack() - setFrame - 1;
|
||||
Script::gEvalState.pushFrameRef(stackIndex);
|
||||
}
|
||||
|
||||
popFrame = true;
|
||||
}
|
||||
|
||||
Script::gEvalState.getCurrentFrame().module = this;
|
||||
Script::gEvalState.getCurrentFrame().ip = ip;
|
||||
|
||||
// Grab the state of the telenet debugger here once
|
||||
// so that the push and pop frames are always balanced.
|
||||
const bool telDebuggerOn = TelDebugger && TelDebugger->isConnected();
|
||||
|
|
@ -730,7 +677,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
|
|||
StringTableEntry curField = NULL;
|
||||
SimObject* prevObject = NULL;
|
||||
SimObject* curObject = NULL;
|
||||
SimObject* saveObject = NULL;
|
||||
SimObject* thisObject = NULL;
|
||||
Namespace::Entry* nsEntry;
|
||||
Namespace* ns = NULL;
|
||||
const char* curFNDocBlock = NULL;
|
||||
|
|
@ -744,8 +691,6 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
|
|||
static char curFieldArray[256];
|
||||
static char prevFieldArray[256];
|
||||
|
||||
CodeBlock* saveCodeBlock = smCurrentCodeBlock;
|
||||
smCurrentCodeBlock = this;
|
||||
if (this->name)
|
||||
{
|
||||
Con::gCurrentFile = this->name;
|
||||
|
|
@ -1402,7 +1347,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
|
|||
case OP_INC:
|
||||
reg = code[ip++];
|
||||
currentRegister = reg;
|
||||
gEvalState.setLocalFloatVariable(reg, gEvalState.getLocalFloatVariable(reg) + 1.0);
|
||||
Script::gEvalState.setLocalFloatVariable(reg, Script::gEvalState.getLocalFloatVariable(reg) + 1.0);
|
||||
break;
|
||||
|
||||
case OP_SETCURVAR:
|
||||
|
|
@ -1420,7 +1365,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
|
|||
// set a global, we aren't active
|
||||
currentRegister = -1;
|
||||
|
||||
gEvalState.setCurVarName(var);
|
||||
Script::gEvalState.setCurVarName(var);
|
||||
|
||||
// In order to let docblocks work properly with variables, we have
|
||||
// clear the current docblock when we do an assign. This way it
|
||||
|
|
@ -1442,7 +1387,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
|
|||
// set a global, we aren't active
|
||||
currentRegister = -1;
|
||||
|
||||
gEvalState.setCurVarNameCreate(var);
|
||||
Script::gEvalState.setCurVarNameCreate(var);
|
||||
|
||||
// See OP_SETCURVAR for why we do this.
|
||||
curFNDocBlock = NULL;
|
||||
|
|
@ -1461,7 +1406,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
|
|||
// set a global, we aren't active
|
||||
currentRegister = -1;
|
||||
|
||||
gEvalState.setCurVarName(var);
|
||||
Script::gEvalState.setCurVarName(var);
|
||||
|
||||
// See OP_SETCURVAR for why we do this.
|
||||
curFNDocBlock = NULL;
|
||||
|
|
@ -1480,7 +1425,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
|
|||
// set a global, we aren't active
|
||||
currentRegister = -1;
|
||||
|
||||
gEvalState.setCurVarNameCreate(var);
|
||||
Script::gEvalState.setCurVarNameCreate(var);
|
||||
|
||||
// See OP_SETCURVAR for why we do this.
|
||||
curFNDocBlock = NULL;
|
||||
|
|
@ -1489,32 +1434,32 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
|
|||
|
||||
case OP_LOADVAR_UINT:
|
||||
currentRegister = -1;
|
||||
stack[_STK + 1].setInt(gEvalState.getIntVariable());
|
||||
stack[_STK + 1].setInt(Script::gEvalState.getIntVariable());
|
||||
_STK++;
|
||||
break;
|
||||
|
||||
case OP_LOADVAR_FLT:
|
||||
currentRegister = -1;
|
||||
stack[_STK + 1].setFloat(gEvalState.getFloatVariable());
|
||||
stack[_STK + 1].setFloat(Script::gEvalState.getFloatVariable());
|
||||
_STK++;
|
||||
break;
|
||||
|
||||
case OP_LOADVAR_STR:
|
||||
currentRegister = -1;
|
||||
stack[_STK + 1].setString(gEvalState.getStringVariable());
|
||||
stack[_STK + 1].setString(Script::gEvalState.getStringVariable());
|
||||
_STK++;
|
||||
break;
|
||||
|
||||
case OP_SAVEVAR_UINT:
|
||||
gEvalState.setIntVariable(stack[_STK].getInt());
|
||||
Script::gEvalState.setIntVariable(stack[_STK].getInt());
|
||||
break;
|
||||
|
||||
case OP_SAVEVAR_FLT:
|
||||
gEvalState.setFloatVariable(stack[_STK].getFloat());
|
||||
Script::gEvalState.setFloatVariable(stack[_STK].getFloat());
|
||||
break;
|
||||
|
||||
case OP_SAVEVAR_STR:
|
||||
gEvalState.setStringVariable(stack[_STK].getString());
|
||||
Script::gEvalState.setStringVariable(stack[_STK].getString());
|
||||
break;
|
||||
|
||||
case OP_LOAD_LOCAL_VAR_UINT:
|
||||
|
|
@ -1526,7 +1471,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
|
|||
prevObject = NULL;
|
||||
curObject = NULL;
|
||||
|
||||
stack[_STK + 1].setInt(gEvalState.getLocalIntVariable(reg));
|
||||
stack[_STK + 1].setInt(Script::gEvalState.getLocalIntVariable(reg));
|
||||
_STK++;
|
||||
break;
|
||||
|
||||
|
|
@ -1539,7 +1484,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
|
|||
prevObject = NULL;
|
||||
curObject = NULL;
|
||||
|
||||
stack[_STK + 1].setFloat(gEvalState.getLocalFloatVariable(reg));
|
||||
stack[_STK + 1].setFloat(Script::gEvalState.getLocalFloatVariable(reg));
|
||||
_STK++;
|
||||
break;
|
||||
|
||||
|
|
@ -1552,7 +1497,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
|
|||
prevObject = NULL;
|
||||
curObject = NULL;
|
||||
|
||||
val = gEvalState.getLocalStringVariable(reg);
|
||||
val = Script::gEvalState.getLocalStringVariable(reg);
|
||||
stack[_STK + 1].setString(val);
|
||||
_STK++;
|
||||
break;
|
||||
|
|
@ -1566,7 +1511,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
|
|||
prevObject = NULL;
|
||||
curObject = NULL;
|
||||
|
||||
gEvalState.setLocalIntVariable(reg, stack[_STK].getInt());
|
||||
Script::gEvalState.setLocalIntVariable(reg, stack[_STK].getInt());
|
||||
break;
|
||||
|
||||
case OP_SAVE_LOCAL_VAR_FLT:
|
||||
|
|
@ -1578,7 +1523,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
|
|||
prevObject = NULL;
|
||||
curObject = NULL;
|
||||
|
||||
gEvalState.setLocalFloatVariable(reg, stack[_STK].getFloat());
|
||||
Script::gEvalState.setLocalFloatVariable(reg, stack[_STK].getFloat());
|
||||
break;
|
||||
|
||||
case OP_SAVE_LOCAL_VAR_STR:
|
||||
|
|
@ -1591,7 +1536,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
|
|||
prevObject = NULL;
|
||||
curObject = NULL;
|
||||
|
||||
gEvalState.setLocalStringVariable(reg, val, (S32)dStrlen(val));
|
||||
Script::gEvalState.setLocalStringVariable(reg, val, (S32)dStrlen(val));
|
||||
break;
|
||||
|
||||
case OP_SETCUROBJECT:
|
||||
|
|
@ -1820,10 +1765,10 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
|
|||
U32 callType = code[ip + 4];
|
||||
|
||||
//if this is called from inside a function, append the ip and codeptr
|
||||
if (!gEvalState.stack.empty())
|
||||
if (!Script::gEvalState.stack.empty())
|
||||
{
|
||||
gEvalState.getCurrentFrame().code = this;
|
||||
gEvalState.getCurrentFrame().ip = ip - 1;
|
||||
Script::gEvalState.getCurrentFrame().module = this;
|
||||
Script::gEvalState.getCurrentFrame().ip = ip - 1;
|
||||
}
|
||||
|
||||
ip += 5;
|
||||
|
|
@ -1868,25 +1813,10 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
|
|||
}
|
||||
else if (callType == FuncCallExprNode::MethodCall)
|
||||
{
|
||||
saveObject = gEvalState.thisObject;
|
||||
ConsoleValue& simObjectLookupValue = callArgv[1];
|
||||
thisObject = getThisObject(simObjectLookupValue);
|
||||
|
||||
// Optimization: If we're an integer, we can lookup the value by SimObjectId
|
||||
const ConsoleValue& simObjectLookupValue = callArgv[1];
|
||||
if (simObjectLookupValue.getType() == ConsoleValueType::cvInteger)
|
||||
gEvalState.thisObject = Sim::findObject(static_cast<SimObjectId>(simObjectLookupValue.getFastInt()));
|
||||
else
|
||||
{
|
||||
SimObject *foundObject = Sim::findObject(simObjectLookupValue.getString());
|
||||
|
||||
// Optimization: If we're not an integer, let's make it so that the fast path exists
|
||||
// on the first argument of the method call (speeds up future usage of %this, for example)
|
||||
if (foundObject != NULL)
|
||||
callArgv[1].setInt(static_cast<S64>(foundObject->getId()));
|
||||
|
||||
gEvalState.thisObject = foundObject;
|
||||
}
|
||||
|
||||
if (gEvalState.thisObject == NULL)
|
||||
if (thisObject == NULL)
|
||||
{
|
||||
Con::warnf(
|
||||
ConsoleLogEntry::General,
|
||||
|
|
@ -1902,7 +1832,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
|
|||
break;
|
||||
}
|
||||
|
||||
ns = gEvalState.thisObject->getNamespace();
|
||||
ns = thisObject->getNamespace();
|
||||
if (ns)
|
||||
nsEntry = ns->lookup(fnName);
|
||||
else
|
||||
|
|
@ -1910,6 +1840,25 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
|
|||
}
|
||||
else // it's a ParentCall
|
||||
{
|
||||
ConsoleValue& simObjectLookupValue = callArgv[1];
|
||||
thisObject = getThisObject(simObjectLookupValue);
|
||||
|
||||
if (thisObject == NULL)
|
||||
{
|
||||
Con::warnf(
|
||||
ConsoleLogEntry::General,
|
||||
"%s: Unable to find object: '%s' attempting to call function '%s'",
|
||||
getFileLine(ip - 6),
|
||||
simObjectLookupValue.getString(),
|
||||
fnName
|
||||
);
|
||||
|
||||
gCallStack.popFrame();
|
||||
stack[_STK + 1].setEmptyString();
|
||||
_STK++;
|
||||
break;
|
||||
}
|
||||
|
||||
if (thisNamespace)
|
||||
{
|
||||
ns = thisNamespace->mParent;
|
||||
|
|
@ -1933,8 +1882,8 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
|
|||
if (callType == FuncCallExprNode::MethodCall)
|
||||
{
|
||||
Con::warnf(ConsoleLogEntry::General, " Object %s(%d) %s",
|
||||
gEvalState.thisObject->getName() ? gEvalState.thisObject->getName() : "",
|
||||
gEvalState.thisObject->getId(), Con::getNamespaceList(ns));
|
||||
thisObject->getName() ? thisObject->getName() : "",
|
||||
thisObject->getId(), Con::getNamespaceList(ns));
|
||||
}
|
||||
}
|
||||
gCallStack.popFrame();
|
||||
|
|
@ -1946,7 +1895,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
|
|||
{
|
||||
if (nsEntry->mFunctionOffset)
|
||||
{
|
||||
ConsoleValue returnFromFn = nsEntry->mCode->exec(nsEntry->mFunctionOffset, fnName, nsEntry->mNamespace, callArgc, callArgv, false, nsEntry->mPackage);
|
||||
ConsoleValue returnFromFn = nsEntry->mModule->exec(nsEntry->mFunctionOffset, fnName, nsEntry->mNamespace, callArgc, callArgv, false, nsEntry->mPackage).value;
|
||||
stack[_STK + 1] = std::move(returnFromFn);
|
||||
}
|
||||
else // no body
|
||||
|
|
@ -1972,7 +1921,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
|
|||
{
|
||||
case Namespace::Entry::StringCallbackType:
|
||||
{
|
||||
const char* result = nsEntry->cb.mStringCallbackFunc(gEvalState.thisObject, callArgc, callArgv);
|
||||
const char* result = nsEntry->cb.mStringCallbackFunc(thisObject, callArgc, callArgv);
|
||||
gCallStack.popFrame();
|
||||
stack[_STK + 1].setString(result);
|
||||
_STK++;
|
||||
|
|
@ -1980,7 +1929,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
|
|||
}
|
||||
case Namespace::Entry::IntCallbackType:
|
||||
{
|
||||
S64 result = nsEntry->cb.mIntCallbackFunc(gEvalState.thisObject, callArgc, callArgv);
|
||||
S64 result = nsEntry->cb.mIntCallbackFunc(thisObject, callArgc, callArgv);
|
||||
gCallStack.popFrame();
|
||||
|
||||
if (code[ip] == OP_POP_STK)
|
||||
|
|
@ -1995,7 +1944,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
|
|||
}
|
||||
case Namespace::Entry::FloatCallbackType:
|
||||
{
|
||||
F64 result = nsEntry->cb.mFloatCallbackFunc(gEvalState.thisObject, callArgc, callArgv);
|
||||
F64 result = nsEntry->cb.mFloatCallbackFunc(thisObject, callArgc, callArgv);
|
||||
gCallStack.popFrame();
|
||||
|
||||
if (code[ip] == OP_POP_STK)
|
||||
|
|
@ -2010,7 +1959,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
|
|||
}
|
||||
case Namespace::Entry::VoidCallbackType:
|
||||
{
|
||||
nsEntry->cb.mVoidCallbackFunc(gEvalState.thisObject, callArgc, callArgv);
|
||||
nsEntry->cb.mVoidCallbackFunc(thisObject, callArgc, callArgv);
|
||||
gCallStack.popFrame();
|
||||
|
||||
if (code[ip] == OP_POP_STK)
|
||||
|
|
@ -2023,7 +1972,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
|
|||
{
|
||||
Con::warnf(ConsoleLogEntry::General, "%s: Call to %s in %s uses result of void function call.", getFileLine(ip - 4), fnName, functionName);
|
||||
}
|
||||
|
||||
|
||||
stack[_STK + 1].setEmptyString();
|
||||
_STK++;
|
||||
|
||||
|
|
@ -2031,7 +1980,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
|
|||
}
|
||||
case Namespace::Entry::BoolCallbackType:
|
||||
{
|
||||
bool result = nsEntry->cb.mBoolCallbackFunc(gEvalState.thisObject, callArgc, callArgv);
|
||||
bool result = nsEntry->cb.mBoolCallbackFunc(thisObject, callArgc, callArgv);
|
||||
gCallStack.popFrame();
|
||||
|
||||
if (code[ip] == OP_POP_STK)
|
||||
|
|
@ -2048,9 +1997,6 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (callType == FuncCallExprNode::MethodCall)
|
||||
gEvalState.thisObject = saveObject;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -2122,9 +2068,9 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
|
|||
case OP_BREAK:
|
||||
{
|
||||
//append the ip and codeptr before managing the breakpoint!
|
||||
AssertFatal(!gEvalState.stack.empty(), "Empty eval stack on break!");
|
||||
gEvalState.getCurrentFrame().code = this;
|
||||
gEvalState.getCurrentFrame().ip = ip - 1;
|
||||
AssertFatal(!Script::gEvalState.stack.empty(), "Empty eval stack on break!");
|
||||
Script::gEvalState.getCurrentFrame().module = this;
|
||||
Script::gEvalState.getCurrentFrame().ip = ip - 1;
|
||||
|
||||
U32 breakLine;
|
||||
findBreakLine(ip - 1, breakLine, instruction);
|
||||
|
|
@ -2153,7 +2099,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
|
|||
if (isGlobal)
|
||||
{
|
||||
StringTableEntry varName = CodeToSTE(code, ip + 1);
|
||||
iter.mVar.mVariable = gEvalState.globalVars.add(varName);
|
||||
iter.mVar.mVariable = Con::gGlobalVars.add(varName);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -2227,7 +2173,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
|
|||
if (iter.mIsGlobalVariable)
|
||||
iter.mVar.mVariable->setStringValue(&str[startIndex]);
|
||||
else
|
||||
gEvalState.setLocalStringVariable(iter.mVar.mRegister, &str[startIndex], endIndex - startIndex);
|
||||
Script::gEvalState.setLocalStringVariable(iter.mVar.mRegister, &str[startIndex], endIndex - startIndex);
|
||||
|
||||
const_cast<char*>(str)[endIndex] = savedChar;
|
||||
}
|
||||
|
|
@ -2236,7 +2182,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
|
|||
if (iter.mIsGlobalVariable)
|
||||
iter.mVar.mVariable->setStringValue("");
|
||||
else
|
||||
gEvalState.setLocalStringVariable(iter.mVar.mRegister, "", 0);
|
||||
Script::gEvalState.setLocalStringVariable(iter.mVar.mRegister, "", 0);
|
||||
}
|
||||
|
||||
// Skip separator.
|
||||
|
|
@ -2261,7 +2207,7 @@ ConsoleValue CodeBlock::exec(U32 ip, const char* functionName, Namespace* thisNa
|
|||
if (iter.mIsGlobalVariable)
|
||||
iter.mVar.mVariable->setIntValue(id);
|
||||
else
|
||||
gEvalState.setLocalIntVariable(iter.mVar.mRegister, id);
|
||||
Script::gEvalState.setLocalIntVariable(iter.mVar.mRegister, id);
|
||||
|
||||
iter.mData.mObj.mIndex = index + 1;
|
||||
}
|
||||
|
|
@ -2296,12 +2242,12 @@ execFinished:
|
|||
|
||||
if (popFrame)
|
||||
{
|
||||
gEvalState.popFrame();
|
||||
Script::gEvalState.popFrame();
|
||||
}
|
||||
|
||||
if (argv)
|
||||
{
|
||||
if (gEvalState.traceOn)
|
||||
if (Con::gTraceOn)
|
||||
{
|
||||
traceBuffer[0] = 0;
|
||||
dStrcat(traceBuffer, "Leaving ", TRACE_BUFFER_SIZE);
|
||||
|
|
@ -2332,11 +2278,11 @@ execFinished:
|
|||
globalStrings = NULL;
|
||||
globalFloats = NULL;
|
||||
}
|
||||
smCurrentCodeBlock = saveCodeBlock;
|
||||
if (saveCodeBlock && saveCodeBlock->name)
|
||||
|
||||
if (Con::getCurrentScriptModuleName())
|
||||
{
|
||||
Con::gCurrentFile = saveCodeBlock->name;
|
||||
Con::gCurrentRoot = saveCodeBlock->modPath;
|
||||
Con::gCurrentFile = Con::getCurrentScriptModuleName();
|
||||
Con::gCurrentRoot = Con::getModNameFromPath(Con::getCurrentScriptModulePath());
|
||||
}
|
||||
|
||||
decRefCount();
|
||||
|
|
@ -2346,7 +2292,7 @@ execFinished:
|
|||
AssertFatal(!(_STK < stackStart), "String stack popped too much in script exec");
|
||||
#endif
|
||||
|
||||
return returnValue;
|
||||
return Con::EvalResult(std::move(returnValue));
|
||||
}
|
||||
|
||||
//------------------------------------------------------------
|
||||
|
|
@ -22,16 +22,8 @@
|
|||
|
||||
#include "platform/platform.h"
|
||||
#include "console/console.h"
|
||||
#include "console/telnetDebugger.h"
|
||||
|
||||
#include "console/ast.h"
|
||||
#include "core/tAlgorithm.h"
|
||||
|
||||
#include "core/strings/findMatch.h"
|
||||
#include "console/consoleInternal.h"
|
||||
#include "core/stream/fileStream.h"
|
||||
#include "console/compiler.h"
|
||||
|
||||
#include "compiler.h"
|
||||
#include "console/simBase.h"
|
||||
|
||||
extern FuncVars gEvalFuncVars;
|
||||
|
|
@ -178,15 +170,15 @@ S32 FuncVars::assign(StringTableEntry var, TypeReq currentType, S32 lineNumber,
|
|||
S32 FuncVars::lookup(StringTableEntry var, S32 lineNumber)
|
||||
{
|
||||
std::unordered_map<StringTableEntry, Var>::iterator found = vars.find(var);
|
||||
|
||||
|
||||
if (found == vars.end())
|
||||
{
|
||||
const char* str = avar("Script Warning: Variable %s referenced before used when compiling script. File: %s Line: %d", var, CodeBlock::smCurrentParser->getCurrentFile(), lineNumber);
|
||||
scriptErrorHandler(str);
|
||||
|
||||
|
||||
return assign(var, TypeReqString, lineNumber, false);
|
||||
}
|
||||
|
||||
|
||||
return found->second.reg;
|
||||
}
|
||||
|
||||
|
|
@ -198,11 +190,11 @@ TypeReq FuncVars::lookupType(StringTableEntry var, S32 lineNumber)
|
|||
{
|
||||
const char* str = avar("Script Warning: Variable %s referenced before used when compiling script. File: %s Line: %d", var, CodeBlock::smCurrentParser->getCurrentFile(), lineNumber);
|
||||
scriptErrorHandler(str);
|
||||
|
||||
|
||||
assign(var, TypeReqString, lineNumber, false);
|
||||
return vars.find(var)->second.currentType;
|
||||
}
|
||||
|
||||
|
||||
return found->second.currentType;
|
||||
}
|
||||
|
||||
|
|
@ -561,4 +553,3 @@ void CodeStream::reset()
|
|||
mCodeHead = mCode;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -33,12 +33,14 @@
|
|||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
class CodeStream;
|
||||
struct StmtNode;
|
||||
class Stream;
|
||||
class DataChunker;
|
||||
|
||||
#include "platform/platform.h"
|
||||
#include "console/ast.h"
|
||||
#include "console/codeBlock.h"
|
||||
#include "ast.h"
|
||||
#include "codeBlock.h"
|
||||
|
||||
#ifndef _TVECTOR_H_
|
||||
#include "core/util/tVector.h"
|
||||
|
|
@ -297,13 +299,13 @@ public:
|
|||
S32 lookup(StringTableEntry var, S32 lineNumber);
|
||||
|
||||
TypeReq lookupType(StringTableEntry var, S32 lineNumber);
|
||||
|
||||
|
||||
inline S32 count() { return counter; }
|
||||
|
||||
std::unordered_map<S32, StringTableEntry> variableNameMap;
|
||||
|
||||
void clear();
|
||||
|
||||
|
||||
private:
|
||||
std::unordered_map<StringTableEntry, Var> vars;
|
||||
S32 counter = 0;
|
||||
157
Engine/source/console/torquescript/evalState.cpp
Normal file
157
Engine/source/console/torquescript/evalState.cpp
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
|
||||
#include "evalState.h"
|
||||
|
||||
void ExprEvalState::pushFrame(StringTableEntry frameName, Namespace *ns, S32 registerCount)
|
||||
{
|
||||
#ifdef DEBUG_SPEW
|
||||
validate();
|
||||
|
||||
Platform::outputDebugString("[ConsoleInternal] Pushing new frame for '%s' at %i",
|
||||
frameName, mStackDepth);
|
||||
#endif
|
||||
|
||||
if (mStackDepth + 1 > stack.size())
|
||||
{
|
||||
#ifdef DEBUG_SPEW
|
||||
Platform::outputDebugString("[ConsoleInternal] Growing stack by one frame");
|
||||
#endif
|
||||
|
||||
stack.push_back(new Dictionary);
|
||||
}
|
||||
|
||||
Dictionary& newFrame = *(stack[mStackDepth]);
|
||||
newFrame.setState();
|
||||
|
||||
newFrame.scopeName = frameName;
|
||||
newFrame.scopeNamespace = ns;
|
||||
|
||||
Con::pushStackFrame(stack[mStackDepth]);
|
||||
mStackDepth++;
|
||||
currentVariable = NULL;
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
void ExprEvalState::popFrame()
|
||||
{
|
||||
AssertFatal(mStackDepth > 0, "ExprEvalState::popFrame - Stack Underflow!");
|
||||
|
||||
#ifdef DEBUG_SPEW
|
||||
validate();
|
||||
|
||||
Platform::outputDebugString("[ConsoleInternal] Popping %sframe at %i",
|
||||
getCurrentFrame().isOwner() ? "" : "shared ", mStackDepth - 1);
|
||||
#endif
|
||||
|
||||
Con::popStackFrame();
|
||||
mStackDepth--;
|
||||
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
|
||||
}
|
||||
|
||||
void ExprEvalState::pushFrameRef(S32 stackIndex)
|
||||
{
|
||||
AssertFatal(stackIndex >= 0 && stackIndex < mStackDepth, "You must be asking for a valid frame!");
|
||||
|
||||
#ifdef DEBUG_SPEW
|
||||
validate();
|
||||
|
||||
Platform::outputDebugString("[ConsoleInternal] Cloning frame from %i to %i",
|
||||
stackIndex, mStackDepth);
|
||||
#endif
|
||||
|
||||
if (mStackDepth + 1 > stack.size())
|
||||
{
|
||||
#ifdef DEBUG_SPEW
|
||||
Platform::outputDebugString("[ConsoleInternal] Growing stack by one frame");
|
||||
#endif
|
||||
|
||||
stack.push_back(new Dictionary);
|
||||
}
|
||||
|
||||
Dictionary& newFrame = *(stack[mStackDepth]);
|
||||
newFrame.setState(stack[stackIndex]);
|
||||
|
||||
Con::pushStackFrame(stack[mStackDepth]);
|
||||
|
||||
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.module = stack[stackIndex]->module;
|
||||
newFrame.ip = stack[stackIndex]->ip;
|
||||
}
|
||||
|
||||
ExprEvalState::ExprEvalState()
|
||||
{
|
||||
VECTOR_SET_ASSOCIATION(stack);
|
||||
currentVariable = NULL;
|
||||
mStackDepth = 0;
|
||||
stack.reserve(64);
|
||||
mShouldReset = false;
|
||||
mResetLocked = false;
|
||||
copyVariable = NULL;
|
||||
currentRegisterArray = NULL;
|
||||
}
|
||||
|
||||
ExprEvalState::~ExprEvalState()
|
||||
{
|
||||
// Delete callframes.
|
||||
|
||||
while (!stack.empty())
|
||||
{
|
||||
delete stack.last();
|
||||
stack.decrement();
|
||||
}
|
||||
}
|
||||
|
||||
void ExprEvalState::validate()
|
||||
{
|
||||
AssertFatal(mStackDepth <= stack.size(),
|
||||
"ExprEvalState::validate() - Stack depth pointing beyond last stack frame!");
|
||||
|
||||
for (U32 i = 0; i < stack.size(); ++i)
|
||||
stack[i]->validate();
|
||||
}
|
||||
119
Engine/source/console/torquescript/evalState.h
Normal file
119
Engine/source/console/torquescript/evalState.h
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
#ifndef _EVALSTATE_H
|
||||
#define _EVALSTATE_H
|
||||
#include "console/consoleInternal.h"
|
||||
|
||||
class ExprEvalState
|
||||
{
|
||||
public:
|
||||
/// @name Expression Evaluation
|
||||
/// @{
|
||||
|
||||
///
|
||||
|
||||
Dictionary::Entry *currentVariable;
|
||||
Dictionary::Entry *copyVariable;
|
||||
|
||||
U32 mStackDepth;
|
||||
bool mShouldReset; ///< Designates if the value stack should be reset
|
||||
bool mResetLocked; ///< mShouldReset will be set at the end
|
||||
|
||||
ExprEvalState();
|
||||
~ExprEvalState();
|
||||
|
||||
/// @}
|
||||
|
||||
/// @name Stack Management
|
||||
/// @{
|
||||
|
||||
/// The stack of callframes. The extra redirection is necessary since Dictionary holds
|
||||
/// an interior pointer that will become invalid when the object changes address.
|
||||
Vector< Dictionary* > stack;
|
||||
|
||||
S32 getTopOfStack() { return (S32)mStackDepth; }
|
||||
|
||||
Vector< ConsoleValueFrame > localStack;
|
||||
ConsoleValueFrame* currentRegisterArray; // contains array at to top of localStack
|
||||
|
||||
///
|
||||
|
||||
void setCurVarName(StringTableEntry name);
|
||||
void setCurVarNameCreate(StringTableEntry name);
|
||||
|
||||
S32 getIntVariable();
|
||||
F64 getFloatVariable();
|
||||
const char *getStringVariable();
|
||||
void setIntVariable(S32 val);
|
||||
void setFloatVariable(F64 val);
|
||||
void setStringVariable(const char *str);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
Dictionary& getCurrentFrame()
|
||||
{
|
||||
return *(stack[mStackDepth - 1]);
|
||||
}
|
||||
|
||||
Dictionary& getFrameAt(S32 depth)
|
||||
{
|
||||
return *(stack[depth]);
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
/// Run integrity checks for debugging.
|
||||
void validate();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -21,8 +21,7 @@
|
|||
// IN THE SOFTWARE.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "console/console.h"
|
||||
#include "console/codeBlock.h"
|
||||
#include "codeBlock.h"
|
||||
|
||||
static bool isLiteralNumber(ExprNode* node)
|
||||
{
|
||||
|
|
@ -85,7 +84,7 @@ bool IntBinaryExprNode::optimize()
|
|||
S32 val = getIntValue(right);
|
||||
switch (val)
|
||||
{
|
||||
case 2:
|
||||
case 2:
|
||||
op = '&';
|
||||
optimizedNode = IntNode::alloc(dbgLineNumber, 1);
|
||||
return true;
|
||||
0
Engine/source/console/torquescript/parser.cpp
Normal file
0
Engine/source/console/torquescript/parser.cpp
Normal file
49
Engine/source/console/torquescript/parser.h
Normal file
49
Engine/source/console/torquescript/parser.h
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
#ifndef _TORQUESCRIPT_PARSER_H_
|
||||
#define _TORQUESCRIPT_PARSER_H_
|
||||
#include <cstdio>
|
||||
|
||||
#include "platform/types.h"
|
||||
|
||||
const char* CMDGetCurrentFile();
|
||||
S32 CMDGetCurrentLine();
|
||||
S32 CMDparse();
|
||||
void CMDrestart(FILE* in);
|
||||
void CMDSetScanBuffer(const char *sb, const char *fn);
|
||||
|
||||
extern void expandEscape(char *dest, const char *src);
|
||||
extern bool collapseEscape(char *buf);
|
||||
|
||||
class TorqueScriptParser
|
||||
{
|
||||
public:
|
||||
TorqueScriptParser() = default;
|
||||
|
||||
const char* mExtension;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \brief Function for GetCurrentFile from the lexer
|
||||
//-----------------------------------------------------------------------------
|
||||
const char* getCurrentFile() { return CMDGetCurrentFile(); }
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \brief Function for GetCurrentLine from the lexer
|
||||
//-----------------------------------------------------------------------------
|
||||
S32 getCurrentLine() { return CMDGetCurrentLine(); }
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \brief Function for Parse from the lexer
|
||||
//-----------------------------------------------------------------------------
|
||||
S32 parse() { return CMDparse(); }
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \brief Function for Restart from the lexer
|
||||
//-----------------------------------------------------------------------------
|
||||
void restart(FILE *pInputFile) { CMDrestart(pInputFile); }
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/// \brief Function for SetScanBuffer from the lexer
|
||||
//-----------------------------------------------------------------------------
|
||||
void setScanBuffer(const char* sb, const char* fn) { CMDSetScanBuffer(sb, fn); }
|
||||
};
|
||||
|
||||
#endif
|
||||
486
Engine/source/console/torquescript/runtime.cpp
Normal file
486
Engine/source/console/torquescript/runtime.cpp
Normal file
|
|
@ -0,0 +1,486 @@
|
|||
#include "runtime.h"
|
||||
|
||||
#include "codeBlock.h"
|
||||
#include "console/script.h"
|
||||
#include "console/runtime.h"
|
||||
#include "core/volume.h"
|
||||
#include "core/stream/fileStream.h"
|
||||
#include "core/util/timeClass.h"
|
||||
|
||||
|
||||
namespace TorqueScript
|
||||
{
|
||||
// Buffer for expanding script filenames.
|
||||
static char scriptFilenameBuffer[1024];
|
||||
|
||||
TorqueScriptRuntime::TorqueScriptRuntime()
|
||||
{
|
||||
Con::registerRuntime(0, this);
|
||||
}
|
||||
|
||||
TorqueScriptRuntime::~TorqueScriptRuntime()
|
||||
{
|
||||
}
|
||||
|
||||
Con::EvalResult TorqueScriptRuntime::evaluate(const char* string, bool echo, const char* fileName)
|
||||
{
|
||||
ConsoleStackFrameSaver stackSaver;
|
||||
stackSaver.save();
|
||||
|
||||
if (echo)
|
||||
{
|
||||
if (string[0] == '%')
|
||||
Con::printf("%s", string);
|
||||
else
|
||||
Con::printf("%s%s", Con::getVariable("$Con::Prompt"), string);
|
||||
}
|
||||
|
||||
if (fileName)
|
||||
fileName = StringTable->insert(fileName);
|
||||
|
||||
CodeBlock* newCodeBlock = new CodeBlock();
|
||||
return std::move(newCodeBlock->compileExec(fileName, string, false, fileName ? -1 : 0));
|
||||
}
|
||||
|
||||
Con::EvalResult TorqueScriptRuntime::evaluate(const char* script, S32 frame, bool echo, const char* fileName)
|
||||
{
|
||||
// Make sure we're passing a valid frame to the eval.
|
||||
if (frame > Script::gEvalState.getStackDepth())
|
||||
frame = Script::gEvalState.getStackDepth() - 1;
|
||||
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(script);
|
||||
bool isEvaluatingLocalVariable = evalBufferLen > 0 && script[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 = Script::gEvalState.getStackDepth() - frame - 1;
|
||||
|
||||
Script::gEvalState.pushDebugFrame(stackIndex);
|
||||
|
||||
Dictionary& stackFrame = Script::gEvalState.getCurrentFrame();
|
||||
StringTableEntry functionName = stackFrame.scopeName;
|
||||
StringTableEntry namespaceName = stackFrame.scopeNamespace->mName;
|
||||
StringTableEntry varToLookup = StringTable->insert(script);
|
||||
|
||||
S32 registerId = ((CodeBlock*)stackFrame.module)->variableRegisterTable.lookup(namespaceName, functionName, varToLookup);
|
||||
|
||||
if (registerId == -1)
|
||||
{
|
||||
// ERROR, can't read the variable!
|
||||
return Con::EvalResult("variable not found");
|
||||
}
|
||||
|
||||
const char* varResult = Script::gEvalState.getLocalStringVariable(registerId);
|
||||
|
||||
Script::gEvalState.popFrame();
|
||||
|
||||
ConsoleValue val;
|
||||
val.setString(varResult);
|
||||
|
||||
return Con::EvalResult("variable not found");
|
||||
}
|
||||
|
||||
// Execute the eval.
|
||||
CodeBlock* newCodeBlock = new CodeBlock();
|
||||
Con::EvalResult result = newCodeBlock->compileExec(NULL, script, false, frame);
|
||||
return result;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
Con::EvalResult TorqueScriptRuntime::evaluatef(const char* string, ...)
|
||||
{
|
||||
char buffer[4096];
|
||||
va_list args;
|
||||
va_start(args, string);
|
||||
dVsprintf(buffer, sizeof(buffer), string, args);
|
||||
va_end(args);
|
||||
return evaluate(buffer);
|
||||
}
|
||||
|
||||
bool TorqueScriptRuntime::executeFile(const char* fileName, bool noCalls, bool journalScript)
|
||||
{
|
||||
bool journal = false;
|
||||
|
||||
U32 execDepth = 0;
|
||||
U32 journalDepth = 1;
|
||||
|
||||
execDepth++;
|
||||
if (journalDepth >= execDepth)
|
||||
journalDepth = execDepth + 1;
|
||||
else
|
||||
journal = true;
|
||||
|
||||
bool ret = false;
|
||||
|
||||
if (journalScript && !journal)
|
||||
{
|
||||
journal = true;
|
||||
journalDepth = execDepth;
|
||||
}
|
||||
|
||||
// Determine the filename we actually want...
|
||||
Con::expandScriptFilename(scriptFilenameBuffer, sizeof(scriptFilenameBuffer), fileName);
|
||||
|
||||
// since this function expects a script file reference, if it's a .dso
|
||||
// lets terminate the string before the dso so it will act like a .tscript
|
||||
if (dStrEndsWith(scriptFilenameBuffer, ".dso"))
|
||||
{
|
||||
scriptFilenameBuffer[dStrlen(scriptFilenameBuffer) - dStrlen(".dso")] = '\0';
|
||||
}
|
||||
|
||||
// Figure out where to put DSOs
|
||||
StringTableEntry dsoPath = Con::getDSOPath(scriptFilenameBuffer);
|
||||
|
||||
const char* ext = dStrrchr(scriptFilenameBuffer, '.');
|
||||
|
||||
if (!ext)
|
||||
{
|
||||
// Try appending the default script extension and see if that succeeds
|
||||
|
||||
if (executeFile(fileName + String("." TORQUE_SCRIPT_EXTENSION), noCalls, journalScript))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// We need an extension!
|
||||
Con::errorf(ConsoleLogEntry::Script, "exec: invalid script file name %s.", scriptFilenameBuffer);
|
||||
execDepth--;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check Editor Extensions
|
||||
bool isEditorScript = false;
|
||||
|
||||
// If the script file extension is '.ed.tscript' then compile it to a different compiled extension
|
||||
if (dStricmp(ext, "." TORQUE_SCRIPT_EXTENSION) == 0)
|
||||
{
|
||||
const char* ext2 = ext - 3;
|
||||
if (dStricmp(ext2, ".ed." TORQUE_SCRIPT_EXTENSION) == 0)
|
||||
isEditorScript = true;
|
||||
}
|
||||
else if (dStricmp(ext, ".gui") == 0)
|
||||
{
|
||||
const char* ext2 = ext - 3;
|
||||
if (dStricmp(ext2, ".ed.gui") == 0)
|
||||
isEditorScript = true;
|
||||
}
|
||||
|
||||
StringTableEntry scriptFileName = StringTable->insert(scriptFilenameBuffer);
|
||||
|
||||
// Is this a file we should compile? (anything in the prefs path should not be compiled)
|
||||
StringTableEntry prefsPath = Platform::getPrefsPath();
|
||||
bool compiled = dStricmp(ext, ".mis") && !journal && !Con::getBoolVariable("Scripts::ignoreDSOs");
|
||||
|
||||
// [tom, 12/5/2006] stripBasePath() fucks up if the filename is not in the exe
|
||||
// path, current directory or prefs path. Thus, getDSOFilename() will also screw
|
||||
// up and so this allows the scripts to still load but without a DSO.
|
||||
if (Platform::isFullPath(Platform::stripBasePath(scriptFilenameBuffer)))
|
||||
compiled = false;
|
||||
|
||||
// [tom, 11/17/2006] It seems to make sense to not compile scripts that are in the
|
||||
// prefs directory. However, getDSOPath() can handle this situation and will put
|
||||
// the dso along with the script to avoid name clashes with tools/game dsos.
|
||||
if ((dsoPath && *dsoPath == 0) || (prefsPath && prefsPath[0] && dStrnicmp(
|
||||
scriptFileName, prefsPath, dStrlen(prefsPath)) == 0))
|
||||
compiled = false;
|
||||
|
||||
// If we're in a journaling mode, then we will read the script
|
||||
// from the journal file.
|
||||
if (journal && Journal::IsPlaying())
|
||||
{
|
||||
char fileNameBuf[256];
|
||||
bool fileRead = false;
|
||||
U32 fileSize;
|
||||
|
||||
Journal::ReadString(fileNameBuf);
|
||||
Journal::Read(&fileRead);
|
||||
|
||||
if (!fileRead)
|
||||
{
|
||||
Con::errorf(ConsoleLogEntry::Script, "Journal script read (failed) for %s", fileNameBuf);
|
||||
execDepth--;
|
||||
return false;
|
||||
}
|
||||
Journal::Read(&fileSize);
|
||||
char* script = new char[fileSize + 1];
|
||||
Journal::Read(fileSize, script);
|
||||
script[fileSize] = 0;
|
||||
Con::printf("Executing (journal-read) %s.", scriptFileName);
|
||||
|
||||
CodeBlock *newCodeBlock = new CodeBlock();
|
||||
newCodeBlock->compileExec(scriptFileName, script, noCalls, 0);
|
||||
delete newCodeBlock;
|
||||
delete[] script;
|
||||
|
||||
execDepth--;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Ok, we let's try to load and compile the script.
|
||||
Torque::FS::FileNodeRef scriptFile = Torque::FS::GetFileNode(scriptFileName);
|
||||
Torque::FS::FileNodeRef dsoFile;
|
||||
|
||||
// ResourceObject *rScr = gResourceManager->find(scriptFileName);
|
||||
// ResourceObject *rCom = NULL;
|
||||
|
||||
char nameBuffer[512];
|
||||
char* script = NULL;
|
||||
U32 version;
|
||||
|
||||
Stream* compiledStream = NULL;
|
||||
Torque::Time scriptModifiedTime, dsoModifiedTime;
|
||||
|
||||
// Check here for .edso
|
||||
bool edso = false;
|
||||
if (dStricmp(ext, ".edso") == 0 && scriptFile != NULL)
|
||||
{
|
||||
edso = true;
|
||||
dsoFile = scriptFile;
|
||||
scriptFile = NULL;
|
||||
|
||||
dsoModifiedTime = dsoFile->getModifiedTime();
|
||||
dStrcpy(nameBuffer, scriptFileName, 512);
|
||||
}
|
||||
|
||||
// If we're supposed to be compiling this file, check to see if there's a DSO
|
||||
if (compiled && !edso)
|
||||
{
|
||||
const char* filenameOnly = dStrrchr(scriptFileName, '/');
|
||||
if (filenameOnly)
|
||||
++filenameOnly;
|
||||
else
|
||||
filenameOnly = scriptFileName;
|
||||
|
||||
char pathAndFilename[1024];
|
||||
Platform::makeFullPathName(filenameOnly, pathAndFilename, sizeof(pathAndFilename), dsoPath);
|
||||
|
||||
if (isEditorScript)
|
||||
dStrcpyl(nameBuffer, sizeof(nameBuffer), pathAndFilename, ".edso", NULL);
|
||||
else
|
||||
dStrcpyl(nameBuffer, sizeof(nameBuffer), pathAndFilename, ".dso", NULL);
|
||||
|
||||
dsoFile = Torque::FS::GetFileNode(nameBuffer);
|
||||
|
||||
if (scriptFile != NULL)
|
||||
scriptModifiedTime = scriptFile->getModifiedTime();
|
||||
|
||||
if (dsoFile != NULL)
|
||||
dsoModifiedTime = dsoFile->getModifiedTime();
|
||||
}
|
||||
|
||||
// Let's do a sanity check to complain about DSOs in the future.
|
||||
//
|
||||
// MM: This doesn't seem to be working correctly for now so let's just not issue
|
||||
// the warning until someone knows how to resolve it.
|
||||
//
|
||||
//if(compiled && rCom && rScr && Platform::compareFileTimes(comModifyTime, scrModifyTime) < 0)
|
||||
//{
|
||||
//Con::warnf("exec: Warning! Found a DSO from the future! (%s)", nameBuffer);
|
||||
//}
|
||||
|
||||
// If we had a DSO, let's check to see if we should be reading from it.
|
||||
//MGT: fixed bug with dsos not getting recompiled correctly
|
||||
//Note: Using Nathan Martin's version from the forums since its easier to read and understand
|
||||
if (compiled && dsoFile != NULL && (scriptFile == NULL || (dsoModifiedTime >= scriptModifiedTime)))
|
||||
{
|
||||
//MGT: end
|
||||
compiledStream = FileStream::createAndOpen(nameBuffer, Torque::FS::File::Read);
|
||||
if (compiledStream)
|
||||
{
|
||||
// Check the version!
|
||||
compiledStream->read(&version);
|
||||
if (version != Con::DSOVersion)
|
||||
{
|
||||
Con::warnf("exec: Found an old DSO (%s, ver %d < %d), ignoring.", nameBuffer, version, Con::DSOVersion);
|
||||
delete compiledStream;
|
||||
compiledStream = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we're journalling, let's write some info out.
|
||||
if (journal && Journal::IsRecording())
|
||||
Journal::WriteString(scriptFileName);
|
||||
|
||||
if (scriptFile != NULL && !compiledStream)
|
||||
{
|
||||
// If we have source but no compiled version, then we need to compile
|
||||
// (and journal as we do so, if that's required).
|
||||
|
||||
void* data;
|
||||
U32 dataSize = 0;
|
||||
Torque::FS::ReadFile(scriptFileName, data, dataSize, true);
|
||||
|
||||
if (journal && Journal::IsRecording())
|
||||
Journal::Write(bool(data != NULL));
|
||||
|
||||
if (data == NULL)
|
||||
{
|
||||
Con::errorf(ConsoleLogEntry::Script, "exec: invalid script file %s.", scriptFileName);
|
||||
execDepth--;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!dataSize)
|
||||
{
|
||||
execDepth--;
|
||||
return false;
|
||||
}
|
||||
|
||||
script = (char*)data;
|
||||
|
||||
if (journal && Journal::IsRecording())
|
||||
{
|
||||
Journal::Write(dataSize);
|
||||
Journal::Write(dataSize, data);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef TORQUE_NO_DSO_GENERATION
|
||||
if (compiled)
|
||||
{
|
||||
// compile this baddie.
|
||||
#ifdef TORQUE_DEBUG
|
||||
Con::printf("Compiling %s...", scriptFileName);
|
||||
#endif
|
||||
|
||||
CodeBlock *code = new CodeBlock();
|
||||
code->compile(nameBuffer, scriptFileName, script);
|
||||
delete code;
|
||||
code = NULL;
|
||||
|
||||
compiledStream = FileStream::createAndOpen(nameBuffer, Torque::FS::File::Read);
|
||||
if (compiledStream)
|
||||
{
|
||||
compiledStream->read(&version);
|
||||
}
|
||||
else
|
||||
{
|
||||
// We have to exit out here, as otherwise we get double error reports.
|
||||
delete[] script;
|
||||
execDepth--;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
if (journal && Journal::IsRecording())
|
||||
Journal::Write(bool(false));
|
||||
}
|
||||
|
||||
if (compiledStream)
|
||||
{
|
||||
// Delete the script object first to limit memory used
|
||||
// during recursive execs.
|
||||
delete[] script;
|
||||
script = 0;
|
||||
|
||||
// We're all compiled, so let's run it.
|
||||
#ifdef TORQUE_DEBUG
|
||||
Con::printf("Loading compiled script %s.", scriptFileName);
|
||||
#endif
|
||||
CodeBlock* code = new CodeBlock;
|
||||
code->read(scriptFileName, *compiledStream);
|
||||
delete compiledStream;
|
||||
code->exec(0, scriptFileName, NULL, 0, NULL, noCalls, NULL, 0);
|
||||
delete code;
|
||||
ret = true;
|
||||
}
|
||||
else if (scriptFile)
|
||||
{
|
||||
// No compiled script, let's just try executing it
|
||||
// directly... this is either a mission file, or maybe
|
||||
// we're on a readonly volume.
|
||||
#ifdef TORQUE_DEBUG
|
||||
Con::printf("Executing %s.", scriptFileName);
|
||||
#endif
|
||||
|
||||
CodeBlock *newCodeBlock = new CodeBlock();
|
||||
StringTableEntry name = StringTable->insert(scriptFileName);
|
||||
|
||||
newCodeBlock->compileExec(name, script, noCalls, 0);
|
||||
ret = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Don't have anything.
|
||||
Con::warnf(ConsoleLogEntry::Script, "Missing file: %s!", scriptFileName);
|
||||
ret = false;
|
||||
}
|
||||
|
||||
delete[] script;
|
||||
execDepth--;
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool TorqueScriptRuntime::compile(const char* fileName, bool overrideNoDso)
|
||||
{
|
||||
Con::expandScriptFilename( scriptFilenameBuffer, sizeof( scriptFilenameBuffer ), fileName );
|
||||
|
||||
// Figure out where to put DSOs
|
||||
StringTableEntry dsoPath = Con::getDSOPath(scriptFilenameBuffer);
|
||||
if(dsoPath && *dsoPath == 0)
|
||||
return false;
|
||||
|
||||
// If the script file extention is '.ed.tscript' then compile it to a different compiled extention
|
||||
bool isEditorScript = false;
|
||||
const char *ext = dStrrchr( scriptFilenameBuffer, '.' );
|
||||
if( ext && ( dStricmp( ext, "." TORQUE_SCRIPT_EXTENSION) == 0 ) )
|
||||
{
|
||||
const char* ext2 = ext - 3;
|
||||
if( dStricmp( ext2, ".ed." TORQUE_SCRIPT_EXTENSION) == 0 )
|
||||
isEditorScript = true;
|
||||
}
|
||||
else if( ext && ( dStricmp( ext, ".gui" ) == 0 ) )
|
||||
{
|
||||
const char* ext2 = ext - 3;
|
||||
if( dStricmp( ext2, ".ed.gui" ) == 0 )
|
||||
isEditorScript = true;
|
||||
}
|
||||
|
||||
const char *filenameOnly = dStrrchr(scriptFilenameBuffer, '/');
|
||||
if(filenameOnly)
|
||||
++filenameOnly;
|
||||
else
|
||||
filenameOnly = scriptFilenameBuffer;
|
||||
|
||||
char nameBuffer[512];
|
||||
|
||||
if( isEditorScript )
|
||||
dStrcpyl(nameBuffer, sizeof(nameBuffer), dsoPath, "/", filenameOnly, ".edso", NULL);
|
||||
else
|
||||
dStrcpyl(nameBuffer, sizeof(nameBuffer), dsoPath, "/", filenameOnly, ".dso", NULL);
|
||||
|
||||
void *data = NULL;
|
||||
U32 dataSize = 0;
|
||||
Torque::FS::ReadFile(scriptFilenameBuffer, data, dataSize, true);
|
||||
if(data == NULL)
|
||||
{
|
||||
Con::errorf(ConsoleLogEntry::Script, "compile: invalid script file %s.", scriptFilenameBuffer);
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *script = static_cast<const char *>(data);
|
||||
|
||||
#ifdef TORQUE_DEBUG
|
||||
Con::printf("Compiling %s...", scriptFilenameBuffer);
|
||||
#endif
|
||||
|
||||
CodeBlock *code = new CodeBlock();
|
||||
code->compile(nameBuffer, scriptFilenameBuffer, script, overrideNoDso);
|
||||
delete code;
|
||||
delete[] script;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
27
Engine/source/console/torquescript/runtime.h
Normal file
27
Engine/source/console/torquescript/runtime.h
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#ifndef _TORQUESCRIPT_RUNTIME_H_
|
||||
#define _TORQUESCRIPT_RUNTIME_H_
|
||||
#include "ast.h"
|
||||
#include "console/runtime.h"
|
||||
|
||||
namespace TorqueScript
|
||||
{
|
||||
class TorqueScriptRuntime : public Con::Runtime
|
||||
{
|
||||
public:
|
||||
TorqueScriptRuntime();
|
||||
~TorqueScriptRuntime() override;
|
||||
|
||||
void expandEscapedCharacters(char* dest, const char* src) override { expandEscape(dest, src); }
|
||||
bool collapseEscapedCharacters(char* buf) override { return collapseEscape(buf); }
|
||||
Con::EvalResult evaluate(const char* string, bool echo = false, const char* fileName = NULL) override;
|
||||
Con::EvalResult evaluate(const char* script, S32 frame, bool echo = false, const char *fileName = NULL) override;
|
||||
Con::EvalResult evaluatef(const char* string, ...) override;
|
||||
bool executeFile(const char* fileName, bool noCalls, bool journalScript) override;
|
||||
bool compile(const char* fileName, bool overrideNoDso);
|
||||
};
|
||||
|
||||
inline TorqueScriptRuntime* gRuntime = new TorqueScriptRuntime();
|
||||
inline TorqueScriptRuntime* getRuntime() { return gRuntime; }
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1234,18 +1234,6 @@ bool IsFile(const Path &path)
|
|||
return sgMountSystem.isFile(path);
|
||||
}
|
||||
|
||||
bool IsScriptFile(const char* pFilePath)
|
||||
{
|
||||
return (sgMountSystem.isFile(pFilePath)
|
||||
|| sgMountSystem.isFile(pFilePath + String(".dso"))
|
||||
|| sgMountSystem.isFile(pFilePath + String(".mis"))
|
||||
|| sgMountSystem.isFile(pFilePath + String(".mis.dso"))
|
||||
|| sgMountSystem.isFile(pFilePath + String(".gui"))
|
||||
|| sgMountSystem.isFile(pFilePath + String(".gui.dso"))
|
||||
|| sgMountSystem.isFile(pFilePath + String("." TORQUE_SCRIPT_EXTENSION))
|
||||
|| sgMountSystem.isFile(pFilePath + String("." TORQUE_SCRIPT_EXTENSION) + String(".dso")));
|
||||
}
|
||||
|
||||
bool IsDirectory(const Path &path)
|
||||
{
|
||||
return sgMountSystem.isDirectory(path);
|
||||
|
|
|
|||
|
|
@ -567,7 +567,6 @@ bool CreatePath(const Path &path);
|
|||
bool IsReadOnly(const Path &path);
|
||||
bool IsDirectory(const Path &path);
|
||||
bool IsFile(const Path &path);
|
||||
bool IsScriptFile(const char* pFilePath);
|
||||
bool VerifyWriteAccess(const Path &path);
|
||||
|
||||
/// This returns a unique file path from the components
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include "console/console.h"
|
||||
#include "console/engineAPI.h"
|
||||
#include "console/script.h"
|
||||
#include "core/volume.h"
|
||||
|
||||
// NOTE: The script class docs are in
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#include "gui/core/guiCanvas.h"
|
||||
#include "console/engineAPI.h"
|
||||
#include "console/script.h"
|
||||
#include "gfx/gfxDebugEvent.h"
|
||||
|
||||
#include "gfx/gl/gfxGLDevice.h"
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
#include "console/consoleTypes.h"
|
||||
#include "console/console.h"
|
||||
#include "console/script.h"
|
||||
#include "core/color.h"
|
||||
#include "gfx/gfxDrawUtil.h"
|
||||
#include "gui/core/guiDefaultControlRender.h"
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include "console/consoleTypes.h"
|
||||
#include "console/engineAPI.h"
|
||||
#include "console/script.h"
|
||||
#include "gfx/gfxDrawUtil.h"
|
||||
#include "gui/containers/guiScrollCtrl.h"
|
||||
#include "sim/actionMap.h"
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
|
||||
#include "console/consoleTypes.h"
|
||||
#include "console/engineAPI.h"
|
||||
#include "console/script.h"
|
||||
#include "gfx/gfxDrawUtil.h"
|
||||
#include "gui/containers/guiScrollCtrl.h"
|
||||
#include "core/strings/stringUnit.h"
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include "gui/controls/guiListBoxCtrl.h"
|
||||
#include "gfx/gfxDrawUtil.h"
|
||||
#include "console/engineAPI.h"
|
||||
#include "console/script.h"
|
||||
|
||||
IMPLEMENT_CONOBJECT(GuiListBoxCtrl);
|
||||
|
||||
|
|
@ -165,7 +166,7 @@ GuiListBoxCtrl::GuiListBoxCtrl()
|
|||
mColorBullet = true;
|
||||
mItemSize = Point2I(10,20);
|
||||
mLastClickItem = NULL;
|
||||
|
||||
|
||||
mRenderTooltipDelegate.bind( this, &GuiListBoxCtrl::renderTooltip );
|
||||
}
|
||||
|
||||
|
|
@ -469,11 +470,11 @@ void GuiListBoxCtrl::getSelectedItems( Vector<S32> &Items )
|
|||
{
|
||||
// Clear our return vector
|
||||
Items.clear();
|
||||
|
||||
|
||||
// If there are no selected items, return an empty vector
|
||||
if( mSelectedItems.empty() )
|
||||
return;
|
||||
|
||||
|
||||
for( S32 i = 0; i < mItems.size(); i++ )
|
||||
if( mItems[i]->isSelected )
|
||||
Items.push_back( i );
|
||||
|
|
@ -882,8 +883,8 @@ StringTableEntry GuiListBoxCtrl::getItemText( S32 index )
|
|||
Con::warnf( "GuiListBoxCtrl::getItemText - index out of range!" );
|
||||
return StringTable->lookup("");
|
||||
}
|
||||
|
||||
return mItems[ index ]->itemText;
|
||||
|
||||
return mItems[ index ]->itemText;
|
||||
}
|
||||
|
||||
DefineEngineMethod( GuiListBoxCtrl, getItemObject, const char*, (S32 index),,
|
||||
|
|
@ -917,7 +918,7 @@ SimObject* GuiListBoxCtrl::getItemObject( S32 index )
|
|||
SimObject *outObj;
|
||||
Sim::findObject( (SimObjectId)(uintptr_t)(mItems[ index ]->itemData), outObj );
|
||||
|
||||
return outObj;
|
||||
return outObj;
|
||||
}
|
||||
|
||||
DefineEngineMethod( GuiListBoxCtrl, setItemText, void, (S32 index, const char* newtext),,
|
||||
|
|
@ -974,7 +975,7 @@ DefineEngineMethod( GuiListBoxCtrl, setItemTooltip, void, (S32 index, const char
|
|||
Con::errorf( "GuiListBoxCtrl::setItemTooltip - index '%i' out of range", index );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
object->mItems[ index ]->itemTooltip = text;
|
||||
}
|
||||
|
||||
|
|
@ -1104,7 +1105,7 @@ bool GuiListBoxCtrl::renderTooltip( const Point2I &hoverPos, const Point2I& curs
|
|||
S32 hitItemIndex;
|
||||
if( hitTest( hoverPos, hitItemIndex ) )
|
||||
tipText = mItems[ hitItemIndex ]->itemTooltip;
|
||||
|
||||
|
||||
return defaultTooltipRender( hoverPos, cursorPos, tipText );
|
||||
}
|
||||
|
||||
|
|
@ -1115,7 +1116,7 @@ bool GuiListBoxCtrl::renderTooltip( const Point2I &hoverPos, const Point2I& curs
|
|||
bool GuiListBoxCtrl::hitTest( const Point2I& point, S32& outItem )
|
||||
{
|
||||
Point2I localPoint = globalToLocalCoord( point );
|
||||
|
||||
|
||||
S32 itemHit = ( localPoint.y < 0 ) ? -1 : (S32)mFloor( (F32)localPoint.y / (F32)mItemSize.y );
|
||||
if ( itemHit >= mItems.size() || itemHit == -1 )
|
||||
return false;
|
||||
|
|
@ -1123,7 +1124,7 @@ bool GuiListBoxCtrl::hitTest( const Point2I& point, S32& outItem )
|
|||
LBItem *hitItem = mItems[ itemHit ];
|
||||
if ( hitItem == NULL )
|
||||
return false;
|
||||
|
||||
|
||||
outItem = itemHit;
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1144,7 +1145,7 @@ void GuiListBoxCtrl::onMouseDown( const GuiEvent &event )
|
|||
S32 itemHit;
|
||||
if( !hitTest( event.mousePoint, itemHit ) )
|
||||
return;
|
||||
|
||||
|
||||
LBItem* hitItem = mItems[ itemHit ];
|
||||
|
||||
// If we're not a multiple selection listbox, we simply select/unselect an item
|
||||
|
|
@ -1172,7 +1173,7 @@ void GuiListBoxCtrl::onMouseDown( const GuiEvent &event )
|
|||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Deal with multiple selections
|
||||
if( event.modifier & SI_MULTISELECT)
|
||||
{
|
||||
|
|
@ -1219,7 +1220,7 @@ void GuiListBoxCtrl::onMouseUp( const GuiEvent& event )
|
|||
|
||||
// Execute console command
|
||||
execConsoleCallback();
|
||||
|
||||
|
||||
Parent::onMouseUp( event );
|
||||
}
|
||||
|
||||
|
|
@ -1268,7 +1269,7 @@ U32 GuiListBoxCtrl::getStringElementCount( const char* inString )
|
|||
// Yes...
|
||||
search = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Found a seperator?
|
||||
|
|
@ -1300,7 +1301,7 @@ U32 GuiListBoxCtrl::getStringElementCount( const char* inString )
|
|||
// Yes...
|
||||
search = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Found Seperator?
|
||||
|
|
@ -1357,7 +1358,7 @@ const char* GuiListBoxCtrl::getStringElement( const char* inString, const U32 in
|
|||
// Yes...
|
||||
search = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Found a seperator?
|
||||
|
|
@ -1396,7 +1397,7 @@ const char* GuiListBoxCtrl::getStringElement( const char* inString, const U32 in
|
|||
// Yes...
|
||||
search = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Found Seperator?
|
||||
|
|
@ -1446,19 +1447,19 @@ void GuiListBoxCtrl::_mirror()
|
|||
|
||||
// Allow script to filter out objects if desired.
|
||||
|
||||
Vector<SimObjectId> workingSet;
|
||||
Vector<SimObjectId> workingSet;
|
||||
|
||||
// If the method is not defined we assume user wants us to add
|
||||
// all objects.
|
||||
bool isObjMirroredDefined = isMethod( "isObjectMirrored" );
|
||||
|
||||
|
||||
for ( S32 i = 0; i < mirrorSet->size(); i++ )
|
||||
{
|
||||
bool addObj = true;
|
||||
|
||||
|
||||
if ( isObjMirroredDefined )
|
||||
addObj = isObjectMirrored_callback(mirrorSet->at(i)->getIdString());
|
||||
|
||||
addObj = isObjectMirrored_callback(mirrorSet->at(i)->getIdString());
|
||||
|
||||
if ( addObj )
|
||||
workingSet.push_back( mirrorSet->at(i)->getId() );
|
||||
}
|
||||
|
|
@ -1481,8 +1482,8 @@ void GuiListBoxCtrl::_mirror()
|
|||
if ( curObj )
|
||||
{
|
||||
if ( workingSet.contains( curId ) )
|
||||
{
|
||||
mItems[i]->itemText = _makeMirrorItemName( curObj );
|
||||
{
|
||||
mItems[i]->itemText = _makeMirrorItemName( curObj );
|
||||
keep = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -1492,7 +1493,7 @@ void GuiListBoxCtrl::_mirror()
|
|||
deleteItem( i );
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Add items that are in the SimSet but not yet in the list.
|
||||
|
|
@ -1512,7 +1513,7 @@ void GuiListBoxCtrl::_mirror()
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for ( U32 j = 0; j < mFilteredItems.size(); j++ )
|
||||
{
|
||||
if ( (SimObjectId)(uintptr_t)(mFilteredItems[j]->itemData) == curId )
|
||||
|
|
@ -1523,8 +1524,8 @@ void GuiListBoxCtrl::_mirror()
|
|||
}
|
||||
|
||||
if ( !found )
|
||||
{
|
||||
addItem( _makeMirrorItemName( curObj ), (void*)(uintptr_t)curId );
|
||||
{
|
||||
addItem( _makeMirrorItemName( curObj ), (void*)(uintptr_t)curId );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1537,12 +1538,12 @@ StringTableEntry GuiListBoxCtrl::_makeMirrorItemName( SimObject *inObj )
|
|||
{
|
||||
Con::setIntVariable( "$ThisControl", getId() );
|
||||
Con::setIntVariable( "$ThisObject", inObj->getId() );
|
||||
|
||||
outName = StringTable->insert( Con::evaluate( mMakeNameCallback ), true );
|
||||
|
||||
outName = StringTable->insert( Con::evaluate( mMakeNameCallback ).value, true );
|
||||
}
|
||||
else if ( inObj->getName() )
|
||||
outName = StringTable->insert( inObj->getName() );
|
||||
|
||||
|
||||
if ( !outName || !outName[0] )
|
||||
outName = StringTable->insert( "(no name)" );
|
||||
|
||||
|
|
@ -1582,22 +1583,22 @@ DefineEngineMethod( GuiListBoxCtrl, addFilteredItem, void, (const char* newItem)
|
|||
void GuiListBoxCtrl::addFilteredItem( String item )
|
||||
{
|
||||
// Delete from selected items list
|
||||
for ( S32 i = 0; i < mSelectedItems.size(); i++ )
|
||||
for ( S32 i = 0; i < mSelectedItems.size(); i++ )
|
||||
{
|
||||
String itemText = mSelectedItems[i]->itemText;
|
||||
if ( String::compare( itemText.c_str(), item.c_str() ) == 0 )
|
||||
if ( String::compare( itemText.c_str(), item.c_str() ) == 0 )
|
||||
{
|
||||
mSelectedItems.erase_fast( i );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for ( S32 i = 0; i < mItems.size(); i++ )
|
||||
for ( S32 i = 0; i < mItems.size(); i++ )
|
||||
{
|
||||
String itemText = mItems[i]->itemText;
|
||||
if( String::compare( itemText.c_str(), item.c_str() ) == 0 )
|
||||
{
|
||||
mItems[i]->isSelected = false;
|
||||
{
|
||||
mItems[i]->isSelected = false;
|
||||
mFilteredItems.push_front( mItems[i] );
|
||||
mItems.erase( &mItems[i] );
|
||||
break;
|
||||
|
|
@ -1625,11 +1626,11 @@ DefineEngineMethod( GuiListBoxCtrl, removeFilteredItem, void, ( const char* item
|
|||
|
||||
void GuiListBoxCtrl::removeFilteredItem( String item )
|
||||
{
|
||||
for ( S32 i = 0; i < mFilteredItems.size(); i++ )
|
||||
for ( S32 i = 0; i < mFilteredItems.size(); i++ )
|
||||
{
|
||||
String itemText = mFilteredItems[i]->itemText;
|
||||
if( String::compare( itemText.c_str(), item.c_str() ) == 0 )
|
||||
{
|
||||
{
|
||||
mItems.push_front( mFilteredItems[i] );
|
||||
mFilteredItems.erase( &mFilteredItems[i] );
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
#include "core/stringBuffer.h"
|
||||
#include "gfx/gfxDrawUtil.h"
|
||||
#include "console/engineAPI.h"
|
||||
#include "console/script.h"
|
||||
|
||||
IMPLEMENT_CONOBJECT(GuiMLTextEditCtrl);
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
#include "console/console.h"
|
||||
#include "console/consoleInternal.h"
|
||||
#include "console/engineAPI.h"
|
||||
#include "console/codeBlock.h"
|
||||
#include "console/script.h"
|
||||
#include "gfx/bitmap/gBitmap.h"
|
||||
#include "sim/actionMap.h"
|
||||
#include "gui/core/guiCanvas.h"
|
||||
|
|
@ -2489,7 +2489,7 @@ void GuiControl::getCursor(GuiCursor *&cursor, bool &showCursor, const GuiEvent
|
|||
const char* GuiControl::evaluate( const char* str )
|
||||
{
|
||||
smThisControl = this;
|
||||
const char* result = Con::evaluate(str, false);
|
||||
const char* result = Con::evaluate(str, false).value;
|
||||
smThisControl = NULL;
|
||||
|
||||
return result;
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#include "gui/containers/guiScrollCtrl.h"
|
||||
#include "core/strings/stringUnit.h"
|
||||
#include "console/engineAPI.h"
|
||||
#include "console/script.h"
|
||||
|
||||
|
||||
IMPLEMENT_CONOBJECT( GuiEditCtrl );
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#include "gui/editor/inspector/dynamicGroup.h"
|
||||
#include "gui/editor/inspector/dynamicField.h"
|
||||
#include "console/engineAPI.h"
|
||||
#include "console/script.h"
|
||||
|
||||
IMPLEMENT_CONOBJECT(GuiInspectorDynamicGroup);
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@
|
|||
#include "console/engineAPI.h"
|
||||
#include "platform/platform.h"
|
||||
#include "gui/editor/inspector/field.h"
|
||||
|
||||
#include "console/script.h"
|
||||
#include "gui/buttons/guiIconButtonCtrl.h"
|
||||
#include "gui/editor/guiInspector.h"
|
||||
#include "core/util/safeDelete.h"
|
||||
|
|
@ -321,7 +323,7 @@ void GuiInspectorField::setData( const char* data, bool callbacks )
|
|||
{
|
||||
char buffer[ 2048 ];
|
||||
expandEscape( buffer, newValue );
|
||||
evaluationResult = Con::evaluatef("$f = \"%s\"; return ( %s );", oldValue.c_str(), buffer);
|
||||
evaluationResult = Con::evaluatef("$f = \"%s\"; return ( %s );", oldValue.c_str(), buffer).value;
|
||||
newValue = evaluationResult.getString();
|
||||
Con::evaluatef("$f=0;");
|
||||
}
|
||||
|
|
@ -359,7 +361,7 @@ void GuiInspectorField::setData( const char* data, bool callbacks )
|
|||
expandEscape( buffer, newComponentExpr );
|
||||
|
||||
evaluationResult = Con::evaluatef("$f = \"%s\"; $v = \"%s\"; return ( %s );",
|
||||
oldComponentVal, oldValue.c_str(), buffer);
|
||||
oldComponentVal, oldValue.c_str(), buffer).value;
|
||||
Con::evaluatef("$f=0;$v=0;");
|
||||
|
||||
if( !isFirst )
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@
|
|||
|
||||
#include "gui/editor/guiInspector.h"
|
||||
#include "gui/editor/inspector/group.h"
|
||||
|
||||
#include "console/script.h"
|
||||
#include "gui/editor/inspector/dynamicField.h"
|
||||
#include "gui/editor/inspector/datablockField.h"
|
||||
#include "gui/buttons/guiIconButtonCtrl.h"
|
||||
|
|
|
|||
|
|
@ -25,8 +25,7 @@
|
|||
#include "gui/editor/guiInspector.h"
|
||||
#include "gui/buttons/guiIconButtonCtrl.h"
|
||||
#include "console/consoleInternal.h"
|
||||
|
||||
extern ExprEvalState gEvalState;
|
||||
#include "console/script.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// GuiInspectorVariableGroup
|
||||
|
|
@ -65,7 +64,7 @@ bool GuiInspectorVariableGroup::inspectGroup()
|
|||
{
|
||||
Vector<String> names;
|
||||
|
||||
gEvalState.globalVars.exportVariables(mSearchString, &names, NULL);
|
||||
Con::gGlobalVars.exportVariables(mSearchString, &names, NULL);
|
||||
|
||||
for (U32 i = 0; i < names.size(); i++)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
#include "gui/shiny/guiAudioCtrl.h"
|
||||
#include "console/engineAPI.h"
|
||||
#include "console/script.h"
|
||||
#include "sfx/sfxSystem.h"
|
||||
#include "sfx/sfxTrack.h"
|
||||
#include "sfx/sfxSource.h"
|
||||
|
|
|
|||
|
|
@ -25,8 +25,6 @@
|
|||
#include "core/stream/fileStream.h"
|
||||
#include "console/console.h"
|
||||
#include "console/consoleInternal.h"
|
||||
#include "console/ast.h"
|
||||
#include "console/compiler.h"
|
||||
#include "core/util/safeDelete.h"
|
||||
#include "console/engineAPI.h"
|
||||
|
||||
|
|
@ -102,7 +100,7 @@ bool LangFile::load(Stream *s)
|
|||
bool LangFile::save(const UTF8 *filename)
|
||||
{
|
||||
FileStream *fs;
|
||||
|
||||
|
||||
if(!isLoaded())
|
||||
return false;
|
||||
|
||||
|
|
@ -168,7 +166,7 @@ void LangFile::setLangName(const UTF8 *newName)
|
|||
{
|
||||
if(mLangName)
|
||||
delete [] mLangName;
|
||||
|
||||
|
||||
dsize_t langNameLen = dStrlen(newName) + 1;
|
||||
mLangName = new UTF8 [langNameLen];
|
||||
dStrcpy(mLangName, newName, langNameLen);
|
||||
|
|
@ -178,7 +176,7 @@ void LangFile::setLangFile(const UTF8 *langFile)
|
|||
{
|
||||
if(mLangFile)
|
||||
delete [] mLangFile;
|
||||
|
||||
|
||||
dsize_t langFileLen = dStrlen(langFile) + 1;
|
||||
mLangFile = new UTF8 [langFileLen];
|
||||
dStrcpy(mLangFile, langFile, langFileLen);
|
||||
|
|
@ -211,7 +209,7 @@ IMPLEMENT_CONOBJECT(LangTable);
|
|||
ConsoleDocClass( LangTable,
|
||||
"@brief Provides the code necessary to handle the low level management "
|
||||
"of the string tables for localization\n\n"
|
||||
|
||||
|
||||
"One LangTable is created for each mod, as well as one for the C++ code. "
|
||||
"LangTable is responsible for obtaining the correct strings from each "
|
||||
"and relaying it to the appropriate controls.\n\n"
|
||||
|
|
@ -260,7 +258,7 @@ S32 LangTable::addLanguage(const UTF8 *filename, const UTF8 *name /* = NULL */)
|
|||
if(Torque::FS::IsFile(filename))
|
||||
{
|
||||
lang->setLangFile(filename);
|
||||
|
||||
|
||||
S32 ret = addLanguage(lang);
|
||||
if(ret >= 0)
|
||||
return ret;
|
||||
|
|
@ -287,7 +285,7 @@ const U32 LangTable::getStringLength(const U32 id) const
|
|||
const UTF8 *s = getString(id);
|
||||
if(s)
|
||||
return dStrlen(s);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -299,7 +297,7 @@ void LangTable::setDefaultLanguage(S32 langid)
|
|||
{
|
||||
if(mDefaultLang >= 0)
|
||||
mLangTable[mDefaultLang]->deactivateLanguage();
|
||||
|
||||
|
||||
mDefaultLang = langid;
|
||||
}
|
||||
}
|
||||
|
|
@ -329,7 +327,7 @@ void LangTable::setCurrentLanguage(S32 langid)
|
|||
|
||||
|
||||
|
||||
DefineEngineMethod(LangTable, addLanguage, S32, (String filename, String languageName), ("", ""),
|
||||
DefineEngineMethod(LangTable, addLanguage, S32, (String filename, String languageName), ("", ""),
|
||||
"(string filename, [string languageName])"
|
||||
"@brief Adds a language to the table\n\n"
|
||||
"@param filename Name and path to the language file\n"
|
||||
|
|
@ -338,12 +336,12 @@ DefineEngineMethod(LangTable, addLanguage, S32, (String filename, String languag
|
|||
)
|
||||
{
|
||||
UTF8 scriptFilenameBuffer[1024];
|
||||
|
||||
|
||||
Con::expandScriptFilename((char*)scriptFilenameBuffer, sizeof(scriptFilenameBuffer), filename);
|
||||
return object->addLanguage(scriptFilenameBuffer, (const UTF8*)languageName);
|
||||
}
|
||||
|
||||
DefineEngineMethod(LangTable, getString, const char *, (U32 id), ,
|
||||
DefineEngineMethod(LangTable, getString, const char *, (U32 id), ,
|
||||
"(string filename)"
|
||||
"@brief Grabs a string from the specified table\n\n"
|
||||
"If an invalid is passed, the function will attempt to "
|
||||
|
|
@ -359,7 +357,7 @@ DefineEngineMethod(LangTable, getString, const char *, (U32 id), ,
|
|||
dStrcpy(ret, str, retLen);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
|
|
@ -370,7 +368,7 @@ DefineEngineMethod(LangTable, setDefaultLanguage, void, (S32 langId), , "(int la
|
|||
object->setDefaultLanguage(langId);
|
||||
}
|
||||
|
||||
DefineEngineMethod(LangTable, setCurrentLanguage, void, (S32 langId), ,
|
||||
DefineEngineMethod(LangTable, setCurrentLanguage, void, (S32 langId), ,
|
||||
"(int language)"
|
||||
"@brief Sets the current language table for grabbing text\n\n"
|
||||
"@param language ID of the table\n")
|
||||
|
|
@ -398,7 +396,7 @@ DefineEngineMethod(LangTable, getLangName, const char *, (S32 langId), , "(int l
|
|||
dStrcpy(ret, str, retLen);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
|
|
@ -420,9 +418,9 @@ UTF8 *sanitiseVarName(const UTF8 *varName, UTF8 *buffer, U32 bufsize)
|
|||
*buffer = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
dStrcpy(buffer, (const UTF8*)"I18N::", bufsize);
|
||||
|
||||
|
||||
UTF8 *dptr = buffer + 6;
|
||||
const UTF8 *sptr = varName;
|
||||
while(*sptr)
|
||||
|
|
@ -435,27 +433,27 @@ UTF8 *sanitiseVarName(const UTF8 *varName, UTF8 *buffer, U32 bufsize)
|
|||
*dptr++ = '_';
|
||||
sptr++;
|
||||
}
|
||||
|
||||
|
||||
if((dptr - buffer) >= (bufsize - 1))
|
||||
break;
|
||||
}
|
||||
*dptr = 0;
|
||||
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
UTF8 *getCurrentModVarName(UTF8 *buffer, U32 bufsize)
|
||||
{
|
||||
char varName[256];
|
||||
StringTableEntry cbName = CodeBlock::getCurrentCodeBlockName();
|
||||
|
||||
StringTableEntry cbName = Con::getCurrentScriptModuleName();
|
||||
|
||||
const UTF8 *slash = (const UTF8*)dStrchr(cbName, '/');
|
||||
if (slash == NULL)
|
||||
{
|
||||
Con::errorf("Illegal CodeBlock path detected in sanitiseVarName() (no mod directory): %s", cbName);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
dStrncpy(varName, cbName, slash - (const UTF8*)cbName);
|
||||
varName[slash - (const UTF8*)cbName] = 0;
|
||||
|
||||
|
|
@ -465,7 +463,7 @@ UTF8 *getCurrentModVarName(UTF8 *buffer, U32 bufsize)
|
|||
const LangTable *getCurrentModLangTable()
|
||||
{
|
||||
UTF8 saneVarName[256];
|
||||
|
||||
|
||||
if(getCurrentModVarName(saneVarName, sizeof(saneVarName)))
|
||||
{
|
||||
const LangTable *lt = dynamic_cast<LangTable *>(Sim::findObject(Con::getIntVariable((const char*)saneVarName)));
|
||||
|
|
@ -508,7 +506,7 @@ bool compiledFileNeedsUpdate(UTF8* filename)
|
|||
return false;
|
||||
}
|
||||
|
||||
DefineEngineFunction(CompileLanguage, void, (const char* inputFile, bool createMap), (false),
|
||||
DefineEngineFunction(CompileLanguage, void, (const char* inputFile, bool createMap), (false),
|
||||
"@brief Compiles a LSO language file."
|
||||
" if createIndex is true, will also create languageMap." TORQUE_SCRIPT_EXTENSION " with"
|
||||
" the global variables for each string index."
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@
|
|||
|
||||
#include "platform/platform.h"
|
||||
#include "postFx/postEffectVis.h"
|
||||
|
||||
#include "console/script.h"
|
||||
#include "gui/containers/guiWindowCtrl.h"
|
||||
#include "gui/controls/guiBitmapCtrl.h"
|
||||
#include "gui/core/guiCanvas.h"
|
||||
|
|
|
|||
|
|
@ -37,6 +37,8 @@
|
|||
#include "core/module.h"
|
||||
#include "math/mathIO.h"
|
||||
#include "math/mathTypes.h"
|
||||
#include "console/simBase.h"
|
||||
#include "console/engineAPI.h"
|
||||
|
||||
|
||||
IMPLEMENT_CO_DATABLOCK_V1( SFXDescription );
|
||||
|
|
@ -455,7 +457,7 @@ bool SFXDescription::onAdd()
|
|||
const char* channelValue = getDataField( sChannel, NULL );
|
||||
if( channelValue && channelValue[ 0 ] )
|
||||
{
|
||||
ConsoleValue result = Con::evaluatef( "return sfxOldChannelToGroup( %s );", channelValue );
|
||||
ConsoleValue result = Con::executef("sfxOldChannelToGroup", channelValue);
|
||||
const char* group = result.getString();
|
||||
if( !Sim::findObject( group, mSourceGroup ) )
|
||||
Con::errorf( "SFXDescription::onAdd - could not resolve channel '%s' to SFXSource", channelValue );
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@
|
|||
#include "core/stream/fileStream.h"
|
||||
#include "math/mMathFn.h"
|
||||
#include "console/engineAPI.h"
|
||||
#include "console/script.h"
|
||||
#include "math/mQuat.h"
|
||||
#include "math/mAngAxis.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -26,12 +26,13 @@
|
|||
#include "console/simBase.h"
|
||||
#include "console/engineAPI.h"
|
||||
#include "math/mMath.h"
|
||||
#include "console/script.h"
|
||||
#include "console/stringStack.h"
|
||||
#include "gui/buttons/guiIconButtonCtrl.h"
|
||||
|
||||
inline ConsoleValue RunScript(const char* str)
|
||||
{
|
||||
return std::move(Con::evaluate(str, false, NULL));
|
||||
return std::move(Con::evaluate(str, false, NULL).value);
|
||||
}
|
||||
|
||||
using ::testing::Matcher;
|
||||
|
|
|
|||
|
|
@ -7,12 +7,10 @@
|
|||
#include "console/simBase.h"
|
||||
#include "console/engineAPI.h"
|
||||
#include "math/mMath.h"
|
||||
#include "console/script.h"
|
||||
#include "console/stringStack.h"
|
||||
#include "console/consoleInternal.h"
|
||||
|
||||
// Stupid globals not declared in a header
|
||||
extern ExprEvalState gEvalState;
|
||||
|
||||
using ::testing::Matcher;
|
||||
using ::testing::TypedEq;
|
||||
|
||||
|
|
@ -25,10 +23,10 @@ protected:
|
|||
|
||||
void SetUp() override
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
TEST_F(ConsoleTest, executef)
|
||||
|
|
@ -176,7 +174,7 @@ TEST_F(ConsoleTest, execute)
|
|||
{
|
||||
Con::evaluate("function testScriptExecuteFunction(%a,%b) {return %a SPC %b;}\nfunction testScriptExecuteFunction(%a,%b,%this) {return %a SPC %b;}\r\n", false, "testExecute");
|
||||
|
||||
U32 startStackPos = gEvalState.getStackDepth();
|
||||
U32 startStackPos = Con::getFrameStack().size();
|
||||
U32 startStringStackPos = STR.mStart;
|
||||
|
||||
// const char* versions of execute should maintain stack
|
||||
|
|
@ -187,7 +185,7 @@ TEST_F(ConsoleTest, execute)
|
|||
EXPECT_STREQ(returnValue, "1 2") <<
|
||||
"execute should return 1 2";
|
||||
|
||||
EXPECT_EQ(gEvalState.getStackDepth(), startStackPos) <<
|
||||
EXPECT_EQ(Con::getFrameStack().size(), startStackPos) <<
|
||||
"execute should restore stack";
|
||||
|
||||
returnValue = Con::execute(4, argvObject);
|
||||
|
|
@ -195,6 +193,6 @@ TEST_F(ConsoleTest, execute)
|
|||
EXPECT_STREQ(returnValue, "1 2") <<
|
||||
"execute should return 1 2";
|
||||
|
||||
EXPECT_EQ(gEvalState.getStackDepth(), startStackPos) <<
|
||||
EXPECT_EQ(Con::getFrameStack().size(), startStackPos) <<
|
||||
"execute should restore stack";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include "console/simBase.h"
|
||||
#include "console/engineAPI.h"
|
||||
#include "math/mMath.h"
|
||||
#include "console/script.h"
|
||||
|
||||
using ::testing::Matcher;
|
||||
using ::testing::TypedEq;
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#include "console/simBase.h"
|
||||
#include "console/consoleTypes.h"
|
||||
#include "console/runtimeClassRep.h"
|
||||
#include "console/script.h"
|
||||
|
||||
class RuntimeRegisteredSimObject : public SimObject
|
||||
{
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
#include "app/mainLoop.h"
|
||||
#include "console/console.h"
|
||||
#include "console/codeBlock.h"
|
||||
#include "console/script.h"
|
||||
#include "console/engineAPI.h"
|
||||
#include "console/consoleInternal.h"
|
||||
#include "gfx/gfxInit.h"
|
||||
|
|
@ -32,6 +32,8 @@
|
|||
#define _CRTDBG_MAP_ALLOC
|
||||
#include <crtdbg.h>
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class TorqueUnitTestListener : public ::testing::EmptyTestEventListener
|
||||
|
|
@ -195,9 +197,9 @@ DefineEngineFunction(addUnitTest, void, (const char* function), ,
|
|||
U32 ln = __LINE__;
|
||||
if (entry != NULL)
|
||||
{
|
||||
file = entry->mCode->name;
|
||||
file = entry->mModule->getName();
|
||||
U32 inst;
|
||||
entry->mCode->findBreakLine(entry->mFunctionOffset, ln, inst);
|
||||
entry->mModule->findBreakLine(entry->mFunctionOffset, ln, inst);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -210,9 +212,9 @@ DefineEngineFunction(addUnitTest, void, (const char* function), ,
|
|||
|
||||
String scriptFileMessage(const char* message)
|
||||
{
|
||||
Dictionary* frame = &gEvalState.getCurrentFrame();
|
||||
CodeBlock* code = frame->code;
|
||||
const char* scriptLine = code->getFileLine(frame->ip);
|
||||
Dictionary* frame = Con::getCurrentStackFrame();
|
||||
Con::Module* module = frame->module;
|
||||
const char* scriptLine = module->getFileLine(frame->ip);
|
||||
return String::ToString("at %s: %s", scriptLine, message);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,12 +29,13 @@
|
|||
#include "console/console.h"
|
||||
#include "ts/tsShapeInstance.h"
|
||||
#include "collision/convex.h"
|
||||
#include "console/consoleInternal.h"
|
||||
#include "console/script.h"
|
||||
#include "materials/matInstance.h"
|
||||
#include "materials/materialManager.h"
|
||||
#include "math/mathIO.h"
|
||||
#include "core/util/endian.h"
|
||||
#include "core/stream/fileStream.h"
|
||||
#include "console/compiler.h"
|
||||
#include "core/fileObject.h"
|
||||
|
||||
#ifdef TORQUE_COLLADA
|
||||
|
|
@ -2144,7 +2145,7 @@ template<> void *Resource<TSShape>::create(const Torque::Path &path)
|
|||
scriptPath.setExtension(TORQUE_SCRIPT_EXTENSION);
|
||||
|
||||
// Don't execute the script if we're already doing so!
|
||||
StringTableEntry currentScript = Platform::stripBasePath(CodeBlock::getCurrentCodeBlockFullPath());
|
||||
StringTableEntry currentScript = Platform::stripBasePath(Con::getCurrentScriptModulePath());
|
||||
if (!scriptPath.getFullPath().equal(currentScript))
|
||||
{
|
||||
Torque::Path scriptPathDSO(scriptPath);
|
||||
|
|
|
|||
|
|
@ -650,7 +650,7 @@ void PlatformWindowSDL::_processSDLEvent(SDL_Event &evt)
|
|||
_updateMonitorFromMove(evt);
|
||||
// If display device has changed, make sure window params are compatible with the new device.
|
||||
if (oldDisplay != Con::getIntVariable("pref::Video::deviceId", 0))
|
||||
Con::evaluate("configureCanvas();");
|
||||
Con::executef("configureCanvas");
|
||||
break;
|
||||
}
|
||||
case SDL_WINDOWEVENT_RESIZED:
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "windowManager/windowInputGenerator.h"
|
||||
|
||||
#include "console/script.h"
|
||||
#include "windowManager/platformWindow.h"
|
||||
#include "sim/actionMap.h"
|
||||
#include "platform/input/IProcessInput.h"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue