feat: expand editor scripting asset and viewport flow

This commit is contained in:
2026-04-03 13:22:30 +08:00
parent ed8c27fde2
commit a05d0b80a2
124 changed files with 10397 additions and 1737 deletions

View File

@@ -0,0 +1,106 @@
#pragma once
#include "Platform/Win32Utf8.h"
#include <algorithm>
#include <filesystem>
#include <fstream>
#include <string>
#include <vector>
namespace XCEngine {
namespace Editor {
namespace Scripting {
inline std::string ScriptBuilderPathToUtf8(const std::filesystem::path& path) {
return Platform::WideToUtf8(path.wstring());
}
inline std::vector<std::filesystem::path> CollectCSharpSourceFiles(const std::filesystem::path& root) {
std::vector<std::filesystem::path> sourceFiles;
std::error_code ec;
if (root.empty() || !std::filesystem::exists(root, ec)) {
return sourceFiles;
}
for (std::filesystem::recursive_directory_iterator it(root, ec), end; it != end && !ec; it.increment(ec)) {
if (ec || !it->is_regular_file(ec)) {
continue;
}
const std::filesystem::path path = it->path();
if (path.extension() == ".cs") {
sourceFiles.push_back(path.lexically_normal());
}
}
std::sort(sourceFiles.begin(), sourceFiles.end());
return sourceFiles;
}
inline std::string ParseLatestDotnetSdkVersion(const std::string& sdkListOutput) {
std::string latestVersion;
size_t lineStart = 0;
while (lineStart < sdkListOutput.size()) {
const size_t lineEnd = sdkListOutput.find_first_of("\r\n", lineStart);
const std::string line = sdkListOutput.substr(
lineStart,
lineEnd == std::string::npos ? std::string::npos : lineEnd - lineStart);
const size_t delimiter = line.find(" [");
if (delimiter != std::string::npos) {
latestVersion = line.substr(0, delimiter);
}
if (lineEnd == std::string::npos) {
break;
}
lineStart = lineEnd + 1;
if (lineStart < sdkListOutput.size() &&
sdkListOutput[lineEnd] == '\r' &&
sdkListOutput[lineStart] == '\n') {
++lineStart;
}
}
return latestVersion;
}
inline bool EnsurePlaceholderProjectScriptSource(
std::vector<std::filesystem::path>& ioSourceFiles,
const std::filesystem::path& placeholderPath,
std::string& outError) {
if (!ioSourceFiles.empty()) {
return true;
}
std::error_code ec;
std::filesystem::create_directories(placeholderPath.parent_path(), ec);
if (ec) {
outError = "Failed to create the placeholder script directory: " +
ScriptBuilderPathToUtf8(placeholderPath.parent_path());
return false;
}
std::ofstream output(placeholderPath, std::ios::out | std::ios::trunc);
if (!output.is_open()) {
outError = "Failed to create the placeholder project script source: " +
ScriptBuilderPathToUtf8(placeholderPath);
return false;
}
output << "namespace XCEngine.Generated { public static class EmptyProjectGameScriptsMarker {} }\n";
output.close();
if (!output.good()) {
outError = "Failed to write the placeholder project script source: " +
ScriptBuilderPathToUtf8(placeholderPath);
return false;
}
ioSourceFiles.push_back(placeholderPath.lexically_normal());
return true;
}
} // namespace Scripting
} // namespace Editor
} // namespace XCEngine