Skip to content

Commit

Permalink
Package WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
wgergely committed Mar 1, 2024
1 parent 9b11430 commit ca5b3a7
Show file tree
Hide file tree
Showing 13 changed files with 258 additions and 188 deletions.
1 change: 1 addition & 0 deletions .idea/bookmarks.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

133 changes: 133 additions & 0 deletions src/include/commandlineparser.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@

#ifndef COMMAND_LINE_PARSER_H
#define COMMAND_LINE_PARSER_H

#include <iostream>
#include <map>
#include <optional>
#include <sstream>
#include <stdexcept>
#include <string>
#include <vector>

class CommandLineParser {
public:
struct ArgumentSpec {
std::vector<std::wstring> names; // Include both short and long names here
std::wstring description;
std::optional<std::wstring> defaultValue;
bool requiresValue = false;
bool required = false;
};

private:
std::map<std::wstring, ArgumentSpec> specs;
std::map<std::wstring, std::wstring> parsedArgs;
std::map<std::wstring, std::wstring> aliasMap; // Map aliases to primary names

void buildAliasMap() {
for (const auto &spec : specs) {
for (const auto &name : spec.second.names) {
aliasMap[name] = spec.first;
}
}
}

void initializeDefaults() {
for (const auto &spec : specs) {
if (spec.second.defaultValue.has_value()) {
parsedArgs[spec.first] = spec.second.defaultValue.value();
} else if (!spec.second.requiresValue) {
// If it doesn't require a value and no default is specified, initialize
// with an empty string
parsedArgs[spec.first] = L"";
}
}
}

public:
CommandLineParser(std::initializer_list<std::pair<const std::wstring, ArgumentSpec>> list) {
for (const auto &item : list) {
specs[item.first] = item.second;
}
buildAliasMap();
initializeDefaults();
}

void parse(int argc, wchar_t *argv[]) {
for (int i = 1; i < argc; ++i) {
std::wstring arg = argv[i];
std::wstring primaryName;

// Find the primary argument name for the given alias
auto aliasIt = aliasMap.find(arg);
if (aliasIt != aliasMap.end()) {
primaryName = aliasIt->second;
} else {
throw std::runtime_error("Unknown argument: " + std::string(arg.begin(), arg.end()));
}

const auto &spec = specs[primaryName];
if (spec.requiresValue) {
if ((i + 1) < argc && argv[i + 1][0] != L'-') {
parsedArgs[primaryName] = argv[++i];
} else {
throw std::runtime_error("Argument requires a value but none was provided.");
}
} else {
parsedArgs[primaryName] = spec.defaultValue.value_or(L"");
}
}

for (const auto &spec : specs) {
if (spec.second.required && parsedArgs.find(spec.first) == parsedArgs.end()) {
throw std::runtime_error("Missing required argument: " +
std::string(spec.first.begin(), spec.first.end()));
}
}
}

template <typename T>
T get(const std::wstring &name) const {
auto it = parsedArgs.find(name);
if (it != parsedArgs.end()) {
T value;
std::wistringstream wiss(it->second);
if (!(wiss >> value)) {
throw std::runtime_error("Invalid argument value for: " + std::string(name.begin(), name.end()));
}
return value;
}

throw std::runtime_error("Argument not found: " + std::string(name.begin(), name.end()));
}

bool has(const std::wstring &name) const { return parsedArgs.find(name) != parsedArgs.end(); }

void showHelp() const {
std::wcout << L"Usage instructions:\n";
for (const auto &specItem : specs) {
const auto &spec = specItem.second;
std::wstring names = join(spec.names, L", ");
std::wstring defaultValue = spec.defaultValue.has_value() ? spec.defaultValue.value() : L"";
std::wcout << L" " << names << L"\t" << spec.description;
if (!defaultValue.empty()) {
std::wcout << L" (default: " << defaultValue << L")";
}
std::wcout << std::endl;
}
}

static std::wstring join(const std::vector<std::wstring> &vec, const std::wstring &delimiter) {
std::wstring result;
for (auto it = vec.begin(); it != vec.end(); ++it) {
if (it != vec.begin()) {
result += delimiter;
}
result += *it;
}
return result;
}
};

#endif // COMMAND_LINE_PARSER_H
9 changes: 7 additions & 2 deletions src/include/env.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
#ifndef ENV_H
#define ENV_H

#ifdef _WIN32
#define NOMINMAX
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif // _WIN32
#include <filesystem>
#include <iostream>
#include <sstream>
#include <string>
#include <filesystem>
#include <unordered_map>

#include "dist.h"
Expand All @@ -13,4 +18,4 @@ Dist::Paths InitializeEnvironment(bool use_grandparent = false);

int LaunchProcess(int argc, wchar_t *argv[], std::filesystem::path exe_path);

#endif // ENV_H
#endif // ENV_H
20 changes: 5 additions & 15 deletions src/include/imageutil.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,24 @@

#pragma once // Prevents multiple inclusions

#include <OpenImageIO/imagebufalgo.h>
#include <OpenImageIO/imagecache.h>
#include <OpenImageIO/imageio.h>

#include <chrono>
#include <cstdlib>
#include <filesystem>
#include <iomanip>
#include <iostream>
#include <locale>
#include <map>
#include <memory>
#include <optional>
#include <regex>
#include <sstream>
#include <stdexcept>
#include <string>
#include <variant>
#include <vector>

// Workaround the codecvt deprecation
#ifdef _WIN32
#define NOMINMAX
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#else
#include <codecvt>
#endif // _WIN32

#include <OpenImageIO/imagebufalgo.h>
#include <OpenImageIO/imagecache.h>
#include <OpenImageIO/imageio.h>

#ifdef _PYBIND_MODULE
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
Expand Down
42 changes: 42 additions & 0 deletions src/include/stringconverter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#ifndef STRINGCONVERTER_H
#define STRINGCONVERTER_H

#include <locale>
#include <string>

#ifdef _WIN32
#define NOMINMAX
#define WIN32_LEAN_AND_MEAN
#include <windows.h> // For MultiByteToWideChar and WideCharToMultiByte
#else
#include <codecvt> // For std::codecvt_utf8 (deprecated in C++17)
#endif

class StringConverter {
public:
static std::wstring to_wstring(const std::string &utf8Str) {
#ifdef _WIN32
int count = MultiByteToWideChar(CP_UTF8, 0, utf8Str.c_str(), -1, nullptr, 0);
std::wstring wideStr(count, 0);
MultiByteToWideChar(CP_UTF8, 0, utf8Str.c_str(), -1, &wideStr[0], count);
return wideStr;
#else
std::wstring_convert<std::codecvt_utf8<wchar_t> > converter;
return converter.from_bytes(utf8Str);
#endif
}

static std::string to_string(const std::wstring &wideStr) {
#ifdef _WIN32
int count = WideCharToMultiByte(CP_UTF8, 0, wideStr.c_str(), -1, nullptr, 0, nullptr, nullptr);
std::string utf8Str(count, 0);
WideCharToMultiByte(CP_UTF8, 0, wideStr.c_str(), -1, &utf8Str[0], count, nullptr, nullptr);
return utf8Str;
#else
std::wstring_convert<std::codecvt_utf8<wchar_t> > converter;
return converter.to_bytes(wideStr);
#endif
}
};

#endif // STRINGCONVERTER_H
File renamed without changes.
File renamed without changes.
20 changes: 10 additions & 10 deletions tools/installer/installer.iss.in → src/inno/installer.iss
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#define MyAppName "Bookmarks"
#define MyAppVersion "${Bookmarks_VERSION_MAJOR}.${Bookmarks_VERSION_MINOR}.${Bookmarks_VERSION_PATCH}"
#define MyAppName "${APP_NAME}"
#define MyAppVersion "${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION}"
#define MyAppPublisher "Gergely Wootsch"
#define MyAppURL "https://bookmarks-vfx.com"
#define MyAppExeName "Bookmarks.exe"
#define MyAppURL "${APP_URL}"
#define MyAppExeName "${APP_EXE_NAME}"

[Setup]
AppId={{C6A64D39-06F7-4229-92B1-5AFEADF201CB}
Expand Down Expand Up @@ -30,7 +30,7 @@ ChangesEnvironment=yes
ChangesAssociations=yes

OutputBaseFilename={#MyAppName}_{#MyAppVersion}
SetupIconFile=${ICON_FILE}
SetupIconFile=${APP_ICON_FILE}

Compression=lzma2/ultra64
SolidCompression=no
Expand All @@ -44,15 +44,15 @@ VersionInfoCopyright={#MyAppPublisher}
AppCopyright={#MyAppPublisher}

UsePreviousGroup=false
UninstallDisplayIcon=${ICON_FILE}
UninstallDisplayIcon=${APP_ICON_FILE}
UninstallDisplayName={#MyAppName}

DisableWelcomePage=no
ShowLanguageDialog=no

WizardStyle=modern
WizardImageFile=${WIZARD_IMAGE}
WizardSmallImageFile=${WIZARD_IMAGE_SMALL}
WizardSmallImageFile=${WIZARD_SMALL_IMAGE}
BackColor=clBlack
BackColor2=clBlack
BackSolid=false
Expand All @@ -78,12 +78,12 @@ Name: maya; Description: {#MyAppName}: Maya Plugin; Types: full; Check: DirExist
Source: "${PACKAGE_DIR}/*"; DestDir: "{app}"; Components: standalone; Flags: ignoreversion recursesubdirs createallsubdirs; Permissions: users-modify
; Bookmarks python module
Source: "${SOURCE_DIR}/*"; DestDir: "{app}/shared/bookmarks"; Flags: ignoreversion recursesubdirs createallsubdirs; Permissions: users-modify
; Maya plugin
Source: "${SOURCE_DIR}/maya/plugin.py"; DestName: "Bookmarks.py"; DestDir: {userdocs}/maya/plug-ins; Components: maya; Flags: ignoreversion recursesubdirs createallsubdirs; Permissions: users-modify
; Templates
Source: "${SOURCE_DIR}/rsc/templates/*.zip"; DestDir: "{localappdata}/{#MyAppName}/asset_templates"; Components: standalone; Flags: ignoreversion recursesubdirs createallsubdirs; Permissions: users-modify
; Icon
Source: "${ICON_FILE}"; DestName: "icon.ico"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs; Permissions: users-modify
Source: "${APP_ICON_FILE}"; DestName: "icon.ico"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs; Permissions: users-modify
; Maya plugin
Source: "${SOURCE_DIR}/maya/plugin.py"; DestName: "Bookmarks.py"; DestDir: {userdocs}/maya/plug-ins; Components: maya; Flags: ignoreversion recursesubdirs createallsubdirs; Permissions: users-modify

[Registry]
; Used by the DCC plugins and the standalone executable to locate the install dir
Expand Down
4 changes: 2 additions & 2 deletions src/src/env.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,8 @@ Dist::Paths InitializeEnvironment(bool use_grandparent) {
#endif

#ifndef NO_CONSOLE
std::wcout << L"Bookmarks_ROOT=" << paths.root.wstring() << std::endl;
std::wcout << L"Bookmarks_VERSION=" << version << std::endl;
std::wcout << L"# Bookmarks_ROOT=" << paths.root.wstring() << std::endl;
std::wcout << L"# Bookmarks_VERSION=" << version << std::endl;
#endif

return paths;
Expand Down
Loading

0 comments on commit ca5b3a7

Please sign in to comment.