Merge pull request #299 from SHADE-DP/SP3-6-c-scripting
Added scripting quality of life features
This commit is contained in:
commit
a6a0e1588b
|
@ -20,10 +20,11 @@ echo "M - SDL"
|
||||||
echo "N - dotnet"
|
echo "N - dotnet"
|
||||||
echo "O - tinyddsloader"
|
echo "O - tinyddsloader"
|
||||||
echo "P - fmod"
|
echo "P - fmod"
|
||||||
|
echo "Q - vswhere"
|
||||||
echo ---------------------------------------------------
|
echo ---------------------------------------------------
|
||||||
echo.
|
echo.
|
||||||
|
|
||||||
choice /C ABCDEFGHIJKLMNOP /T 10 /D A
|
choice /C ABCDEFGHIJKLMNOPQ /T 10 /D A
|
||||||
set _e=%ERRORLEVEL%
|
set _e=%ERRORLEVEL%
|
||||||
|
|
||||||
if %_e%==1 goto VMA
|
if %_e%==1 goto VMA
|
||||||
|
@ -42,6 +43,7 @@ if %_e%==13 goto SDL
|
||||||
if %_e%==14 goto dotnet
|
if %_e%==14 goto dotnet
|
||||||
if %_e%==15 goto tinyddsloader
|
if %_e%==15 goto tinyddsloader
|
||||||
if %_e%==16 goto fmod
|
if %_e%==16 goto fmod
|
||||||
|
if %_e%==17 goto vswhere
|
||||||
|
|
||||||
:VMA
|
:VMA
|
||||||
echo -----------------------VMA----------------------------
|
echo -----------------------VMA----------------------------
|
||||||
|
@ -155,6 +157,13 @@ if %_e%==15 (goto :done) else (goto :fmod)
|
||||||
echo --------------------fmod-------------------------
|
echo --------------------fmod-------------------------
|
||||||
rmdir "Dependencies/fmod" /S /Q
|
rmdir "Dependencies/fmod" /S /Q
|
||||||
git clone https://github.com/SHADE-DP/FMOD.git "Dependencies/fmod"
|
git clone https://github.com/SHADE-DP/FMOD.git "Dependencies/fmod"
|
||||||
|
if %_e%==16 (goto :done) else (goto :vswhere)
|
||||||
|
|
||||||
|
:vswhere
|
||||||
|
echo -----------------------vswhere----------------------------
|
||||||
|
rmdir "Dependencies/vswhere" /S /Q
|
||||||
|
mkdir "Dependencies/vswhere"
|
||||||
|
powershell -Command "& {wget https://github.com/microsoft/vswhere/releases/download/3.1.1/vswhere.exe -OutFile "Dependencies/vswhere/vswhere.exe"}"
|
||||||
|
|
||||||
:done
|
:done
|
||||||
echo DONE!
|
echo DONE!
|
||||||
|
|
|
@ -17,3 +17,4 @@ IncludeDir["VULKAN"] = "$(VULKAN_SDK)"
|
||||||
IncludeDir["dotnet"] = "%{wks.location}\\Dependencies\\dotnet"
|
IncludeDir["dotnet"] = "%{wks.location}\\Dependencies\\dotnet"
|
||||||
IncludeDir["tinyddsloader"] = "%{wks.location}\\Dependencies\\tinyddsloader"
|
IncludeDir["tinyddsloader"] = "%{wks.location}\\Dependencies\\tinyddsloader"
|
||||||
IncludeDir["fmod"] = "%{wks.location}\\Dependencies\\fmod"
|
IncludeDir["fmod"] = "%{wks.location}\\Dependencies\\fmod"
|
||||||
|
IncludeDir["vswhere"] = "%{wks.location}\\Dependencies\\vswhere"
|
|
@ -124,7 +124,8 @@ project "SHADE_Engine"
|
||||||
"xcopy /r /y /q \"%{IncludeDir.ModelCompiler}\\bin\\Debug\\ModelCompiler.exe\" \"$(OutDir)\"",
|
"xcopy /r /y /q \"%{IncludeDir.ModelCompiler}\\bin\\Debug\\ModelCompiler.exe\" \"$(OutDir)\"",
|
||||||
"xcopy /r /y /q \"%{IncludeDir.FontCompiler}\\bin\\Debug\\FontCompiler.exe\" \"$(OutDir)\"",
|
"xcopy /r /y /q \"%{IncludeDir.FontCompiler}\\bin\\Debug\\FontCompiler.exe\" \"$(OutDir)\"",
|
||||||
"xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmodL.dll\" \"$(OutDir)\"",
|
"xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmodL.dll\" \"$(OutDir)\"",
|
||||||
"xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmodstudioL.dll\" \"$(OutDir)\""
|
"xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmodstudioL.dll\" \"$(OutDir)\"",
|
||||||
|
"xcopy /r /y /q \"%{IncludeDir.vswhere}\\vswhere.exe\" \"$(OutDir)\""
|
||||||
}
|
}
|
||||||
|
|
||||||
filter "configurations:Release"
|
filter "configurations:Release"
|
||||||
|
@ -134,7 +135,8 @@ project "SHADE_Engine"
|
||||||
"xcopy /r /y /q \"%{IncludeDir.ModelCompiler}\\bin\\Release\\ModelCompiler.exe\" \"$(OutDir)\"",
|
"xcopy /r /y /q \"%{IncludeDir.ModelCompiler}\\bin\\Release\\ModelCompiler.exe\" \"$(OutDir)\"",
|
||||||
"xcopy /r /y /q \"%{IncludeDir.FontCompiler}\\bin\\Release\\FontCompiler.exe\" \"$(OutDir)\"",
|
"xcopy /r /y /q \"%{IncludeDir.FontCompiler}\\bin\\Release\\FontCompiler.exe\" \"$(OutDir)\"",
|
||||||
"xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmod.dll\" \"$(OutDir)\"",
|
"xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmod.dll\" \"$(OutDir)\"",
|
||||||
"xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmodstudio.dll\" \"$(OutDir)\""
|
"xcopy /r /y /q \"%{IncludeDir.fmod}\\lib\\fmodstudio.dll\" \"$(OutDir)\"",
|
||||||
|
"xcopy /r /y /q \"%{IncludeDir.vswhere}\\vswhere.exe\" \"$(OutDir)\""
|
||||||
}
|
}
|
||||||
|
|
||||||
filter "configurations:Publish"
|
filter "configurations:Publish"
|
||||||
|
|
|
@ -14,6 +14,8 @@
|
||||||
#include "Editor/DragDrop/SHDragDrop.hpp"
|
#include "Editor/DragDrop/SHDragDrop.hpp"
|
||||||
#include "Editor/EditorWindow/MaterialInspector/SHMaterialInspector.h"
|
#include "Editor/EditorWindow/MaterialInspector/SHMaterialInspector.h"
|
||||||
#include "Editor/EditorWindow/SHEditorWindowManager.h"
|
#include "Editor/EditorWindow/SHEditorWindowManager.h"
|
||||||
|
#include "Scripting/SHVSUtilities.h"
|
||||||
|
#include "Scripting/SHScriptEngine.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -249,6 +251,12 @@ namespace SHADE
|
||||||
matInspector->OpenMaterial(asset->id);
|
matInspector->OpenMaterial(asset->id);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case AssetType::SCRIPT:
|
||||||
|
if(auto scriptEngine = SHSystemManager::GetSystem<SHScriptEngine>())
|
||||||
|
{
|
||||||
|
scriptEngine->OpenFile(asset->path);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case AssetType::MAX_COUNT: break;
|
case AssetType::MAX_COUNT: break;
|
||||||
default:;
|
default:;
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,6 +120,11 @@ namespace SHADE
|
||||||
auto* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
|
auto* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
|
||||||
scriptEngine->GenerateScriptsCsProjFile();
|
scriptEngine->GenerateScriptsCsProjFile();
|
||||||
}
|
}
|
||||||
|
if (ImGui::Selectable("Open Visual Studio Project"))
|
||||||
|
{
|
||||||
|
auto* scriptEngine = static_cast<SHScriptEngine*>(SHSystemManager::GetSystem<SHScriptEngine>());
|
||||||
|
scriptEngine->OpenSolution();
|
||||||
|
}
|
||||||
ImGui::BeginDisabled(SHSystemManager::GetSystem<SHEditor>()->editorState != SHEditor::State::STOP);
|
ImGui::BeginDisabled(SHSystemManager::GetSystem<SHEditor>()->editorState != SHEditor::State::STOP);
|
||||||
if (ImGui::Selectable("Build Scripts - Debug"))
|
if (ImGui::Selectable("Build Scripts - Debug"))
|
||||||
{
|
{
|
||||||
|
|
|
@ -28,8 +28,9 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
#include "Physics/System/SHPhysicsSystem.h"
|
#include "Physics/System/SHPhysicsSystem.h"
|
||||||
#include "Physics/SHPhysicsEvents.h"
|
#include "Physics/SHPhysicsEvents.h"
|
||||||
#include "Scene/SHSceneEvents.h"
|
#include "Scene/SHSceneEvents.h"
|
||||||
|
|
||||||
#include "Assets/SHAssetMacros.h"
|
#include "Assets/SHAssetMacros.h"
|
||||||
|
#include "Tools/Utilities/SHExecUtilities.h"
|
||||||
|
#include "SHVSUtilities.h"
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
|
@ -189,12 +190,9 @@ namespace SHADE
|
||||||
oss << "[ScriptEngine] Building " << (debug ? " debug " : "") << "Managed Script Assembly (" << MANAGED_SCRIPT_LIB_NAME << ")!";
|
oss << "[ScriptEngine] Building " << (debug ? " debug " : "") << "Managed Script Assembly (" << MANAGED_SCRIPT_LIB_NAME << ")!";
|
||||||
SHLOG_INFO(oss.str());
|
SHLOG_INFO(oss.str());
|
||||||
oss.str("");
|
oss.str("");
|
||||||
const bool BUILD_SUCCESS = execProcess
|
const auto BUILD_SUCCESS = SHExecUtilties::ExecBlockingProcess(L"C:\\Program Files\\dotnet\\dotnet.exe", generateBuildCommand(debug), false, false);
|
||||||
(
|
SHLOG_WARNING("Build Output: {}", SHStringUtilities::WstrToStr(BUILD_SUCCESS.StdOutput));
|
||||||
L"C:\\Windows\\system32\\cmd.exe",
|
if (BUILD_SUCCESS.Code == 0)
|
||||||
L"/K \"" + generateBuildCommand(debug) + L" & exit\""
|
|
||||||
) == 0;
|
|
||||||
if (BUILD_SUCCESS)
|
|
||||||
{
|
{
|
||||||
// Copy to built dll to the working directory and replace
|
// Copy to built dll to the working directory and replace
|
||||||
if (!copyFile("./tmp/SHADE_Scripting.dll", "SHADE_Scripting.dll", std::filesystem::copy_options::overwrite_existing))
|
if (!copyFile("./tmp/SHADE_Scripting.dll", "SHADE_Scripting.dll", std::filesystem::copy_options::overwrite_existing))
|
||||||
|
@ -238,7 +236,7 @@ namespace SHADE
|
||||||
LoadScriptAssembly();
|
LoadScriptAssembly();
|
||||||
}
|
}
|
||||||
|
|
||||||
return BUILD_SUCCESS;
|
return BUILD_SUCCESS.Code == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SHScriptEngine::GenerateScriptsCsProjFile(const std::filesystem::path& path) const
|
void SHScriptEngine::GenerateScriptsCsProjFile(const std::filesystem::path& path) const
|
||||||
|
@ -306,6 +304,16 @@ namespace SHADE
|
||||||
file.close();
|
file.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SHScriptEngine::OpenSolution()
|
||||||
|
{
|
||||||
|
SHVSUtilties::OpenProject(CSPROJ_PATH);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHScriptEngine::OpenFile(const std::filesystem::path& path)
|
||||||
|
{
|
||||||
|
SHVSUtilties::OpenFile(CSPROJ_PATH, path);
|
||||||
|
}
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* Event Handler Functions */
|
/* Event Handler Functions */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
@ -610,64 +618,12 @@ namespace SHADE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
|
||||||
<< " (" << SHStringUtilities::GetWin32ErrorMessage(err) << ")";
|
|
||||||
throw std::runtime_error(oss.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wait for execution to end
|
|
||||||
DWORD status;
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
const auto EXEC_SUCCESS = GetExitCodeProcess(procInfo.hProcess, &status);
|
|
||||||
if (!EXEC_SUCCESS)
|
|
||||||
{
|
|
||||||
auto err = GetLastError();
|
|
||||||
std::ostringstream oss;
|
|
||||||
oss << "[ScriptEngine] Failed to query process. Error code: " << std::hex << err
|
|
||||||
<< " (" << SHStringUtilities::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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::wstring SHScriptEngine::generateBuildCommand(bool debug)
|
std::wstring SHScriptEngine::generateBuildCommand(bool debug)
|
||||||
{
|
{
|
||||||
std::wostringstream oss;
|
std::wostringstream oss;
|
||||||
oss << "dotnet build \"" << SHStringUtilities::StrToWstr(CSPROJ_PATH) << "\" -c ";
|
oss << " build \"" << SHStringUtilities::StrToWstr(std::filesystem::absolute(CSPROJ_PATH).string()) << "\" -c ";
|
||||||
oss << debug ? "Debug" : "Release";
|
oss << debug ? "Debug" : "Release";
|
||||||
oss << " -o \"./tmp/\" -fl -flp:LogFile=build.log;Verbosity=quiet -r \"win-x64\"";
|
oss << " -o \"./tmp/\" -r \"win-x64\"";
|
||||||
return oss.str();
|
return oss.str();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/************************************************************************************//*!
|
/************************************************************************************//*!
|
||||||
\file ScriptEngine.h
|
\file SHScriptEngine.h
|
||||||
\author Tng Kah Wei, kahwei.tng, 390009620
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
\par email: kahwei.tng\@digipen.edu
|
\par email: kahwei.tng\@digipen.edu
|
||||||
\date Sep 17, 2021
|
\date Sep 17, 2021
|
||||||
|
@ -217,6 +217,15 @@ namespace SHADE
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="path">File path to the generated file.</param>
|
/// <param name="path">File path to the generated file.</param>
|
||||||
void GenerateScriptsCsProjFile(const std::filesystem::path& path = CSPROJ_PATH) const;
|
void GenerateScriptsCsProjFile(const std::filesystem::path& path = CSPROJ_PATH) const;
|
||||||
|
/// <summary>
|
||||||
|
/// Opens the script solution in Visual Studio.
|
||||||
|
/// </summary>
|
||||||
|
void OpenSolution();
|
||||||
|
/// <summary>
|
||||||
|
/// Opens the file in Visual Studio.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path"></param>
|
||||||
|
void OpenFile(const std::filesystem::path& path);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
|
@ -320,7 +329,6 @@ namespace SHADE
|
||||||
/// <returns> True if the file exists </returns>
|
/// <returns> True if the file exists </returns>
|
||||||
static bool fileExists(const std::filesystem::path& filePath);
|
static bool fileExists(const std::filesystem::path& filePath);
|
||||||
static bool copyFile(const std::filesystem::path& from, const std::filesystem::path& to, const std::filesystem::copy_options options) noexcept;
|
static bool copyFile(const std::filesystem::path& from, const std::filesystem::path& to, const std::filesystem::copy_options options) noexcept;
|
||||||
static DWORD execProcess(const std::wstring& path, const std::wstring& args);
|
|
||||||
static std::wstring generateBuildCommand(bool debug);
|
static std::wstring generateBuildCommand(bool debug);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,127 @@
|
||||||
|
/************************************************************************************//*!
|
||||||
|
\file SHVSUtilities.cpp
|
||||||
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
|
\par email: kahwei.tng\@digipen.edu
|
||||||
|
\date Dec 21, 2022
|
||||||
|
\brief Contains the implementation for SHVSUtilities static class.
|
||||||
|
|
||||||
|
Copyright (C) 2022 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 "SHVSUtilities.h"
|
||||||
|
// Project Headers
|
||||||
|
#include "Tools/Utilities/SHExecUtilities.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Static Data Members */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
std::filesystem::path SHVSUtilties::devEnvPath;
|
||||||
|
HANDLE SHVSUtilties::devEnvInst = nullptr;
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Usage Functions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
void SHVSUtilties::OpenProject(const std::filesystem::path& projPath)
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Check if there is an instance
|
||||||
|
bool devEnvActive = false;
|
||||||
|
if (devEnvInst)
|
||||||
|
{
|
||||||
|
|
||||||
|
DWORD status;
|
||||||
|
const auto GET_CODE_STATUS = GetExitCodeProcess(devEnvInst, &status);
|
||||||
|
devEnvActive = GET_CODE_STATUS && status == STILL_ACTIVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reuse the existing instance if there is one
|
||||||
|
if (devEnvActive)
|
||||||
|
{
|
||||||
|
// No need to reopen one
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (devEnvPath.empty())
|
||||||
|
{
|
||||||
|
devEnvPath = SHVSUtilties::getDevEnvPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto absProjPath = std::filesystem::canonical(projPath);
|
||||||
|
auto pi = SHExecUtilties::ExecProcess(devEnvPath.generic_wstring(), L" " + absProjPath.generic_wstring());
|
||||||
|
// Cache the process handle
|
||||||
|
devEnvInst = pi.hProcess;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (std::exception& e)
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("{}", e.what());
|
||||||
|
SHLOG_ERROR("[SHVSUtilities] Failed to launch Visual Studio.");
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHVSUtilties::OpenFile(const std::filesystem::path& projPath, const std::filesystem::path& path)
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Check if there is an instance
|
||||||
|
bool devEnvActive = false;
|
||||||
|
if (devEnvInst)
|
||||||
|
{
|
||||||
|
|
||||||
|
DWORD status;
|
||||||
|
const auto GET_CODE_STATUS = GetExitCodeProcess(devEnvInst, &status);
|
||||||
|
devEnvActive = GET_CODE_STATUS && status == STILL_ACTIVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto absPath = std::filesystem::canonical(path);
|
||||||
|
|
||||||
|
// Reuse the existing instance if there is one
|
||||||
|
if (devEnvActive)
|
||||||
|
{
|
||||||
|
// Edit the file only
|
||||||
|
SHExecUtilties::ExecProcess(devEnvPath.generic_wstring(), L" /Edit " + absPath.generic_wstring());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (devEnvPath.empty())
|
||||||
|
{
|
||||||
|
devEnvPath = SHVSUtilties::getDevEnvPath();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto absProjPath = std::filesystem::canonical(projPath);
|
||||||
|
auto pi = SHExecUtilties::ExecProcess(devEnvPath.generic_wstring(), absProjPath.generic_wstring() + L" " + absPath.generic_wstring());
|
||||||
|
// Cache the process handle
|
||||||
|
devEnvInst = pi.hProcess;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (std::exception& e)
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("{}", e.what());
|
||||||
|
SHLOG_ERROR("[SHVSUtilities] Failed to launch Visual Studio.");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Helper Functions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
std::filesystem::path SHVSUtilties::getDevEnvPath()
|
||||||
|
{
|
||||||
|
#ifdef _PUBLISH
|
||||||
|
return {}; // Don't do anything if it's a published build
|
||||||
|
#else
|
||||||
|
static constexpr int EXCESS_CHARS_COUNT = 2;
|
||||||
|
|
||||||
|
const auto RESULT = SHExecUtilties::ExecBlockingPowerShellCommand(L"./vswhere -version \"[15.0,19.0]\" -requires Microsoft.NetCore.Component.DevelopmentTools -find Common7\\\\IDE\\\\devenv.exe | Select-Object -first 1", true, true);
|
||||||
|
if (RESULT.StdOutput.size() < EXCESS_CHARS_COUNT)
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("[SHVSUtilities] Unable to get path to Visual Studio installation. SHVSUtilities will not work.");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
return RESULT.StdOutput.substr(0, RESULT.StdOutput.size() - EXCESS_CHARS_COUNT);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
/************************************************************************************//*!
|
||||||
|
\file SHVSUtilties.h
|
||||||
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
|
\par email: kahwei.tng\@digipen.edu
|
||||||
|
\date Dec 21, 2022
|
||||||
|
\brief Contains the interface for SHVSUtilties class.
|
||||||
|
|
||||||
|
Copyright (C) 2022 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.
|
||||||
|
*//*************************************************************************************/
|
||||||
|
|
||||||
|
// STL Includes
|
||||||
|
#include <filesystem>
|
||||||
|
// External Dependencies
|
||||||
|
#include <Windows.h>
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Static class containing functions for working with Visual Studio installation and
|
||||||
|
/// running instances.
|
||||||
|
/// </summary>
|
||||||
|
class SH_API SHVSUtilties final
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Usage Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/// <summary>
|
||||||
|
/// Opens the project at the specified path with a new or existing instance of Visual
|
||||||
|
/// Studio if it exists.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="projPath">Path to the project file to open.</param>
|
||||||
|
static void OpenProject(const std::filesystem::path& projPath);
|
||||||
|
/// <summary>
|
||||||
|
/// Opens the file at the specified path with a new or existing instance of Visual
|
||||||
|
/// Studio if it exists.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="projPath">Path to the project file to open.</param>
|
||||||
|
/// <param name="path">Path to the file to open.</param>
|
||||||
|
static void OpenFile(const std::filesystem::path& projPath, const std::filesystem::path& path);
|
||||||
|
|
||||||
|
private:
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Constructors/Destructors */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
SHVSUtilties() = delete;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Static Data Members */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
static std::filesystem::path devEnvPath;
|
||||||
|
static HANDLE devEnvInst;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Helper Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
static std::filesystem::path getDevEnvPath();
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,215 @@
|
||||||
|
/************************************************************************************//*!
|
||||||
|
\file SHExecUtilities.cpp
|
||||||
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
|
\par email: kahwei.tng\@digipen.edu
|
||||||
|
\date Dec 21, 2022
|
||||||
|
\brief Contains the implementation for SHExecUtilities static class.
|
||||||
|
|
||||||
|
Copyright (C) 2022 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 "SHExecUtilities.h"
|
||||||
|
// Project Includes
|
||||||
|
#include "SHStringUtilities.h"
|
||||||
|
#include "SHFileUtilties.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Process Execution Functions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
PROCESS_INFORMATION SHExecUtilties::ExecProcess(const std::wstring& path, const std::wstring& args)
|
||||||
|
{
|
||||||
|
return execProcess(path, args, nullptr, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
ExecResult SHExecUtilties::ExecBlockingProcess(const std::wstring& path, const std::wstring& args, bool output, bool errorOutput)
|
||||||
|
{
|
||||||
|
// Create pipes for stdout and stderr if specified
|
||||||
|
HANDLE stdoutReadPipe = nullptr;
|
||||||
|
HANDLE stdoutWritePipe = nullptr;
|
||||||
|
HANDLE stderrReadPipe = nullptr;
|
||||||
|
HANDLE stderrWritePipe = nullptr;
|
||||||
|
if (output)
|
||||||
|
{
|
||||||
|
std::tie(stdoutReadPipe, stdoutWritePipe) = createIoPipes();
|
||||||
|
}
|
||||||
|
if (errorOutput)
|
||||||
|
{
|
||||||
|
std::tie(stderrReadPipe, stderrWritePipe) = createIoPipes();
|
||||||
|
}
|
||||||
|
|
||||||
|
PROCESS_INFORMATION procInfo = execProcess(path, args, stdoutWritePipe, stderrWritePipe);
|
||||||
|
|
||||||
|
// Wait for execution to end
|
||||||
|
ExecResult result;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
const auto EXEC_SUCCESS = GetExitCodeProcess(procInfo.hProcess, &result.Code);
|
||||||
|
if (!EXEC_SUCCESS)
|
||||||
|
{
|
||||||
|
auto err = GetLastError();
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << "[SHExecUtilties] Failed to query process. Error code: " << std::hex << err
|
||||||
|
<< " (" << SHStringUtilities::GetWin32ErrorMessage(err) << ")";
|
||||||
|
throw std::runtime_error(oss.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Break only if process ends
|
||||||
|
if (result.Code != STILL_ACTIVE)
|
||||||
|
{
|
||||||
|
// Get stdout/stderror output
|
||||||
|
if (stdoutReadPipe)
|
||||||
|
{
|
||||||
|
readPipeData(stdoutReadPipe, stdoutWritePipe, result.StdOutput);
|
||||||
|
}
|
||||||
|
if (stderrReadPipe)
|
||||||
|
{
|
||||||
|
readPipeData(stderrReadPipe, stderrWritePipe, result.StdErrOutput);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close the process and threads for that process
|
||||||
|
CloseHandle(procInfo.hProcess);
|
||||||
|
CloseHandle(procInfo.hThread);
|
||||||
|
|
||||||
|
// Return results
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
/* Command Execution Functions */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
PROCESS_INFORMATION SHExecUtilties::ExecCommand(const std::wstring& command)
|
||||||
|
{
|
||||||
|
return ExecProcess
|
||||||
|
(
|
||||||
|
L"C:\\Windows\\system32\\cmd.exe",
|
||||||
|
L"/K \"" + command + L" & exit\""
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
ExecResult SHExecUtilties::ExecBlockingCommand(const std::wstring& command, bool output, bool errorOutput)
|
||||||
|
{
|
||||||
|
return ExecBlockingProcess
|
||||||
|
(
|
||||||
|
L"C:\\Windows\\system32\\cmd.exe",
|
||||||
|
L"/K \"" + command + L" & exit\"",
|
||||||
|
output,
|
||||||
|
errorOutput
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
PROCESS_INFORMATION SHExecUtilties::ExecPowerShellCommand(const std::wstring& command)
|
||||||
|
{
|
||||||
|
return ExecProcess
|
||||||
|
(
|
||||||
|
L"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
|
||||||
|
L"-Command \"& {" + command + L"} \""
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
ExecResult SHExecUtilties::ExecBlockingPowerShellCommand(const std::wstring& command, bool output, bool errorOutput)
|
||||||
|
{
|
||||||
|
return ExecBlockingProcess
|
||||||
|
(
|
||||||
|
L"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
|
||||||
|
L"-Command \"& { cd \"" + SHFileUtilities::GetExecDir().generic_wstring() + L"\";" + command + L"} \"",
|
||||||
|
output,
|
||||||
|
errorOutput
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
PROCESS_INFORMATION SHExecUtilties::execProcess(const std::wstring& path, const std::wstring& args, HANDLE outputWritePipe, HANDLE errorOutputWritePipe)
|
||||||
|
{
|
||||||
|
STARTUPINFOW startInfo;
|
||||||
|
PROCESS_INFORMATION procInfo;
|
||||||
|
ZeroMemory(&startInfo, sizeof(startInfo));
|
||||||
|
ZeroMemory(&procInfo, sizeof(procInfo));
|
||||||
|
startInfo.cb = sizeof(startInfo);
|
||||||
|
if (outputWritePipe)
|
||||||
|
{
|
||||||
|
startInfo.hStdOutput = outputWritePipe;
|
||||||
|
startInfo.dwFlags |= STARTF_USESTDHANDLES;
|
||||||
|
startInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
|
||||||
|
}
|
||||||
|
if (errorOutputWritePipe)
|
||||||
|
{
|
||||||
|
startInfo.hStdError = errorOutputWritePipe;
|
||||||
|
startInfo.dwFlags |= STARTF_USESTDHANDLES;
|
||||||
|
startInfo.hStdInput = GetStdHandle(STD_INPUT_HANDLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::wstring argsWstr = args;
|
||||||
|
|
||||||
|
// Start Process
|
||||||
|
const auto SUCCESS = CreateProcess
|
||||||
|
(
|
||||||
|
path.data(), argsWstr.data(),
|
||||||
|
nullptr, nullptr, true, NULL, nullptr, nullptr,
|
||||||
|
&startInfo, &procInfo
|
||||||
|
);
|
||||||
|
|
||||||
|
// Error Check
|
||||||
|
if (!SUCCESS)
|
||||||
|
{
|
||||||
|
auto err = GetLastError();
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << "[SHExecUtilties] Failed to launch process. Error code: " << std::hex << err
|
||||||
|
<< " (" << SHStringUtilities::GetWin32ErrorMessage(err) << ")";
|
||||||
|
throw std::runtime_error(oss.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
return procInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<HANDLE, HANDLE> SHExecUtilties::createIoPipes()
|
||||||
|
{
|
||||||
|
SECURITY_ATTRIBUTES saAttr;
|
||||||
|
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||||
|
saAttr.bInheritHandle = true;
|
||||||
|
saAttr.lpSecurityDescriptor = nullptr;
|
||||||
|
|
||||||
|
// First: Read | Second: Write
|
||||||
|
std::pair<HANDLE, HANDLE> output = { nullptr, nullptr };
|
||||||
|
if (CreatePipe(&output.first, &output.second, &saAttr, 0))
|
||||||
|
{
|
||||||
|
if (!SetHandleInformation(output.first, HANDLE_FLAG_INHERIT, 0))
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("[SHExecUtilities] Failed to initialize pipe for process IO.");
|
||||||
|
CloseHandle(output.first);
|
||||||
|
CloseHandle(output.second);
|
||||||
|
output = { nullptr, nullptr };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SHLOG_ERROR("[SHExecUtilities] Failed to create pipe for process IO.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SHExecUtilties::readPipeData(HANDLE readPipe, HANDLE writePipe, std::wstring& output)
|
||||||
|
{
|
||||||
|
CloseHandle(writePipe);
|
||||||
|
|
||||||
|
LARGE_INTEGER stdoutSize = {};
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
std::array<char, 256> buffer{};
|
||||||
|
DWORD bytesRead = 0;
|
||||||
|
const auto RESULT = ReadFile(readPipe, buffer.data(), buffer.size(), &bytesRead, nullptr);
|
||||||
|
if (!RESULT || bytesRead <= 0)
|
||||||
|
break;
|
||||||
|
output.insert(output.end(), buffer.data(), buffer.data() + bytesRead);
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseHandle(readPipe);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,142 @@
|
||||||
|
/************************************************************************************//*!
|
||||||
|
\file SHExecUtilties.h
|
||||||
|
\author Tng Kah Wei, kahwei.tng, 390009620
|
||||||
|
\par email: kahwei.tng\@digipen.edu
|
||||||
|
\date Dec 21, 2022
|
||||||
|
\brief Contains the interface for SHExecUtilities class.
|
||||||
|
|
||||||
|
Copyright (C) 2022 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.
|
||||||
|
*//*************************************************************************************/
|
||||||
|
|
||||||
|
// STL Includes
|
||||||
|
#include <string>
|
||||||
|
// External Dependencies
|
||||||
|
#include <Windows.h>
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Stores the result of an execution of a process.
|
||||||
|
/// </summary>
|
||||||
|
struct SH_API ExecResult final
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Exit code of the process.
|
||||||
|
/// </summary>
|
||||||
|
DWORD Code;
|
||||||
|
/// <summary>
|
||||||
|
/// Stored text output from the process.
|
||||||
|
/// </summary>
|
||||||
|
std::wstring StdOutput;
|
||||||
|
/// <summary>
|
||||||
|
/// Stored error text output from the process.
|
||||||
|
/// </summary>
|
||||||
|
std::wstring StdErrOutput;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Static class containing functions for executing external processes or commands.
|
||||||
|
/// </summary>
|
||||||
|
class SH_API SHExecUtilties final
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Process Execution Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/// <summary>
|
||||||
|
/// Executes a process at the specified path with the specified arguments. This call
|
||||||
|
/// does not wait for the process to finish executing.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">Path to the processs to start.</param>
|
||||||
|
/// <param name="args">Arguments to pass to the process.</param>
|
||||||
|
/// <returns>Information about the started process.</returns>
|
||||||
|
/// <exception cref="std::runtime_error">
|
||||||
|
/// Thrown if failed to start the process.
|
||||||
|
/// </exception>
|
||||||
|
static PROCESS_INFORMATION ExecProcess(const std::wstring& path, const std::wstring& args);
|
||||||
|
/// <summary>
|
||||||
|
/// Executes a process at the specified path with the specified arguments and waits
|
||||||
|
/// for that process to finish executing.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">Path to the processs to start.</param>
|
||||||
|
/// <param name="args">Arguments to pass to the process.</param>
|
||||||
|
/// <param name="output">If true, stdout will be routed to return.</param>
|
||||||
|
/// <param name="errorOutput">If true, outstderr will be routed to return.</param>
|
||||||
|
/// <returns>Information about the process's execution.</returns>
|
||||||
|
/// <exception cref="std::runtime_error">
|
||||||
|
/// Thrown if failed to start the process.
|
||||||
|
/// </exception>
|
||||||
|
static ExecResult ExecBlockingProcess(const std::wstring& path, const std::wstring& args, bool output = false, bool errorOutput = false);
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Command Execution Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/// <summary>
|
||||||
|
/// Executes a specified command in cmd.
|
||||||
|
/// This call does not wait for the command to finish executing.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="command">Command to execute.</param>
|
||||||
|
/// <returns>
|
||||||
|
/// Information about the started cmd process that executes the command.
|
||||||
|
/// </returns>
|
||||||
|
/// <exception cref="std::runtime_error">
|
||||||
|
/// Thrown if failed to start the process.
|
||||||
|
/// </exception>
|
||||||
|
static PROCESS_INFORMATION ExecCommand(const std::wstring& command);
|
||||||
|
/// <summary>
|
||||||
|
/// Executes a specified command in cmd and waits for that process to finish
|
||||||
|
/// executing.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="command">Command to execute.</param>
|
||||||
|
/// <param name="output">If true, stdout will be routed to return.</param>
|
||||||
|
/// <param name="errorOutput">If true, outstderr will be routed to return.</param>
|
||||||
|
/// <returns>Information about the process's execution.</returns>
|
||||||
|
/// <exception cref="std::runtime_error">
|
||||||
|
/// Thrown if failed to start the process.
|
||||||
|
/// </exception>
|
||||||
|
static ExecResult ExecBlockingCommand(const std::wstring& command, bool output = false, bool errorOutput = false);
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* PowerShell Execution Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/// <summary>
|
||||||
|
/// Executes a specified command in PowerShell.
|
||||||
|
/// This call does not wait for the command to finish executing.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="command">Command to execute.</param>
|
||||||
|
/// <returns>
|
||||||
|
/// Information about the started cmd process that executes the command.
|
||||||
|
/// </returns>
|
||||||
|
/// <exception cref="std::runtime_error">
|
||||||
|
/// Thrown if failed to start the process.
|
||||||
|
/// </exception>
|
||||||
|
static PROCESS_INFORMATION ExecPowerShellCommand(const std::wstring& command);
|
||||||
|
/// <summary>
|
||||||
|
/// Executes a specified command in PowerShell and waits for that process to finish
|
||||||
|
/// executing.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="command">Command to execute.</param>
|
||||||
|
/// <param name="output">If true, stdout will be routed to return.</param>
|
||||||
|
/// <param name="errorOutput">If true, outstderr will be routed to return.</param>
|
||||||
|
/// <returns>Information about the process's execution.</returns>
|
||||||
|
/// <exception cref="std::runtime_error">
|
||||||
|
/// Thrown if failed to start the process.
|
||||||
|
/// </exception>
|
||||||
|
static ExecResult ExecBlockingPowerShellCommand(const std::wstring& command, bool output, bool errorOutput);
|
||||||
|
|
||||||
|
private:
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Constructors/Destructors */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
SHExecUtilties() = delete;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Helper Functions */
|
||||||
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
static PROCESS_INFORMATION execProcess(const std::wstring& path, const std::wstring& args, HANDLE outputWritePipe, HANDLE errorOutputWritePipe);
|
||||||
|
static std::pair<HANDLE, HANDLE> createIoPipes();
|
||||||
|
static void readPipeData(HANDLE readPipe, HANDLE writePipe, std::wstring& output);
|
||||||
|
};
|
||||||
|
}
|
|
@ -22,9 +22,21 @@ namespace SHADE
|
||||||
{
|
{
|
||||||
void SHFileUtilities::SetWorkDirToExecDir()
|
void SHFileUtilities::SetWorkDirToExecDir()
|
||||||
{
|
{
|
||||||
TCHAR currentExecFilePath[MAX_PATH] = { '\0' };
|
std::filesystem::current_path(GetExecDir());
|
||||||
GetModuleFileName(nullptr, currentExecFilePath, MAX_PATH);
|
}
|
||||||
PathRemoveFileSpec(currentExecFilePath);
|
|
||||||
std::filesystem::current_path(currentExecFilePath);
|
std::filesystem::path SHFileUtilities::GetExecDir()
|
||||||
|
{
|
||||||
|
TCHAR currentExecFilePath[MAX_PATH] = { '\0' };
|
||||||
|
GetModuleFileName(nullptr, currentExecFilePath, MAX_PATH);
|
||||||
|
PathRemoveFileSpec(currentExecFilePath);
|
||||||
|
return std::filesystem::path(currentExecFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::filesystem::path SHFileUtilities::GetExecPath()
|
||||||
|
{
|
||||||
|
TCHAR currentExecFilePath[MAX_PATH] = { '\0' };
|
||||||
|
GetModuleFileName(nullptr, currentExecFilePath, MAX_PATH);
|
||||||
|
return std::filesystem::path(currentExecFilePath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,24 +15,29 @@ of DigiPen Institute of Technology is prohibited.
|
||||||
|
|
||||||
namespace SHADE
|
namespace SHADE
|
||||||
{
|
{
|
||||||
/*!************************************************************************************
|
/// <summary>
|
||||||
|
/// Static class that contains functions for working with files and directories.
|
||||||
\class SHFileUtilities
|
/// </summary>
|
||||||
|
|
||||||
\brief
|
|
||||||
Static class that contains functions for working with files and directories.
|
|
||||||
|
|
||||||
**************************************************************************************/
|
|
||||||
class SH_API SHFileUtilities
|
class SH_API SHFileUtilities
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/*!**********************************************************************************
|
/*---------------------------------------------------------------------------------*/
|
||||||
|
/* Executable Directory Functions */
|
||||||
\brief
|
/*---------------------------------------------------------------------------------*/
|
||||||
Sets the application's current working directory to the application executable's
|
/// <summary>
|
||||||
directory.
|
/// Sets the application's current working directory to the application executable's
|
||||||
|
/// directory.
|
||||||
************************************************************************************/
|
/// </summary>
|
||||||
static void SetWorkDirToExecDir();
|
static void SetWorkDirToExecDir();
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves the file path to the executable's directory.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>File path to the executable's directory.</returns>
|
||||||
|
static std::filesystem::path GetExecDir();
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieves the file path to the executable.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>File path to the executable.</returns>
|
||||||
|
static std::filesystem::path GetExecPath();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,27 +26,29 @@ namespace SHADE
|
||||||
std::vector<std::wstring> SHStringUtilities::Split(const std::wstring& str, const wchar_t& delim)
|
std::vector<std::wstring> SHStringUtilities::Split(const std::wstring& str, const wchar_t& delim)
|
||||||
{
|
{
|
||||||
return Split<wchar_t>(str, delim);
|
return Split<wchar_t>(str, delim);
|
||||||
}
|
}
|
||||||
std::string SHStringUtilities::WstrToStr(const std::wstring& wstr)
|
std::string SHStringUtilities::WstrToStr(const std::wstring& wstr)
|
||||||
{
|
{
|
||||||
static std::vector<char> buffer;
|
static std::vector<char> buffer;
|
||||||
const int STR_SIZE = WideCharToMultiByte(CP_UTF8, 0, wstr.data(), static_cast<int>(wstr.size()), nullptr, 0, nullptr, nullptr) + 1 /* Null Terminator */;
|
buffer.clear();
|
||||||
buffer.resize(STR_SIZE);
|
const int STR_SIZE = WideCharToMultiByte(CP_UTF8, 0, wstr.data(), static_cast<int>(wstr.size()), nullptr, 0, nullptr, nullptr) + 1 /* Null Terminator */;
|
||||||
WideCharToMultiByte(CP_UTF8, 0, wstr.data(), static_cast<int>(wstr.size()), buffer.data(), MAX_PATH, nullptr, nullptr);
|
buffer.resize(STR_SIZE, '\0');
|
||||||
return std::string(buffer.data());
|
WideCharToMultiByte(CP_UTF8, 0, wstr.data(), static_cast<int>(wstr.size()), buffer.data(), MAX_PATH, nullptr, nullptr);
|
||||||
}
|
return std::string(buffer.data());
|
||||||
std::wstring SHStringUtilities::StrToWstr(const std::string& str)
|
}
|
||||||
{
|
std::wstring SHStringUtilities::StrToWstr(const std::string& str)
|
||||||
static std::vector<wchar_t> buffer;
|
{
|
||||||
const int WSTR_SIZE = MultiByteToWideChar(CP_UTF8, 0, str.data(), static_cast<int>(str.size()), nullptr, 0) + 1 /* Null Terminator */;
|
static std::vector<wchar_t> buffer;
|
||||||
buffer.resize(WSTR_SIZE);
|
buffer.clear();
|
||||||
MultiByteToWideChar(CP_UTF8, 0, str.data(), static_cast<int>(str.size()), buffer.data(), WSTR_SIZE);
|
const int WSTR_SIZE = MultiByteToWideChar(CP_UTF8, 0, str.data(), static_cast<int>(str.size()), nullptr, 0) + 1 /* Null Terminator */;
|
||||||
return std::wstring(buffer.data());
|
buffer.resize(WSTR_SIZE, '\0');
|
||||||
}
|
MultiByteToWideChar(CP_UTF8, 0, str.data(), static_cast<int>(str.size()), buffer.data(), WSTR_SIZE);
|
||||||
|
return std::wstring(buffer.data());
|
||||||
|
}
|
||||||
|
|
||||||
std::string SHStringUtilities::GetWin32ErrorMessage(unsigned long errorCode)
|
std::string SHStringUtilities::GetWin32ErrorMessage(unsigned long errorCode)
|
||||||
{
|
{
|
||||||
return std::system_category().message(errorCode);
|
return std::system_category().message(errorCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -44,6 +44,10 @@ namespace SHADE
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
bool Application::IsEditor::get()
|
||||||
|
{
|
||||||
|
return SHSystemManager::GetSystem<SHEditor>() != nullptr;
|
||||||
|
}
|
||||||
int Application::WindowWidth::get()
|
int Application::WindowWidth::get()
|
||||||
{
|
{
|
||||||
return SHGraphicsSystemInterface::GetWindowWidth();
|
return SHGraphicsSystemInterface::GetWindowWidth();
|
||||||
|
@ -66,6 +70,9 @@ namespace SHADE
|
||||||
/*---------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------*/
|
||||||
void Application::Quit()
|
void Application::Quit()
|
||||||
{
|
{
|
||||||
SHGraphicsSystemInterface::CloseWindow();
|
if (!IsEditor)
|
||||||
|
{
|
||||||
|
SHGraphicsSystemInterface::CloseWindow();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,13 @@ namespace SHADE
|
||||||
bool get();
|
bool get();
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
/// True if the engine is running in the editor.
|
||||||
|
/// </summary>
|
||||||
|
static property bool IsEditor
|
||||||
|
{
|
||||||
|
bool get();
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
/// Retrieves the designated width of the current window.
|
/// Retrieves the designated width of the current window.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
static property int WindowWidth
|
static property int WindowWidth
|
||||||
|
@ -71,6 +78,7 @@ namespace SHADE
|
||||||
/*-----------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------*/
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Marks the application to stop at the end of the current frame.
|
/// Marks the application to stop at the end of the current frame.
|
||||||
|
/// If running in the editor, this function does nothing.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
static void Quit();
|
static void Quit();
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue