Compare commits

..

1 Commits

Author SHA1 Message Date
870fb9c6e3 [nostalgia/studio] Set version to d2025.07.0
All checks were successful
Build / build (push) Successful in 1m17s
2025-07-31 22:07:22 -05:00
6 changed files with 60 additions and 69 deletions

View File

@@ -30,49 +30,11 @@ constexpr void *operator new(std::size_t, void *addr) noexcept {
constexpr void *operator new[](std::size_t, void *addr) noexcept { constexpr void *operator new[](std::size_t, void *addr) noexcept {
return addr; return addr;
} }
namespace std {
template<typename T>
[[nodiscard]]
constexpr T* launder(T* __p) noexcept {
return __builtin_launder(__p);
}
template<typename T, typename... Args, bool noex>
void launder(T(*)(Args...) noexcept(noex)) = delete;
template<typename T, typename... Args, bool noex>
void launder(T(*)(Args......) noexcept(noex)) = delete;
void launder(void*) = delete;
void launder(void const*) = delete;
void launder(volatile void*) = delete;
void launder(volatile void const*) = delete;
}
#endif #endif
namespace ox { namespace ox {
/**
* Aliases type T in size and alignment to allow allocating space for a T
* without running the constructor.
*/
template<typename T, std::size_t sz = sizeof(T)>
struct alignas(alignof(T)) AllocAlias {
char buff[sz];
constexpr AllocAlias() noexcept = default;
[[nodiscard]]
auto data() noexcept {
return reinterpret_cast<T*>(this);
}
[[nodiscard]]
auto data() const noexcept {
return reinterpret_cast<T const*>(this);
}
};
template<typename T, typename U = T, typename ...Args> template<typename T, typename U = T, typename ...Args>
[[nodiscard]] [[nodiscard]]
constexpr U *make(Args &&...args) noexcept { constexpr U *make(Args &&...args) noexcept {

View File

@@ -63,6 +63,25 @@ namespace ox {
using CString = char const*; using CString = char const*;
/**
* Aliases type T in size and alignment to allow allocating space for a T
* without running the constructor.
*/
template<typename T, std::size_t sz = sizeof(T)>
struct alignas(alignof(T)) AllocAlias {
char buff[sz];
constexpr AllocAlias() noexcept = default;
[[nodiscard]]
auto data() noexcept {
return reinterpret_cast<T*>(this);
}
[[nodiscard]]
auto data() const noexcept {
return reinterpret_cast<const T*>(this);
}
};
template<std::size_t sz> template<std::size_t sz>
struct SignedType { struct SignedType {
}; };

View File

@@ -34,10 +34,10 @@ struct VectorAllocator {
ox::Array<AllocAlias<T>, Size> m_data = {}; ox::Array<AllocAlias<T>, Size> m_data = {};
protected: protected:
constexpr VectorAllocator() noexcept = default; constexpr VectorAllocator() noexcept = default;
constexpr VectorAllocator(VectorAllocator const&) noexcept = default; constexpr VectorAllocator(const VectorAllocator&) noexcept = default;
constexpr VectorAllocator(VectorAllocator&&) noexcept = default; constexpr VectorAllocator(VectorAllocator&&) noexcept = default;
constexpr void allocate(T **items, std::size_t const cap) noexcept { constexpr void allocate(T **items, std::size_t cap) noexcept {
// small vector optimization cannot be done it constexpr, but it doesn't really matter in constexpr // small vector optimization cannot be done it constexpr, but it doesn't really matter in constexpr
if (std::is_constant_evaluated() || cap > Size) { if (std::is_constant_evaluated() || cap > Size) {
*items = Allocator{}.allocate(cap); *items = Allocator{}.allocate(cap);
@@ -49,26 +49,42 @@ struct VectorAllocator {
constexpr void moveConstructItemsFrom( constexpr void moveConstructItemsFrom(
T **items, T **items,
VectorAllocator *src, VectorAllocator *src,
std::size_t const count, const std::size_t count,
std::size_t const cap) noexcept { const std::size_t cap) noexcept {
// this totally idiotic redundant check (&& count <= Size) is required to address a bug in devkitARM, // this totally idiotic redundant check (&& count <= Size) is required to address a bug in devkitARM,
// try removing it later // try removing it later
if (!std::is_constant_evaluated()) { if (!std::is_constant_evaluated()) {
if (cap <= m_data.size() && count <= m_data.size()) { if (cap <= m_data.size() && count <= m_data.size()) {
for (auto i = 0u; i < count; ++i) { for (auto i = 0u; i < count; ++i) {
auto const srcItem = std::launder(reinterpret_cast<T*>(&src->m_data[i])); const auto dstItem = reinterpret_cast<T *>(&m_data[i]);
new (&m_data[i]) T(std::move(*srcItem)); const auto srcItem = reinterpret_cast<T *>(&src->m_data[i]);
} std::construct_at<T>(dstItem, std::move(*srcItem));
if (count) {
*items = std::launder(reinterpret_cast<T*>(m_data.data()));
} else {
*items = reinterpret_cast<T*>(m_data.data());
} }
*items = reinterpret_cast<T*>(m_data.data());
} }
} }
} }
constexpr void deallocate(T *const items, std::size_t const cap) noexcept { constexpr void moveItemsFrom(
T **items,
VectorAllocator *src,
const std::size_t count,
const std::size_t cap) noexcept {
// this totally idiotic redundant check (&& count <= Size) is required to address a bug in devkitARM,
// try removing it later
if (!std::is_constant_evaluated()) {
if (cap <= m_data.size() && count <= m_data.size()) {
for (std::size_t i = 0; i < count; ++i) {
const auto dstItem = reinterpret_cast<T *>(&m_data[i]);
const auto srcItem = reinterpret_cast<T *>(&src->m_data[i]);
*dstItem = std::move(*srcItem);
}
*items = reinterpret_cast<T*>(m_data.data());
}
}
}
constexpr void deallocate(T *items, std::size_t cap) noexcept {
// small vector optimization cannot be done it constexpr, but it doesn't really matter in constexpr // small vector optimization cannot be done it constexpr, but it doesn't really matter in constexpr
if (std::is_constant_evaluated()) { if (std::is_constant_evaluated()) {
if (items) { if (items) {
@@ -87,10 +103,10 @@ template<typename T, typename Allocator>
struct VectorAllocator<T, Allocator, 0> { struct VectorAllocator<T, Allocator, 0> {
protected: protected:
constexpr VectorAllocator() noexcept = default; constexpr VectorAllocator() noexcept = default;
constexpr VectorAllocator(VectorAllocator const&) noexcept = default; constexpr VectorAllocator(const VectorAllocator&) noexcept = default;
constexpr VectorAllocator(VectorAllocator&&) noexcept = default; constexpr VectorAllocator(VectorAllocator&&) noexcept = default;
constexpr void allocate(T **items, std::size_t const cap) noexcept { constexpr void allocate(T **items, std::size_t cap) noexcept {
*items = Allocator{}.allocate(cap); *items = Allocator{}.allocate(cap);
} }
@@ -98,15 +114,15 @@ struct VectorAllocator<T, Allocator, 0> {
constexpr void moveConstructItemsFrom( constexpr void moveConstructItemsFrom(
T**, T**,
VectorAllocator*, VectorAllocator*,
std::size_t const, const std::size_t,
std::size_t const) noexcept { const std::size_t) noexcept {
} }
[[maybe_unused]] [[maybe_unused]]
constexpr void moveItemsFrom(T**, VectorAllocator*, std::size_t const, std::size_t const) noexcept { constexpr void moveItemsFrom(T**, VectorAllocator*, const std::size_t, const std::size_t) noexcept {
} }
constexpr void deallocate(T *const items, std::size_t const cap) noexcept { constexpr void deallocate(T *items, std::size_t cap) noexcept {
if (items) { if (items) {
Allocator{}.deallocate(items, cap); Allocator{}.deallocate(items, cap);
} }
@@ -405,7 +421,7 @@ constexpr Vector<T, SmallVectorSize, Allocator> &Vector<T, SmallVectorSize, Allo
m_size = other.m_size; m_size = other.m_size;
m_cap = other.m_cap; m_cap = other.m_cap;
m_items = other.m_items; m_items = other.m_items;
this->moveConstructItemsFrom(&m_items, &other, m_size, m_cap); this->moveItemsFrom(&m_items, &other, m_size, m_cap);
other.m_size = 0; other.m_size = 0;
other.m_cap = 0; other.m_cap = 0;
other.m_items = nullptr; other.m_items = nullptr;

View File

@@ -15,7 +15,7 @@ target_link_libraries(
target_compile_definitions( target_compile_definitions(
NostalgiaStudio PUBLIC NostalgiaStudio PUBLIC
OLYMPIC_APP_VERSION="dev build" OLYMPIC_APP_VERSION="d2025.07.0"
) )
install( install(

View File

@@ -18,7 +18,7 @@
<string>APPL</string> <string>APPL</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>dev build</string> <string>d2025.07.0</string>
<key>LSMinimumSystemVersion</key> <key>LSMinimumSystemVersion</key>
<string>12.0.0</string> <string>12.0.0</string>

View File

@@ -8,18 +8,13 @@ namespace studio {
void navigateTo(Context &ctx, ox::StringParam filePath, ox::StringParam navArgs) noexcept { void navigateTo(Context &ctx, ox::StringParam filePath, ox::StringParam navArgs) noexcept {
ox::String path = std::move(filePath); ox::String path = std::move(filePath);
if (keel::isUuidUrl(path)) { if (beginsWith(path, "uuid://")) {
auto const [p, err] = keel::uuidUrlToPath(keelCtx(ctx), path); auto const [p, err] = keel::uuidUrlToPath(keelCtx(ctx), path);
if (err) { if (err) {
return; return;
} }
path = p; path = p;
} }
//if (
// auto const [np, err] = ctx.navStack.back();
// !err && np->filePath == path && np->navArgs == navArgs.view()) {
// return;
//}
ctx.navStack.resize(ctx.navIdx + 1); ctx.navStack.resize(ctx.navIdx + 1);
ctx.navStack.emplace_back(ox::String{path}, ox::String{navArgs.view()}); ctx.navStack.emplace_back(ox::String{path}, ox::String{navArgs.view()});
try { try {
@@ -54,9 +49,8 @@ void navigateBack(Context &ctx) noexcept {
} }
void navigateForward(Context &ctx) noexcept { void navigateForward(Context &ctx) noexcept {
auto const nextIdx = ctx.navIdx + 1; while (ctx.navIdx < ctx.navStack.size()) {
while (nextIdx < ctx.navStack.size()) { auto const &n = ctx.navStack[ctx.navIdx];
auto const &n = ctx.navStack[nextIdx];
try { try {
ctx.navCallback(n.filePath, n.navArgs); ctx.navCallback(n.filePath, n.navArgs);
} catch (std::exception const &e) { } catch (std::exception const &e) {
@@ -64,7 +58,7 @@ void navigateForward(Context &ctx) noexcept {
oxErrf("navigateForward failed: {}", e.what()); oxErrf("navigateForward failed: {}", e.what());
} }
if (!ctx.project->exists(n.filePath)) { if (!ctx.project->exists(n.filePath)) {
std::ignore = ctx.navStack.erase(nextIdx); std::ignore = ctx.navStack.erase(ctx.navIdx);
continue; continue;
} }
++ctx.navIdx; ++ctx.navIdx;