2022-09-12 16:04:22 +08:00
|
|
|
/************************************************************************************//*!
|
|
|
|
\file SHScriptEngine.cpp
|
|
|
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
|
|
|
\par email: kahwei.tng\@digipen.edu
|
|
|
|
\date Sep 17, 2021
|
|
|
|
\brief Contains the implementation for ScriptEngine class.
|
|
|
|
|
|
|
|
Copyright (C) 2021 DigiPen Institute of Technology.
|
|
|
|
Reproduction or disclosure of this file or its contents without the prior written consent
|
|
|
|
of DigiPen Institute of Technology is prohibited.
|
|
|
|
*//*************************************************************************************/
|
|
|
|
// Precompiled Headers
|
|
|
|
#include <SHpch.h>
|
|
|
|
// Primary Header
|
|
|
|
#include "SHScriptEngine.h"
|
|
|
|
// Standard Library
|
|
|
|
#include <fstream> // std::fstream
|
|
|
|
#include <filesystem> // std::filesystem::canonical, std::filesystem::remove
|
|
|
|
// Project Headers
|
|
|
|
#include "Tools/SHLogger.h"
|
|
|
|
#include "Tools/SHStringUtils.h"
|
|
|
|
|
|
|
|
namespace SHADE
|
|
|
|
{
|
|
|
|
/*--------------------------------------------------------------------------------*/
|
|
|
|
/* Static Definitions */
|
|
|
|
/*--------------------------------------------------------------------------------*/
|
2022-09-14 20:26:31 +08:00
|
|
|
const std::string SHScriptEngine::DEFAULT_CSHARP_NAMESPACE = std::string("SHADE");
|
2022-09-13 20:30:32 +08:00
|
|
|
SHDotNetRuntime SHScriptEngine::dotNet { false };
|
|
|
|
SHScriptEngine::CsFuncPtr SHScriptEngine::csEngineInit = nullptr;
|
|
|
|
SHScriptEngine::CsFuncPtr SHScriptEngine::csEngineLoadScripts = nullptr;
|
|
|
|
SHScriptEngine::CsFuncPtr SHScriptEngine::csEngineUnloadScripts = nullptr;
|
|
|
|
SHScriptEngine::CsFuncPtr SHScriptEngine::csEngineReloadScripts = nullptr;
|
|
|
|
SHScriptEngine::CsFuncPtr SHScriptEngine::csEngineExit = nullptr;
|
|
|
|
SHScriptEngine::CsFuncPtr SHScriptEngine::csScriptsFrameSetUp = nullptr;
|
|
|
|
SHScriptEngine::CsFuncPtr SHScriptEngine::csScriptsExecuteFixedUpdate = nullptr;
|
|
|
|
SHScriptEngine::CsFuncPtr SHScriptEngine::csScriptsExecuteUpdate = nullptr;
|
|
|
|
SHScriptEngine::CsFuncPtr SHScriptEngine::csScriptsExecuteLateUpdate = nullptr;
|
|
|
|
SHScriptEngine::CsFuncPtr SHScriptEngine::csScriptsFrameCleanUp = nullptr;
|
|
|
|
SHScriptEngine::CsScriptManipFuncPtr SHScriptEngine::csScriptsAdd = nullptr;
|
|
|
|
SHScriptEngine::CsScriptBasicFuncPtr SHScriptEngine::csScriptsRemoveAll = nullptr;
|
|
|
|
SHScriptEngine::CsScriptOptionalFuncPtr SHScriptEngine::csScriptsRemoveAllImmediately = nullptr;
|
|
|
|
SHScriptEngine::CsScriptSerialiseFuncPtr SHScriptEngine::csScriptsSerialise = nullptr;
|
|
|
|
SHScriptEngine::CsScriptDeserialiseFuncPtr SHScriptEngine::csScriptDeserialise = nullptr;
|
|
|
|
SHScriptEngine::CsScriptSerialiseYamlFuncPtr SHScriptEngine::csScriptsSerialiseYaml = nullptr;
|
|
|
|
SHScriptEngine::CsScriptSerialiseYamlFuncPtr SHScriptEngine::csScriptDeserialiseYaml = nullptr;
|
|
|
|
SHScriptEngine::CsScriptEditorFuncPtr SHScriptEngine::csEditorRenderScripts = nullptr;
|
2022-09-12 16:04:22 +08:00
|
|
|
|
|
|
|
/*---------------------------------------------------------------------------------*/
|
|
|
|
/* Lifecycle Functions */
|
|
|
|
/*---------------------------------------------------------------------------------*/
|
|
|
|
void SHScriptEngine::Init()
|
|
|
|
{
|
|
|
|
// Do not allow initialization if already initialised
|
|
|
|
if (dotNet.IsLoaded())
|
|
|
|
{
|
|
|
|
SHLOG_ERROR("[ScriptEngine] Attempted to initialise an already loaded DotNetRuntime.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
dotNet.Init();
|
|
|
|
|
|
|
|
// Load all the helpers
|
|
|
|
loadFunctions();
|
|
|
|
|
|
|
|
// Generate script assembly if it hasn't been before
|
|
|
|
if (!fileExists(std::string(MANAGED_SCRIPT_LIB_NAME) + ".dll"))
|
|
|
|
{
|
|
|
|
BuildScriptAssembly();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Initialise the CSharp Engine
|
|
|
|
csEngineInit();
|
|
|
|
|
|
|
|
// Link events
|
|
|
|
// - Entity Destruction
|
|
|
|
/*onEntityDestroy = [this](const SHEntity& e)
|
|
|
|
{
|
|
|
|
csScriptsRemoveAll(e.GetEID());
|
|
|
|
csGOLibNotifyDestroyEntity(e.GetEID());
|
|
|
|
};
|
|
|
|
ECS::OnEntityDestroy += onEntityDestroy;*/
|
|
|
|
}
|
|
|
|
void SHScriptEngine::UnloadScriptAssembly()
|
|
|
|
{
|
|
|
|
csEngineUnloadScripts();
|
|
|
|
}
|
|
|
|
void SHScriptEngine::LoadScriptAssembly()
|
|
|
|
{
|
|
|
|
csEngineLoadScripts();
|
|
|
|
}
|
|
|
|
void SHScriptEngine::ReloadScriptAssembly()
|
|
|
|
{
|
|
|
|
csEngineReloadScripts();
|
|
|
|
}
|
|
|
|
void SHScriptEngine::ExecuteFixedUpdates()
|
|
|
|
{
|
|
|
|
csScriptsExecuteFixedUpdate();
|
|
|
|
}
|
|
|
|
|
|
|
|
void SHScriptEngine::Exit()
|
|
|
|
{
|
|
|
|
// Do not allow deinitialization if not initialised
|
|
|
|
if (!dotNet.IsLoaded())
|
|
|
|
{
|
|
|
|
SHLOG_ERROR("[ScriptEngine] Attempted to clean up an unloaded DotNetRuntime.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Unlink events
|
|
|
|
/*ECS::OnEntityCreated -= onEntityCreate;
|
|
|
|
ECS::OnEntityDestroy -= onEntityDestroy;*/
|
|
|
|
|
|
|
|
// Clean up the CSharp Engine
|
|
|
|
csEngineExit();
|
|
|
|
|
|
|
|
// Shut down the CLR
|
|
|
|
dotNet.Exit();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*---------------------------------------------------------------------------------*/
|
|
|
|
/* Script Manipulation Functions */
|
|
|
|
/*---------------------------------------------------------------------------------*/
|
2022-09-13 20:30:32 +08:00
|
|
|
bool SHScriptEngine::AddScript(const SHEntity& entity, const std::string_view& scriptName)
|
2022-09-12 16:04:22 +08:00
|
|
|
{
|
|
|
|
return csScriptsAdd(entity.GetEID(), scriptName.data());
|
|
|
|
}
|
2022-09-13 20:30:32 +08:00
|
|
|
void SHScriptEngine::RemoveAllScripts(const SHEntity& entity)
|
2022-09-12 16:04:22 +08:00
|
|
|
{
|
|
|
|
csScriptsRemoveAll(entity.GetEID());
|
|
|
|
}
|
2022-09-13 20:30:32 +08:00
|
|
|
void SHScriptEngine::RemoveAllScriptsImmediately(const SHEntity& entity, bool callOnDestroy)
|
2022-09-12 16:04:22 +08:00
|
|
|
{
|
|
|
|
csScriptsRemoveAllImmediately(entity.GetEID(), callOnDestroy);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*---------------------------------------------------------------------------------*/
|
|
|
|
/* Script Serialisation Functions */
|
|
|
|
/*---------------------------------------------------------------------------------*/
|
2022-09-13 20:30:32 +08:00
|
|
|
std::string SHScriptEngine::SerialiseScripts(const SHEntity& entity)
|
2022-09-12 16:04:22 +08:00
|
|
|
{
|
|
|
|
// Create buffer needed to store serialised script data
|
|
|
|
constexpr int BUFFER_SIZE = 10240;
|
|
|
|
std::unique_ptr<char> buffer { new char[BUFFER_SIZE] };
|
|
|
|
std::memset(buffer.get(), 0, BUFFER_SIZE);
|
|
|
|
|
|
|
|
// Attempt to serialise the script
|
|
|
|
std::string result;
|
|
|
|
if (csScriptsSerialise(entity.GetEID(), buffer.get(), BUFFER_SIZE))
|
|
|
|
{
|
|
|
|
result = std::string(buffer.get());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SHLOG_ERROR("[ScriptEngine] Failed to serialise scripts as string buffer is too small!");
|
|
|
|
}
|
|
|
|
|
|
|
|
// Return an empty string since we failed to serialise
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*---------------------------------------------------------------------------------*/
|
|
|
|
/* Script Serialisation Functions */
|
|
|
|
/*---------------------------------------------------------------------------------*/
|
2022-09-13 20:30:32 +08:00
|
|
|
void SHScriptEngine::DeserialiseScript(const SHEntity& entity, const std::string& yaml)
|
2022-09-12 16:04:22 +08:00
|
|
|
{
|
|
|
|
csScriptDeserialise(entity.GetEID(), yaml.c_str());
|
|
|
|
}
|
|
|
|
|
|
|
|
/*---------------------------------------------------------------------------------*/
|
|
|
|
/* Script Editor Functions */
|
|
|
|
/*---------------------------------------------------------------------------------*/
|
2022-09-13 20:30:32 +08:00
|
|
|
void SHScriptEngine::RenderScriptsInInspector(const SHEntity& entity)
|
2022-09-12 16:04:22 +08:00
|
|
|
{
|
|
|
|
csEditorRenderScripts(entity.GetEID());
|
|
|
|
}
|
|
|
|
|
|
|
|
/*---------------------------------------------------------------------------------*/
|
|
|
|
/* Static Utility Functions */
|
|
|
|
/*---------------------------------------------------------------------------------*/
|
|
|
|
bool SHScriptEngine::BuildScriptAssembly(bool debug)
|
|
|
|
{
|
|
|
|
constexpr std::string_view BUILD_LOG_PATH = "../Build.log";
|
|
|
|
|
|
|
|
// Prepare directory (delete useless files)
|
|
|
|
deleteFolder("net5.0");
|
|
|
|
deleteFolder("ref");
|
2022-09-14 20:26:31 +08:00
|
|
|
deleteFolder("../SHADE_Scripting");
|
2022-09-12 16:04:22 +08:00
|
|
|
deleteFolder("../obj");
|
|
|
|
|
|
|
|
// Attempt to build the assembly
|
|
|
|
std::ostringstream oss;
|
|
|
|
oss << "[ScriptEngine] Building " << (debug ? " debug " : "") << "Managed Script Assembly (" << MANAGED_SCRIPT_LIB_NAME << ")!";
|
|
|
|
SHLOG_INFO(oss.str());
|
|
|
|
oss.str("");
|
|
|
|
const bool BUILD_SUCCESS = execProcess
|
|
|
|
(
|
|
|
|
L"C:\\Windows\\system32\\cmd.exe",
|
2022-09-14 20:26:31 +08:00
|
|
|
L"/K \"dotnet build \"../SHADE_Scripting.csproj\" -c Debug -o \"./tmp/\" -fl -flp:LogFile=build.log;Verbosity=quiet & exit\""
|
2022-09-12 16:04:22 +08:00
|
|
|
) == 0;
|
|
|
|
if (BUILD_SUCCESS)
|
|
|
|
{
|
|
|
|
// Copy to built dll to the working directory and replace
|
2022-09-14 20:26:31 +08:00
|
|
|
std::filesystem::copy_file("./tmp/SHADE_Managed.dll", "SHADE_Managed.dll", std::filesystem::copy_options::overwrite_existing);
|
2022-09-12 16:04:22 +08:00
|
|
|
|
|
|
|
oss << "[ScriptEngine] Successfully built Managed Script Assembly (" << MANAGED_SCRIPT_LIB_NAME << ")!";
|
|
|
|
SHLOG_INFO(oss.str());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
oss << "[ScriptEngine] Failed to build Managed Script Assembly (" << MANAGED_SCRIPT_LIB_NAME << ")!";
|
|
|
|
SHLOG_ERROR(oss.str());
|
|
|
|
}
|
|
|
|
|
|
|
|
// Clean up built files
|
|
|
|
deleteFolder("./tmp");
|
|
|
|
|
|
|
|
// Read the build log and output to the console
|
|
|
|
dumpBuildLog(BUILD_LOG_PATH);
|
|
|
|
// Delete the build log file since we no longer need it
|
|
|
|
deleteFile(BUILD_LOG_PATH);
|
|
|
|
|
|
|
|
return BUILD_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SHScriptEngine::GenerateScriptsCsProjFile(const std::filesystem::path& path)
|
|
|
|
{
|
|
|
|
// Sample
|
|
|
|
static std::string_view FILE_CONTENTS =
|
|
|
|
"<Project Sdk=\"Microsoft.NET.Sdk\">\n\
|
|
|
|
<PropertyGroup>\n\
|
|
|
|
<TargetFramework>net5.0</TargetFramework>\n\
|
|
|
|
<Platforms>x64</Platforms>\n\
|
|
|
|
<Configurations>Release;Debug</Configurations>\n\
|
|
|
|
</PropertyGroup>\n\
|
|
|
|
<PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n\
|
|
|
|
<OutputPath>.\\bin_Release-x64</OutputPath>\n\
|
|
|
|
<PlatformTarget>x64</PlatformTarget>\n\
|
|
|
|
</PropertyGroup>\n\
|
|
|
|
<PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\"> \n\
|
|
|
|
<OutputPath>.\\bin_Debug-x64</OutputPath>\n\
|
|
|
|
<PlatformTarget>x64</PlatformTarget>\n\
|
|
|
|
<DefineConstants>DEBUG;TRACE</DefineConstants>\n\
|
|
|
|
<Optimize>false</Optimize>\n\
|
|
|
|
<DebugType>full</DebugType>\n\
|
|
|
|
<DebugSymbols>true</DebugSymbols>\n\
|
|
|
|
</PropertyGroup>\n\
|
|
|
|
<ItemGroup>\n\
|
2022-09-13 11:43:49 +08:00
|
|
|
<Compile Remove=\"bin\\**\" />\n\
|
|
|
|
<EmbeddedResource Remove=\"Assets\\**\" />\n\
|
|
|
|
<EmbeddedResource Remove=\"bin\\**\" />\n\
|
|
|
|
<None Remove=\"bin\\**\" />\n\
|
2022-09-12 16:04:22 +08:00
|
|
|
</ItemGroup>\n\
|
|
|
|
<ItemGroup>\n\
|
|
|
|
<None Remove=\".gitignore\" />\n\
|
|
|
|
<None Remove=\".gitmodules\" />\n\
|
|
|
|
</ItemGroup>\n\
|
|
|
|
<ItemGroup>\n\
|
2022-09-14 20:26:31 +08:00
|
|
|
<Reference Include=\"SHADE_Managed\">\n\
|
|
|
|
<HintPath>.\\bin\\SHADE_Managed.dll</HintPath>\n\
|
2022-09-12 16:04:22 +08:00
|
|
|
</Reference>\n\
|
|
|
|
</ItemGroup>\n\
|
|
|
|
</Project>";
|
|
|
|
|
|
|
|
// Attempt to create the file
|
|
|
|
std::ofstream file(path);
|
|
|
|
if (!file.is_open())
|
|
|
|
throw std::runtime_error("Unable to create CsProj file!");
|
|
|
|
|
|
|
|
// Fill the file
|
|
|
|
file << FILE_CONTENTS;
|
|
|
|
|
|
|
|
// Close
|
|
|
|
file.close();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*---------------------------------------------------------------------------------*/
|
|
|
|
/* Helper Functions */
|
|
|
|
/*---------------------------------------------------------------------------------*/
|
|
|
|
void SHScriptEngine::loadFunctions()
|
|
|
|
{
|
|
|
|
std::ostringstream oss;
|
|
|
|
oss << "[ScriptEngine] Loading \"" << DEFAULT_CSHARP_LIB_NAME << "\" CLR library.";
|
|
|
|
SHLOG_INFO(oss.str());
|
|
|
|
|
|
|
|
// Load functions
|
|
|
|
csEngineInit = dotNet.GetFunctionPtr<CsFuncPtr>
|
|
|
|
(
|
|
|
|
DEFAULT_CSHARP_LIB_NAME,
|
|
|
|
DEFAULT_CSHARP_NAMESPACE + ".EngineInterface",
|
|
|
|
"Init"
|
|
|
|
);
|
|
|
|
csEngineLoadScripts = dotNet.GetFunctionPtr<CsFuncPtr>
|
|
|
|
(
|
|
|
|
DEFAULT_CSHARP_LIB_NAME,
|
|
|
|
DEFAULT_CSHARP_NAMESPACE + ".EngineInterface",
|
|
|
|
"LoadScriptAssembly"
|
|
|
|
);
|
|
|
|
csEngineUnloadScripts = dotNet.GetFunctionPtr<CsFuncPtr>
|
|
|
|
(
|
|
|
|
DEFAULT_CSHARP_LIB_NAME,
|
|
|
|
DEFAULT_CSHARP_NAMESPACE + ".EngineInterface",
|
|
|
|
"UnloadScriptAssembly"
|
|
|
|
);
|
|
|
|
csEngineReloadScripts = dotNet.GetFunctionPtr<CsFuncPtr>
|
|
|
|
(
|
|
|
|
DEFAULT_CSHARP_LIB_NAME,
|
|
|
|
DEFAULT_CSHARP_NAMESPACE + ".EngineInterface",
|
|
|
|
"ReloadScriptAssembly"
|
|
|
|
);
|
|
|
|
csEngineExit = dotNet.GetFunctionPtr<CsFuncPtr>
|
|
|
|
(
|
|
|
|
DEFAULT_CSHARP_LIB_NAME,
|
|
|
|
DEFAULT_CSHARP_NAMESPACE + ".EngineInterface",
|
|
|
|
"Exit"
|
|
|
|
);
|
|
|
|
csScriptsFrameSetUp = dotNet.GetFunctionPtr<CsFuncPtr>
|
|
|
|
(
|
|
|
|
DEFAULT_CSHARP_LIB_NAME,
|
|
|
|
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
|
|
|
|
"FrameSetUp"
|
|
|
|
);
|
|
|
|
csScriptsExecuteFixedUpdate = dotNet.GetFunctionPtr<CsFuncPtr>
|
|
|
|
(
|
|
|
|
DEFAULT_CSHARP_LIB_NAME,
|
|
|
|
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
|
|
|
|
"ExecuteFixedUpdate"
|
|
|
|
);
|
|
|
|
csScriptsExecuteUpdate = dotNet.GetFunctionPtr<CsFuncPtr>
|
|
|
|
(
|
|
|
|
DEFAULT_CSHARP_LIB_NAME,
|
|
|
|
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
|
|
|
|
"ExecuteUpdate"
|
|
|
|
);
|
|
|
|
csScriptsExecuteLateUpdate = dotNet.GetFunctionPtr<CsFuncPtr>
|
|
|
|
(
|
|
|
|
DEFAULT_CSHARP_LIB_NAME,
|
|
|
|
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
|
|
|
|
"ExecuteLateUpdate"
|
|
|
|
);
|
|
|
|
csScriptsFrameCleanUp = dotNet.GetFunctionPtr<CsFuncPtr>
|
|
|
|
(
|
|
|
|
DEFAULT_CSHARP_LIB_NAME,
|
|
|
|
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
|
|
|
|
"FrameCleanUp"
|
|
|
|
);
|
|
|
|
csScriptsAdd = dotNet.GetFunctionPtr<CsScriptManipFuncPtr>
|
|
|
|
(
|
|
|
|
DEFAULT_CSHARP_LIB_NAME,
|
|
|
|
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
|
|
|
|
"AddScriptViaName"
|
|
|
|
);
|
|
|
|
csScriptsRemoveAll = dotNet.GetFunctionPtr<CsScriptBasicFuncPtr>
|
|
|
|
(
|
|
|
|
DEFAULT_CSHARP_LIB_NAME,
|
|
|
|
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
|
|
|
|
"RemoveAllScripts"
|
|
|
|
);
|
|
|
|
csScriptsRemoveAllImmediately = dotNet.GetFunctionPtr<CsScriptOptionalFuncPtr>
|
|
|
|
(
|
|
|
|
DEFAULT_CSHARP_LIB_NAME,
|
|
|
|
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
|
|
|
|
"RemoveAllScriptsImmediately"
|
|
|
|
);
|
2022-09-13 20:30:32 +08:00
|
|
|
/*csScriptsSerialise = dotNet.GetFunctionPtr<CsScriptSerialiseFuncPtr>
|
2022-09-12 16:04:22 +08:00
|
|
|
(
|
|
|
|
DEFAULT_CSHARP_LIB_NAME,
|
|
|
|
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
|
|
|
|
"SerialiseScripts"
|
|
|
|
);
|
2022-09-13 20:30:32 +08:00
|
|
|
csScriptsSerialiseYaml = dotNet.GetFunctionPtr<CsScriptSerialiseYamlFuncPtr>
|
2022-09-12 16:04:22 +08:00
|
|
|
(
|
|
|
|
DEFAULT_CSHARP_LIB_NAME,
|
|
|
|
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
|
2022-09-13 20:30:32 +08:00
|
|
|
"SerialiseScriptsYaml"
|
2022-09-12 16:04:22 +08:00
|
|
|
);
|
|
|
|
csScriptDeserialise = dotNet.GetFunctionPtr<CsScriptDeserialiseFuncPtr>
|
|
|
|
(
|
|
|
|
DEFAULT_CSHARP_LIB_NAME,
|
|
|
|
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
|
|
|
|
"DeserialiseScript"
|
|
|
|
);
|
2022-09-13 20:30:32 +08:00
|
|
|
csScriptDeserialiseYaml = dotNet.GetFunctionPtr<CsScriptSerialiseYamlFuncPtr>
|
|
|
|
(
|
|
|
|
DEFAULT_CSHARP_LIB_NAME,
|
|
|
|
DEFAULT_CSHARP_NAMESPACE + ".ScriptStore",
|
|
|
|
"SerialiseScriptsYaml"
|
|
|
|
);
|
2022-09-12 16:04:22 +08:00
|
|
|
csEditorRenderScripts = dotNet.GetFunctionPtr<CsScriptEditorFuncPtr>
|
|
|
|
(
|
|
|
|
DEFAULT_CSHARP_LIB_NAME,
|
|
|
|
DEFAULT_CSHARP_NAMESPACE + ".Editor",
|
|
|
|
"RenderScriptsInInspector"
|
2022-09-13 20:30:32 +08:00
|
|
|
);*/
|
2022-09-12 16:04:22 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void SHScriptEngine::dumpBuildLog(const std::string_view& buildLogPath)
|
|
|
|
{
|
|
|
|
std::ifstream buildLog(buildLogPath);
|
|
|
|
|
|
|
|
// Fail to open
|
|
|
|
if (!buildLog.is_open())
|
|
|
|
return;
|
|
|
|
|
|
|
|
// Process line by line
|
|
|
|
std::string line;
|
|
|
|
while (std::getline(buildLog, line))
|
|
|
|
{
|
|
|
|
if (line.find("error") != line.npos)
|
|
|
|
{
|
|
|
|
SHLOG_ERROR(line);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SHLOG_WARNING(line);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void SHScriptEngine::deleteFile(const std::string_view& filePath)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
std::filesystem::remove(std::filesystem::canonical(filePath));
|
|
|
|
}
|
|
|
|
catch (...) {} // Ignore deletion failures
|
|
|
|
}
|
|
|
|
|
|
|
|
void SHScriptEngine::deleteFolder(const std::string_view& filePath)
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
std::filesystem::remove_all(std::filesystem::canonical(filePath));
|
|
|
|
}
|
|
|
|
catch (...) {} // Ignore deletion failures
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SHScriptEngine::fileExists(const std::string_view& filePath)
|
|
|
|
{
|
|
|
|
std::error_code error;
|
|
|
|
if (std::filesystem::exists(filePath, error))
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
DWORD SHScriptEngine::execProcess(const std::wstring& path, const std::wstring& args)
|
|
|
|
{
|
|
|
|
STARTUPINFOW startInfo;
|
|
|
|
PROCESS_INFORMATION procInfo;
|
|
|
|
ZeroMemory(&startInfo, sizeof(startInfo));
|
|
|
|
ZeroMemory(&procInfo, sizeof(procInfo));
|
|
|
|
startInfo.cb = sizeof(startInfo);
|
|
|
|
|
|
|
|
std::wstring argsWstr = args;
|
|
|
|
|
|
|
|
// Start Process
|
|
|
|
const auto SUCCESS = CreateProcess
|
|
|
|
(
|
|
|
|
path.data(), argsWstr.data(),
|
|
|
|
nullptr, nullptr, false, NULL, nullptr, nullptr,
|
|
|
|
&startInfo, &procInfo
|
|
|
|
);
|
|
|
|
|
|
|
|
// Error Check
|
|
|
|
if (!SUCCESS)
|
|
|
|
{
|
|
|
|
auto err = GetLastError();
|
|
|
|
std::ostringstream oss;
|
|
|
|
oss << "[ScriptEngine] Failed to launch process. Error code: " << std::hex << err
|
|
|
|
<< " (" << SHStringUtils::GetWin32ErrorMessage(err) << ")";
|
|
|
|
throw std::runtime_error(oss.str());
|
|
|
|
}
|
|
|
|
|
|
|
|
// Wait for execution to end
|
|
|
|
DWORD status;
|
|
|
|
while (true)
|
|
|
|
{
|
|
|
|
const auto SUCCESS = GetExitCodeProcess(procInfo.hProcess, &status);
|
|
|
|
if (!SUCCESS)
|
|
|
|
{
|
|
|
|
auto err = GetLastError();
|
|
|
|
std::ostringstream oss;
|
|
|
|
oss << "[ScriptEngine] Failed to query process. Error code: " << std::hex << err
|
|
|
|
<< " (" << SHStringUtils::GetWin32ErrorMessage(err) << ")";
|
|
|
|
throw std::runtime_error(oss.str());
|
|
|
|
}
|
|
|
|
|
|
|
|
// Break only if process ends
|
|
|
|
if (status != STILL_ACTIVE)
|
|
|
|
{
|
|
|
|
CloseHandle(procInfo.hProcess);
|
|
|
|
CloseHandle(procInfo.hThread);
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|