Init Repo
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
#include "FileDialog.h"
|
||||
#include "Logger.h"
|
||||
#include <commdlg.h>
|
||||
#include <vector>
|
||||
|
||||
namespace UsdLayerManager {
|
||||
|
||||
std::string FileDialog::OpenFile(const char* filter, const char* title, HWND owner) {
|
||||
std::vector<char> filename(MAX_PATH_LENGTH, 0);
|
||||
|
||||
OPENFILENAMEA ofn = {};
|
||||
ofn.lStructSize = sizeof(OPENFILENAMEA);
|
||||
ofn.hwndOwner = owner;
|
||||
ofn.lpstrFilter = filter;
|
||||
ofn.lpstrFile = filename.data();
|
||||
ofn.nMaxFile = MAX_PATH_LENGTH;
|
||||
ofn.lpstrTitle = title;
|
||||
ofn.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_NOCHANGEDIR;
|
||||
|
||||
if (GetOpenFileNameA(&ofn)) {
|
||||
return std::string(filename.data());
|
||||
}
|
||||
|
||||
// User cancelled or error occurred
|
||||
DWORD error = CommDlgExtendedError();
|
||||
if (error != 0) {
|
||||
LOG_ERROR("File dialog error code: " + std::to_string(error));
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string FileDialog::SaveFile(const char* filter, const char* title, const char* defaultExt, HWND owner) {
|
||||
std::vector<char> filename(MAX_PATH_LENGTH, 0);
|
||||
|
||||
OPENFILENAMEA ofn = {};
|
||||
ofn.lStructSize = sizeof(OPENFILENAMEA);
|
||||
ofn.hwndOwner = owner;
|
||||
ofn.lpstrFilter = filter;
|
||||
ofn.lpstrFile = filename.data();
|
||||
ofn.nMaxFile = MAX_PATH_LENGTH;
|
||||
ofn.lpstrTitle = title;
|
||||
ofn.lpstrDefExt = defaultExt;
|
||||
ofn.Flags = OFN_OVERWRITEPROMPT | OFN_NOCHANGEDIR;
|
||||
|
||||
if (GetSaveFileNameA(&ofn)) {
|
||||
return std::string(filename.data());
|
||||
}
|
||||
|
||||
// User cancelled or error occurred
|
||||
DWORD error = CommDlgExtendedError();
|
||||
if (error != 0) {
|
||||
LOG_ERROR("File dialog error code: " + std::to_string(error));
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
} // namespace UsdLayerManager
|
||||
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <Windows.h>
|
||||
|
||||
namespace UsdLayerManager {
|
||||
|
||||
class FileDialog {
|
||||
public:
|
||||
// Open file dialog
|
||||
static std::string OpenFile(
|
||||
const char* filter = "USD Files (*.usd;*.usda;*.usdc)\0*.usd;*.usda;*.usdc\0All Files (*.*)\0*.*\0",
|
||||
const char* title = "Open USD File",
|
||||
HWND owner = nullptr
|
||||
);
|
||||
|
||||
// Save file dialog
|
||||
static std::string SaveFile(
|
||||
const char* filter = "USD Files (*.usd;*.usda;*.usdc)\0*.usd;*.usda;*.usdc\0All Files (*.*)\0*.*\0",
|
||||
const char* title = "Save USD File",
|
||||
const char* defaultExt = "usd",
|
||||
HWND owner = nullptr
|
||||
);
|
||||
|
||||
private:
|
||||
static const int MAX_PATH_LENGTH = 4096;
|
||||
};
|
||||
|
||||
} // namespace UsdLayerManager
|
||||
@@ -0,0 +1,47 @@
|
||||
#include "GLExt.h"
|
||||
#include "Logger.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
# include <Windows.h>
|
||||
#endif
|
||||
|
||||
namespace UsdLayerManager {
|
||||
namespace GL {
|
||||
|
||||
#ifdef _WIN32
|
||||
// wglGetProcAddress only resolves extension / ARB functions.
|
||||
// Core functions (OpenGL 1.x) live in opengl32.dll and must be
|
||||
// fetched via GetProcAddress. This two-stage loader covers both.
|
||||
static GLADapiproc WinGLLoader(const char* name) {
|
||||
GLADapiproc proc = reinterpret_cast<GLADapiproc>(wglGetProcAddress(name));
|
||||
if (!proc) {
|
||||
HMODULE hMod = GetModuleHandleA("opengl32.dll");
|
||||
if (hMod) {
|
||||
proc = reinterpret_cast<GLADapiproc>(GetProcAddress(hMod, name));
|
||||
}
|
||||
}
|
||||
return proc;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool InitExtensions() {
|
||||
// Must be called after wglMakeCurrent so the context is current.
|
||||
#ifdef _WIN32
|
||||
int version = gladLoadGL(WinGLLoader);
|
||||
#else
|
||||
int version = 0; // supply a platform loader for non-Windows
|
||||
#endif
|
||||
|
||||
if (version == 0) {
|
||||
LOG_ERROR("gladLoadGL failed - could not load OpenGL functions");
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG_INFO("OpenGL loaded via glad (GL "
|
||||
+ std::to_string(GLAD_VERSION_MAJOR(version)) + "."
|
||||
+ std::to_string(GLAD_VERSION_MINOR(version)) + ")");
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace GL
|
||||
} // namespace UsdLayerManager
|
||||
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
// glad must be included before any other OpenGL headers.
|
||||
// It provides all GL core 3.3 functions and constants.
|
||||
#include <glad/gl.h>
|
||||
|
||||
namespace UsdLayerManager {
|
||||
namespace GL {
|
||||
|
||||
// Initializes the glad OpenGL function loader.
|
||||
// Must be called after a valid OpenGL context has been made current.
|
||||
bool InitExtensions();
|
||||
|
||||
} // namespace GL
|
||||
} // namespace UsdLayerManager
|
||||
@@ -0,0 +1,96 @@
|
||||
#include "Logger.h"
|
||||
#include <iomanip>
|
||||
|
||||
namespace UsdLayerManager {
|
||||
|
||||
Logger& Logger::Instance() {
|
||||
static Logger instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
Logger::Logger()
|
||||
: m_logLevel(LogLevel::Info) {
|
||||
}
|
||||
|
||||
Logger::~Logger() {
|
||||
if (m_logFile.is_open()) {
|
||||
m_logFile.close();
|
||||
}
|
||||
}
|
||||
|
||||
void Logger::SetLogLevel(LogLevel level) {
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
m_logLevel = level;
|
||||
}
|
||||
|
||||
void Logger::SetLogFile(const std::string& filename) {
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
if (m_logFile.is_open()) {
|
||||
m_logFile.close();
|
||||
}
|
||||
m_logFile.open(filename, std::ios::out | std::ios::app);
|
||||
if (!m_logFile.is_open()) {
|
||||
std::cerr << "Failed to open log file: " << filename << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void Logger::Debug(const std::string& message) {
|
||||
Log(LogLevel::Debug, message);
|
||||
}
|
||||
|
||||
void Logger::Info(const std::string& message) {
|
||||
Log(LogLevel::Info, message);
|
||||
}
|
||||
|
||||
void Logger::Warning(const std::string& message) {
|
||||
Log(LogLevel::Warning, message);
|
||||
}
|
||||
|
||||
void Logger::Error(const std::string& message) {
|
||||
Log(LogLevel::Error, message);
|
||||
}
|
||||
|
||||
void Logger::Log(LogLevel level, const std::string& message) {
|
||||
if (level < m_logLevel) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
|
||||
std::string timestamp = GetTimestamp();
|
||||
std::string levelStr = LevelToString(level);
|
||||
std::string logMessage = "[" + timestamp + "] [" + levelStr + "] " + message;
|
||||
|
||||
// Output to console
|
||||
if (level == LogLevel::Error) {
|
||||
std::cerr << logMessage << std::endl;
|
||||
} else {
|
||||
std::cout << logMessage << std::endl;
|
||||
}
|
||||
|
||||
// Output to file if open
|
||||
if (m_logFile.is_open()) {
|
||||
m_logFile << logMessage << std::endl;
|
||||
m_logFile.flush();
|
||||
}
|
||||
}
|
||||
|
||||
std::string Logger::GetTimestamp() {
|
||||
auto now = std::time(nullptr);
|
||||
auto tm = *std::localtime(&now);
|
||||
std::ostringstream oss;
|
||||
oss << std::put_time(&tm, "%Y-%m-%d %H:%M:%S");
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
std::string Logger::LevelToString(LogLevel level) {
|
||||
switch (level) {
|
||||
case LogLevel::Debug: return "DEBUG";
|
||||
case LogLevel::Info: return "INFO";
|
||||
case LogLevel::Warning: return "WARNING";
|
||||
case LogLevel::Error: return "ERROR";
|
||||
default: return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace UsdLayerManager
|
||||
@@ -0,0 +1,87 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <mutex>
|
||||
#include <ctime>
|
||||
|
||||
namespace UsdLayerManager {
|
||||
|
||||
enum class LogLevel {
|
||||
Debug,
|
||||
Info,
|
||||
Warning,
|
||||
Error
|
||||
};
|
||||
|
||||
class Logger {
|
||||
public:
|
||||
static Logger& Instance();
|
||||
|
||||
void SetLogLevel(LogLevel level);
|
||||
void SetLogFile(const std::string& filename);
|
||||
|
||||
void Debug(const std::string& message);
|
||||
void Info(const std::string& message);
|
||||
void Warning(const std::string& message);
|
||||
void Error(const std::string& message);
|
||||
|
||||
template<typename... Args>
|
||||
void Debug(const std::string& format, Args... args) {
|
||||
Log(LogLevel::Debug, FormatString(format, args...));
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void Info(const std::string& format, Args... args) {
|
||||
Log(LogLevel::Info, FormatString(format, args...));
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void Warning(const std::string& format, Args... args) {
|
||||
Log(LogLevel::Warning, FormatString(format, args...));
|
||||
}
|
||||
|
||||
template<typename... Args>
|
||||
void Error(const std::string& format, Args... args) {
|
||||
Log(LogLevel::Error, FormatString(format, args...));
|
||||
}
|
||||
|
||||
private:
|
||||
Logger();
|
||||
~Logger();
|
||||
|
||||
Logger(const Logger&) = delete;
|
||||
Logger& operator=(const Logger&) = delete;
|
||||
|
||||
void Log(LogLevel level, const std::string& message);
|
||||
std::string GetTimestamp();
|
||||
std::string LevelToString(LogLevel level);
|
||||
|
||||
template<typename T>
|
||||
std::string FormatString(const std::string& format, T value) {
|
||||
std::ostringstream oss;
|
||||
oss << format << value;
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
template<typename T, typename... Args>
|
||||
std::string FormatString(const std::string& format, T value, Args... args) {
|
||||
std::ostringstream oss;
|
||||
oss << format << value;
|
||||
return FormatString(oss.str(), args...);
|
||||
}
|
||||
|
||||
LogLevel m_logLevel;
|
||||
std::ofstream m_logFile;
|
||||
std::mutex m_mutex;
|
||||
};
|
||||
|
||||
// Convenience macros
|
||||
#define LOG_DEBUG(msg) UsdLayerManager::Logger::Instance().Debug(msg)
|
||||
#define LOG_INFO(msg) UsdLayerManager::Logger::Instance().Info(msg)
|
||||
#define LOG_WARNING(msg) UsdLayerManager::Logger::Instance().Warning(msg)
|
||||
#define LOG_ERROR(msg) UsdLayerManager::Logger::Instance().Error(msg)
|
||||
|
||||
} // namespace UsdLayerManager
|
||||
@@ -0,0 +1,53 @@
|
||||
#include "PathUtils.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace UsdLayerManager {
|
||||
|
||||
std::string ExeDir()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
wchar_t wpath[MAX_PATH] = {};
|
||||
DWORD len = ::GetModuleFileNameW(nullptr, wpath, MAX_PATH);
|
||||
if (len == 0 || len >= MAX_PATH)
|
||||
return "./";
|
||||
|
||||
// Convert UTF-16 → UTF-8
|
||||
int needed = ::WideCharToMultiByte(CP_UTF8, 0, wpath, static_cast<int>(len),
|
||||
nullptr, 0, nullptr, nullptr);
|
||||
std::string path(static_cast<size_t>(needed), '\0');
|
||||
::WideCharToMultiByte(CP_UTF8, 0, wpath, static_cast<int>(len),
|
||||
path.data(), needed, nullptr, nullptr);
|
||||
#else
|
||||
char buf[PATH_MAX] = {};
|
||||
ssize_t len = ::readlink("/proc/self/exe", buf, sizeof(buf) - 1);
|
||||
if (len <= 0)
|
||||
return "./";
|
||||
std::string path(buf, static_cast<size_t>(len));
|
||||
#endif
|
||||
|
||||
// Normalise to forward slashes and strip the filename
|
||||
std::replace(path.begin(), path.end(), '\\', '/');
|
||||
auto slash = path.rfind('/');
|
||||
if (slash != std::string::npos)
|
||||
path = path.substr(0, slash + 1); // keep trailing '/'
|
||||
else
|
||||
path = "./";
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
std::string ResourcePath(const std::string& relativePath)
|
||||
{
|
||||
return ExeDir() + relativePath;
|
||||
}
|
||||
|
||||
} // namespace UsdLayerManager
|
||||
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
|
||||
namespace UsdLayerManager {
|
||||
|
||||
/// Return the directory that contains the running executable, with a
|
||||
/// trailing path separator. On Windows this uses GetModuleFileNameW.
|
||||
/// Falls back to "./" if the path cannot be determined.
|
||||
///
|
||||
/// Usage:
|
||||
/// std::string iconDir = ExeDir() + "resources/icons";
|
||||
std::string ExeDir();
|
||||
|
||||
/// Concatenate the exe directory with a relative path.
|
||||
/// ResourcePath("resources/icons") == ExeDir() + "resources/icons"
|
||||
std::string ResourcePath(const std::string& relativePath);
|
||||
|
||||
} // namespace UsdLayerManager
|
||||
Reference in New Issue
Block a user