Compare commits

...

7 Commits

Author SHA1 Message Date
gary 88e901e214 [keel] Cleanup
Build / build (push) Successful in 1m9s
2026-04-29 01:55:32 -05:00
gary d42e10fcbe [olympic] Cleanup pkg-gba 2026-04-29 01:52:59 -05:00
gary bc88333a59 [studio/modlib] Update ImGui drag/drop, other cleanup 2026-04-29 01:50:39 -05:00
gary 4048753205 [ox/std] Add call and logCatch for safe calling of throwing functions 2026-04-29 01:47:15 -05:00
gary 5c146c6660 [ox/std] Add call and logCatch for safe calling of throwing functions 2026-04-29 01:45:56 -05:00
gary 0885919dbd [ox/std] Cleanup 2026-04-29 01:44:43 -05:00
gary 8c7d8cd08b [ox/model] Cleanup TypeNameCatcher and TypeInfoCatcher 2026-04-29 01:42:53 -05:00
12 changed files with 175 additions and 122 deletions
+17 -59
View File
@@ -17,76 +17,34 @@
namespace ox {
struct TypeNameCatcher {
const char *name = "";
int version = 0;
constexpr TypeNameCatcher() noexcept = default;
template<typename T>
constexpr ox::Error setTypeInfo(
const char *n = T::TypeName,
int v = T::TypeVersion,
const Vector<String>& = {},
std::size_t = ModelFieldCount_v<T>) noexcept {
this->name = n;
this->version = v;
return {};
}
template<typename T>
constexpr Error field(const char*, T*, std::size_t) noexcept {
return {};
}
template<typename T>
constexpr Error field(const char*, T) noexcept {
return {};
}
template<typename ...Args>
constexpr Error fieldCString(Args&&...) noexcept {
return {};
}
static constexpr auto opType() noexcept {
return OpType::Reflect;
}
};
struct TypeInfoCatcher {
const char *name = "";
CString name = "";
int version = 0;
constexpr TypeInfoCatcher() noexcept = default;
template<typename T = std::nullptr_t>
constexpr ox::Error setTypeInfo(
const char *n = T::TypeName,
int v = T::TypeVersion,
const Vector<String>& = {},
std::size_t = 0) noexcept {
constexpr Error setTypeInfo(
CString const n = T::TypeName,
int const v = T::TypeVersion,
Vector<String> const& = {},
size_t = 0) noexcept {
this->name = n;
this->version = v;
return {};
}
template<typename T>
constexpr Error field(const char*, T*, std::size_t) noexcept {
constexpr Error field(CString, T*, size_t) noexcept {
return {};
}
template<typename T>
constexpr Error field(const char*, T) noexcept {
constexpr Error field(CString, T const&) noexcept {
return {};
}
template<typename T>
constexpr Error fieldCString(const char*, T) noexcept {
constexpr Error fieldCString(CString, T const&) noexcept {
return {};
}
@@ -125,14 +83,14 @@ consteval int requireModelTypeVersion() noexcept {
template<typename T, typename Str = const char*>
[[nodiscard]]
constexpr Str getModelTypeName(T *val) noexcept {
TypeNameCatcher nc;
TypeInfoCatcher nc;
std::ignore = model(&nc, val);
return nc.name;
}
template<typename T, typename Str = const char*>
[[nodiscard]]
constexpr Str getModelTypeName() noexcept {
consteval Str getModelTypeName() noexcept {
std::allocator<T> a;
auto t = a.allocate(1);
auto out = getModelTypeName(t);
@@ -140,15 +98,15 @@ constexpr Str getModelTypeName() noexcept {
return out;
}
template<typename T, typename Str = const char*>
template<typename T, typename Str = StringLiteral>
[[nodiscard]]
consteval auto requireModelTypeName() noexcept {
constexpr auto name = getModelTypeName<T, Str>();
static_assert(ox::StringView{name}.size(), "Type lacks required TypeName");
static_assert(StringView{name}.size(), "Type lacks required TypeName");
return name;
}
template<typename T, typename Str = const char*>
template<typename T, typename Str = StringLiteral>
constexpr auto ModelTypeName_v = requireModelTypeName<T, Str>();
template<typename T, typename Str = const char*>
@@ -156,10 +114,10 @@ constexpr auto ModelTypeVersion_v = requireModelTypeVersion<T>();
template<typename T>
constexpr auto ModelTypeId_v = [] {
constexpr auto name = ModelTypeName_v<T, ox::StringView>;
constexpr auto name = ModelTypeName_v<T, StringView>;
constexpr auto version = ModelTypeVersion_v<T>;
constexpr auto versionStr = ox::sfmt<ox::IString<19>>("{}", version);
return ox::sfmt<ox::IString<name.size() + versionStr.size() + 1>>("{};{}", name, versionStr);
constexpr auto versionStr = ox::sfmt<IString<19>>("{}", version);
return ox::sfmt<IString<name.size() + versionStr.size() + 1>>("{};{}", name, versionStr);
}();
}
+1
View File
@@ -107,6 +107,7 @@ install(
def.hpp
defer.hpp
defines.hpp
errhandling.hpp
error.hpp
fmt.hpp
hardware.hpp
+67
View File
@@ -0,0 +1,67 @@
/*
* Copyright 2015 - 2025 gary@drinkingtea.net
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#pragma once
#include <ox/std/error.hpp>
#include <ox/std/trace.hpp>
#include <ox/std/utility.hpp>
namespace ox {
template<typename F, typename... Args>
constexpr Error call(F const &f, Args&&... args) noexcept {
try {
f(ox::forward<Args>(args)...);
return {};
} catch (Exception const &e) {
return e.toError();
} catch (...) {
return Error{1, "unknown exception"};
}
}
template<typename T, typename Method, typename... Args>
constexpr Error call(T &receiver, Method methodPtr, Args&&... args) noexcept {
try {
(receiver.*methodPtr)(ox::forward<Args>(args)...);
return {};
} catch (Exception const &e) {
return e.toError();
} catch (...) {
return Error{1, "unknown exception"};
}
}
template<typename F, typename... Args>
constexpr void logCatch(F const &f, Args&&... args) noexcept {
try {
f(ox::forward<Args>(args)...);
} catch (Exception const &e) {
oxErrf("Caught exception: {} ({}:{})\n", e.what(), e.src.file_name(), e.src.line());
} catch (std::exception const &e) {
oxErrf("Caught exception: {}\n", e.what());
} catch (...) {
oxErr("Caught unknown exception\n");
}
}
template<typename T, typename Method, typename... Args>
constexpr void logCatch(T &receiver, Method methodPtr, Args&&... args) noexcept {
try {
(receiver.*methodPtr)(ox::forward<Args>(args)...);
} catch (Exception const &e) {
oxErrf("Caught exception: {} ({}:{})\n", e.what(), e.src.file_name(), e.src.line());
} catch (std::exception const &e) {
oxErrf("Caught exception: {}\n", e.what());
} catch (...) {
oxErr("Caught unknown exception\n");
}
}
}
+10 -4
View File
@@ -62,13 +62,19 @@ struct [[nodiscard]] Error {
return errCode;
}
constexpr void throwException() const;
/**
* Checks the Error to see if is not OK, and throws the Error as an ox::Exception if not.
*/
constexpr void checkThrow() const;
constexpr Error reoriginate(
ErrorCode const pErrCode,
CString const pMsg = nullptr,
std::source_location const &pSrc = std::source_location::current()) const noexcept {
return Error{pErrCode, pMsg, pSrc};
if (errCode) {
return Error{pErrCode, pMsg, pSrc};
}
return Error{};
}
constexpr Error reoriginate(
@@ -102,7 +108,7 @@ struct Exception: public std::exception {
explicit Exception(
ErrorCode const errCode,
CString msg,
CString const msg,
std::source_location const &src = std::source_location::current()) noexcept:
src{src},
msg{msg},
@@ -124,7 +130,7 @@ struct Exception: public std::exception {
};
constexpr void Error::throwException() const {
constexpr void Error::checkThrow() const {
if (errCode) [[unlikely]] {
throw Exception{*this};
}
+30 -30
View File
@@ -31,27 +31,27 @@ namespace ox {
namespace detail {
template<bool force = false>
constexpr StringView toStringView(const StringView &s) noexcept {
constexpr StringView toStringView(StringViewCR s) noexcept {
return s;
}
template<bool force = false>
constexpr StringView toStringView(const char *s) noexcept {
constexpr StringView toStringView(CString const s) noexcept {
return s;
}
template<bool force = false, std::size_t size>
constexpr StringView toStringView(const IString<size> &s) noexcept {
constexpr StringView toStringView(IString<size> const &s) noexcept {
return s;
}
template<bool force = false>
constexpr StringView toStringView(ox::StringLiteral s) noexcept {
constexpr StringView toStringView(StringLiteral const &s) noexcept {
return s;
}
template<bool force = false, std::size_t size>
constexpr StringView toStringView(const BasicString<size> &s) noexcept {
constexpr StringView toStringView(BasicString<size> const &s) noexcept {
return s;
}
@@ -62,20 +62,20 @@ constexpr
#else
inline
#endif
StringView toStringView(const std::string &s) noexcept {
StringView toStringView(std::string const &s) noexcept {
return s.c_str();
}
#endif
#if __has_include(<QString>)
template<bool force = false>
inline StringView toStringView(const QString &s) noexcept {
inline StringView toStringView(QString const &s) noexcept {
return s.toUtf8().data();
}
#endif
template<bool force = false>
constexpr StringView toStringView(const auto&) noexcept requires(force) {
constexpr StringView toStringView(auto const&) noexcept requires(force) {
return "<unstringable>";
}
@@ -83,10 +83,10 @@ class FmtArg {
private:
static constexpr auto DataSz = 23;
ox::Array<char, DataSz> dataStr{};
Array<char, DataSz> dataStr{};
template<typename T>
constexpr StringView sv(const T &v, ox::Span<char> dataStr) noexcept {
constexpr StringView sv(T const &v, Span<char> dataStr) noexcept {
if constexpr(is_bool_v<T>) {
return v ? "true" : "false";
} else if constexpr(is_integer_v<T>) {
@@ -99,25 +99,25 @@ class FmtArg {
}
public:
const StringView out = nullptr;
StringView const out;
template<typename T>
constexpr FmtArg(const T &v) noexcept: out(sv(v, dataStr)) {
constexpr FmtArg(T const &v) noexcept: out(sv(v, dataStr)) {
}
};
[[nodiscard]]
constexpr uint64_t argCount(StringView str) noexcept {
constexpr uint64_t argCount(StringViewCR str) noexcept {
uint64_t cnt = 0;
const auto prev = [str](std::size_t i) -> char {
auto const prev = [str](std::size_t i) -> char {
if (i > 0) {
return str[i - 1];
} else {
return '\0';
}
};
const auto next = [str](std::size_t i) -> char {
auto const next = [str](std::size_t i) -> char {
if (i < str.bytes() - 1) {
return str[i + 1];
} else {
@@ -133,14 +133,14 @@ constexpr uint64_t argCount(StringView str) noexcept {
}
struct FmtSegment {
const char *str = nullptr;
unsigned length = 0;
CString str{};
unsigned length{};
constexpr bool operator==(const FmtSegment &o) const noexcept {
constexpr bool operator==(FmtSegment const &o) const noexcept {
return length == o.length && ox::strncmp(str, o.str, length) == 0;
}
constexpr bool operator!=(const FmtSegment &o) const noexcept {
constexpr bool operator!=(FmtSegment const &o) const noexcept {
return length != o.length || ox::strncmp(str, o.str, length) != 0;
}
};
@@ -148,9 +148,9 @@ struct FmtSegment {
template<std::size_t sz>
struct Fmt {
static constexpr std::size_t size = sz;
ox::Array<FmtSegment, sz> segments;
Array<FmtSegment, sz> segments;
constexpr bool operator==(const Fmt<sz> &o) const noexcept {
constexpr bool operator==(Fmt const &o) const noexcept {
for (std::size_t i = 0; i < sz; ++i) {
if (segments[i] != o.segments[i]) {
return false;
@@ -162,16 +162,16 @@ struct Fmt {
template<std::size_t segementCnt>
[[nodiscard]]
constexpr Fmt<segementCnt> fmtSegments(StringView fmt) noexcept {
constexpr Fmt<segementCnt> fmtSegments(StringViewCR fmt) noexcept {
Fmt<segementCnt> out;
const auto prev = [fmt](std::size_t i) -> char {
auto const prev = [fmt](std::size_t const i) -> char {
if (i > 0) {
return fmt[i - 1];
} else {
return '\0';
}
};
const auto next = [fmt](std::size_t i) -> char {
auto const next = [fmt](std::size_t const i) -> char {
if (i < fmt.bytes() - 1) {
return fmt[i + 1];
} else {
@@ -197,23 +197,23 @@ constexpr Fmt<segementCnt> fmtSegments(StringView fmt) noexcept {
template<typename StringType = String, typename ...Args>
[[nodiscard]]
constexpr StringType sfmt(StringView fmt, Args&&... args) noexcept {
constexpr StringType sfmt(StringViewCR fmt, Args&&... args) noexcept {
assert(ox::detail::argCount(fmt) == sizeof...(args));
StringType out;
const auto fmtSegments = ox::detail::fmtSegments<sizeof...(args)+1>(fmt);
const auto &firstSegment = fmtSegments.segments[0];
auto const fmtSegments = detail::fmtSegments<sizeof...(args)+1>(fmt);
auto const &firstSegment = fmtSegments.segments[0];
std::ignore = out.append(firstSegment.str, firstSegment.length);
const detail::FmtArg elements[sizeof...(args)] = {args...};
detail::FmtArg const elements[sizeof...(args)] = {args...};
for (size_t i = 0; i < fmtSegments.size - 1; ++i) {
std::ignore = out.append(elements[i].out);
const auto &s = fmtSegments.segments[i + 1];
auto const &s = fmtSegments.segments[i + 1];
std::ignore = out.append(s.str, s.length);
}
return out;
}
template<typename T = String>
constexpr Result<T> join(auto const&d, auto const&list) {
constexpr Result<T> join(auto const &d, auto const &list) {
if (!list.size()) {
return T("");
}
+2 -2
View File
@@ -17,14 +17,14 @@ ox::Result<ox::UUID> readUuidHeader(ox::BufferView const &buff) noexcept;
ox::Result<ox::UUID> regenerateUuidHeader(ox::Buffer &buff) noexcept;
ox::Error writeUuidHeader(ox::Writer_c auto &writer, ox::UUID const &uuid) noexcept {
constexpr ox::Error writeUuidHeader(ox::Writer_c auto &writer, ox::UUID const &uuid) noexcept {
OX_RETURN_ERROR(write(writer, "K1;"));
OX_RETURN_ERROR(uuid.toString(writer));
return writer.put(';');
}
template<typename T>
ox::Result<T> readAsset(ox::BufferView buff) noexcept {
constexpr ox::Result<T> readAsset(ox::BufferView buff) noexcept {
auto const err = readUuidHeader(buff).error;
if (!err) {
buff += K1HdrSz; // the size of K1 headers
+2
View File
@@ -37,6 +37,8 @@ class Module {
virtual ox::Vector<PackTransform> packTransforms() const noexcept;
};
void registerModule(Module const &mod) noexcept;
void registerModule(Module const *mod) noexcept;
[[nodiscard]]
+5 -5
View File
@@ -12,7 +12,7 @@
namespace keel {
ox::Result<char*> loadRom(ox::StringViewCR path) noexcept {
static ox::Result<char*> loadRom(ox::StringViewCR path) noexcept {
std::ifstream file(std::string(toStdStringView(path)), std::ios::binary | std::ios::ate);
if (!file.good()) {
oxErrorf("Could not find ROM file: {}", path);
@@ -33,8 +33,8 @@ ox::Result<char*> loadRom(ox::StringViewCR path) noexcept {
}
}
void unloadRom(char *rom) noexcept {
ox::safeDelete(rom);
static void unloadRom(char *rom) noexcept {
ox::safeDeleteArray(rom);
}
static void clearUuidMap(Context &ctx) noexcept {
@@ -212,7 +212,7 @@ static ox::Error buildUuidMap(Context&, DuplicateSet*) noexcept {
return {};
}
ox::Result<char*> loadRom(ox::StringViewCR) noexcept {
static ox::Result<char*> loadRom(ox::StringViewCR) noexcept {
// put the header in the wrong order to prevent mistaking this code for the
// media section
constexpr auto headerP2 = "R_______________";
@@ -229,7 +229,7 @@ ox::Result<char*> loadRom(ox::StringViewCR) noexcept {
return ox::Error(1);
}
void unloadRom(char*) noexcept {
static void unloadRom(char*) noexcept {
}
ox::Result<std::size_t> getPreloadAddr(keel::Context &ctx, ox::StringViewCR path) noexcept {
+5 -1
View File
@@ -8,9 +8,13 @@ namespace keel {
static ox::Vector<Module const*> mods;
void registerModule(Module const &mod) noexcept {
mods.emplace_back(&mod);
}
void registerModule(Module const *mod) noexcept {
if (mod) {
mods.emplace_back(mod);
registerModule(*mod);
}
}
+15 -9
View File
@@ -38,8 +38,9 @@ static ox::Error pathToInode(
auto const uuid = ox::substr(path, 7);
OX_RETURN_ERROR(keel::uuidToPath(ctx, uuid).to<ox::String>().moveTo(path));
}
auto const s = dest.stat(path);
auto const inode = s.ok() ? s.value.inode : 0;
auto const inode = dest.stat(path)
.or_value({.inode = 0})
.inode;
OX_RETURN_ERROR(typeVal->set(static_cast<int8_t>(ox::FileAddressType::Inode)));
oxOutf("\tpath to inode: {} => {}\n", path, inode);
return data.set(2, inode);
@@ -49,6 +50,7 @@ static ox::Error transformFileAddressesObj(
Context &ctx,
ox::FileSystem const &dest,
ox::ModelObject &obj) noexcept;
static ox::Error transformFileAddressesVec(
Context &ctx,
ox::FileSystem const &dest,
@@ -58,14 +60,18 @@ static ox::Error transformFileAddresses(
Context &ctx,
ox::FileSystem const &dest,
ox::ModelValue &v) noexcept {
if (v.type() == ox::ModelValue::Type::Object) {
auto &obj = v.get<ox::ModelObject>();
return transformFileAddressesObj(ctx, dest, obj);
} else if (v.type() == ox::ModelValue::Type::Vector) {
auto &vec = v.get<ox::ModelValueVector>();
return transformFileAddressesVec(ctx, dest, vec);
switch (v.type()) {
case ox::ModelValue::Type::Object: {
auto &obj = v.get<ox::ModelObject>();
return transformFileAddressesObj(ctx, dest, obj);
}
case ox::ModelValue::Type::Vector: {
auto &vec = v.get<ox::ModelValueVector>();
return transformFileAddressesVec(ctx, dest, vec);
}
default:
return {};
}
return {};
}
static ox::Error transformFileAddressesVec(
@@ -9,11 +9,20 @@
#include <imgui.h>
#include <ox/std/bit.hpp>
#include <ox/std/cstringview.hpp>
#include <ox/std/stringparam.hpp>
#include <ox/claw/claw.hpp>
#include <turbine/context.hpp>
#include <studio/context.hpp>
#include <studio/widget.hpp>
namespace turbine {
class Context;
}
namespace studio {
struct Context;
}
namespace studio::ig {
inline constexpr auto BtnSz = ImVec2{52, 22};
@@ -31,18 +40,18 @@ ox::Result<T> getDragDropPayload(ox::CStringViewCR name) noexcept {
return ox::Error(1, "No drag/drop payload");
}
return ox::readClaw<T>({
std::launder(reinterpret_cast<char const*>(payload->Data)),
static_cast<char const*>(payload->Data),
static_cast<size_t>(payload->DataSize)});
}
template<typename T>
ox::Result<T> getDragDropPayload() noexcept {
auto const payload = ImGui::AcceptDragDropPayload(ox::ModelTypeName_v<T>);
auto const payload = ImGui::AcceptDragDropPayload(ox::ModelTypeName_v<T>.c_str());
if (!payload) {
return ox::Error(1, "No drag/drop payload");
}
return ox::readClaw<T>({
reinterpret_cast<char const*>(payload->Data),
static_cast<char const*>(payload->Data),
static_cast<size_t>(payload->DataSize)});
}
@@ -55,7 +64,7 @@ ox::Error setDragDropPayload(ox::CStringViewCR name, auto const &obj) noexcept {
template<typename T>
ox::Error setDragDropPayload(T const &obj) noexcept {
OX_REQUIRE(buff, ox::writeClaw(obj, ox::ClawFormat::Metal));
ImGui::SetDragDropPayload(ox::ModelTypeName_v<T>, buff.data(), buff.size());
ImGui::SetDragDropPayload(ox::ModelTypeName_v<T>.c_str(), buff.data(), buff.size());
return {};
}
@@ -64,8 +73,8 @@ class DragDropSource {
private:
bool const m_active{};
public:
DragDropSource(ImGuiDragDropFlags const flags = 0) noexcept:
m_active(ImGui::BeginDragDropSource(flags)) {
explicit DragDropSource(ImGuiDragDropFlags const flags = 0) noexcept:
m_active{ImGui::BeginDragDropSource(flags)} {
}
~DragDropSource() noexcept {
if (m_active) {
+4 -4
View File
@@ -1,7 +1,7 @@
#! /usr/bin/env python3
#
# Copyright 2016 - 2023 gary@drinkingtea.net
# Copyright 2016 - 2026 gary@drinkingtea.net
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -21,11 +21,11 @@ def run(args: list[str]):
if subprocess.run(args).returncode != 0:
sys.exit(1)
# get current build type
# get the current build type
with open(".current_build", "r") as f:
current_build = f.readlines()[0]
if current_build[len(current_build) - 1] == '\n':
current_build = current_build[:len(current_build) - 1]
if current_build[-1] == '\n':
current_build = current_build[:-1]
project_dir = sys.argv[1]
project_name = sys.argv[2]