Squashed 'deps/nostalgia/' changes from 3c7652ef..161640fa
161640fa [nostalgia] Cleanup e42126c9 [nostalgia/core] Improve TileSheet validation, add repair 36942cca [nostalgia,olympic] Replace SpanView with Span<const T> b14f1d50 [ox] Replace SpanView with Span<const T> 1bf4f246 [applib] Make run take args as a SpanView edda8e01 [ox/clargs] Add constructor that takes a SpanView 3308b4dd [ox/std] Add missing + and += operators to Span 27f4703a [teagba] Suppress warnings for unsafe buffers 6af00d9a [nostalgia] Enable warnings for unsafe buffers 86b9f931 [olympic] Enable warnings for unsafe buffers a0ed1b3f [ox/std] Fix Span raw array constructor 8dad624b [studio/applib] Cleanup dc6605fd [keel] Add missing error checking to pack c78d3cf6 [ox] Add more unsafe buffer exceptions cee4f65d [ox/std] Replace an unsafe buffer cd3eeeef [ox/fs] Suppress unsafe buffer warnings 287d42f2 [ox/clargs] Cleanup dbbaaa46 [ox/clargs] Enable unsafe buffer warnings 9b8a8c4e [ox/std] Enable unsafe buffer warnings e44fa288 [cityhash] Add pragmas to ignore unsafe buffer warnings e13c6e81 [ox/std] Remove raw char* CharBufferWriter constructor cb55b31a [ox/std] Cleanup ab3f9e16 [ox/std] Make Span access check message consistent with other messages 8f25ef96 [ox/std] Make CharBufferWriter constructor take a Span e13eebaf [ox/std] Cleanup an unsafe buffer 114f5c66 [ox/std] Add overflow checking to SpanIterator df44fe23 [keel] Cleanup 72f4db3d [nostalgia/core/studio] Fix paste command to never paste beyond target dimensions 8a9ff971 [nostalgia/core] Fix resizeSubsheet to work for both growing and shrinking 5a8da59d [keel] Fix readAsset to actually return asset afa3a13d [keel] Cleanup 6522cf8a [keel] Add ensureValid call to readAsset f772e48b [ox] Add Vector/Array/Span overflow checking 13bfe881 [nostalgia/core] Fix resizeSubsheet array overflow 50254754 Merge commit '9e11019b87ba27d1dac9e097dc212a126e404218' bfe890ae [ox] Fix typo in docs ab5bc1ad [ox/std] Remove oxRequireT and oxRequireMT abf7548a [nostalgia/core] Add missing include e2682b5e [studio/modlib] Add missing include 792ad414 [nostalgia] Remove .vs dir git-subtree-dir: deps/nostalgia git-subtree-split: 161640fa11986677dc2e1da6ffd4575e38ab31ad
This commit is contained in:
parent
9e11019b87
commit
4ccdfc3a6e
@ -1,44 +0,0 @@
|
||||
{
|
||||
"version": "0.2.1",
|
||||
"defaults": {},
|
||||
"configurations": [
|
||||
{
|
||||
"type": "default",
|
||||
"project": "CMakeLists.txt",
|
||||
"projectTarget": "nostalgia.exe (Install)",
|
||||
"name": "nostalgia.exe (Install)",
|
||||
"args": [
|
||||
"${projectDir}/sample_project"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "default",
|
||||
"project": "CMakeLists.txt",
|
||||
"projectTarget": "nostalgia.exe",
|
||||
"name": "nostalgia.exe",
|
||||
"args": [
|
||||
"${projectDir}/sample_project"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "default",
|
||||
"project": "CMakeLists.txt",
|
||||
"projectTarget": "nostalgia-studio.exe (Install)",
|
||||
"name": "nostalgia-studio.exe (Install)",
|
||||
"args": [
|
||||
"-profile",
|
||||
"${projectDir}/src/nostalgia/studio/nostalgia-studio-dev.json"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "default",
|
||||
"project": "CMakeLists.txt",
|
||||
"projectTarget": "nostalgia-studio.exe",
|
||||
"name": "nostalgia-studio.exe",
|
||||
"args": [
|
||||
"-profile",
|
||||
"${projectDir}/src/nostalgia/studio/nostalgia-studio-dev.json"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
@ -104,6 +104,11 @@ using size_t = decltype(alignof(int));
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
|
||||
#endif
|
||||
|
||||
namespace cityhash::detail {
|
||||
|
||||
template<typename T>
|
||||
@ -671,4 +676,8 @@ constexpr uint128 CityHash128(const char *s, size_t len) noexcept {
|
||||
|
||||
}
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif // CITY_HASH_H_
|
||||
|
10
deps/ox/ox-docs.md
vendored
10
deps/ox/ox-docs.md
vendored
@ -176,14 +176,10 @@ ox::Result<int> f2() noexcept {
|
||||
```
|
||||
```oxRequire``` is not quite as versatile, but it should still cleanup a lot of otherwise less ideal code.
|
||||
|
||||
```oxRequire``` also has variants for throwing the error and for making to value non-const:
|
||||
```oxRequire``` by default creates a const, but there is also an ```oxRequireM``` (oxRequire Mutable)
|
||||
variant for creating a non-const value.
|
||||
|
||||
* ```oxRequireM``` - oxRequire Mutable
|
||||
* ```oxRequireT``` - oxRequire Throw
|
||||
* ```oxRequireMT``` - oxRequire Mutable Throw
|
||||
|
||||
The throw variants of ```oxRequire``` are generally legacy code.
|
||||
```ox::Result::unwrapThrow``` is generally preferred now.
|
||||
|
||||
### Logging and Output
|
||||
|
||||
@ -207,7 +203,7 @@ never be checked in.
|
||||
```oxError``` always prints.
|
||||
It includes file and line, and is prefixed with a red "ERROR:".
|
||||
It should generally be used conservatively.
|
||||
It shuld be used only when there is an error that is not technically fatal, but
|
||||
It should be used only when there is an error that is not technically fatal, but
|
||||
the user almost certainly wants to know about it.
|
||||
|
||||
```oxTrace``` and ```oxTracef```:
|
||||
|
7
deps/ox/src/ox/clargs/CMakeLists.txt
vendored
7
deps/ox/src/ox/clargs/CMakeLists.txt
vendored
@ -1,4 +1,9 @@
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang")
|
||||
# enable warnings
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wunsafe-buffer-usage")
|
||||
endif()
|
||||
|
||||
|
||||
add_library(
|
||||
OxClArgs
|
||||
|
12
deps/ox/src/ox/clargs/clargs.cpp
vendored
12
deps/ox/src/ox/clargs/clargs.cpp
vendored
@ -11,16 +11,18 @@
|
||||
|
||||
namespace ox {
|
||||
|
||||
ClArgs::ClArgs(int argc, const char **args) noexcept {
|
||||
for (auto i = 0u; i < static_cast<unsigned>(argc); ++i) {
|
||||
auto arg = String(args[i]);
|
||||
ClArgs::ClArgs(int argc, const char **args) noexcept: ClArgs({args, static_cast<size_t>(argc)}) {}
|
||||
|
||||
ClArgs::ClArgs(ox::SpanView<const char*> args) noexcept {
|
||||
for (auto i = 0u; i < args.size(); ++i) {
|
||||
auto arg = StringView(args[i]);
|
||||
if (arg[0] == '-') {
|
||||
while (arg[0] == '-' && arg.len()) {
|
||||
arg = arg.substr(1);
|
||||
arg = substr(arg, 1);
|
||||
}
|
||||
m_bools[arg] = true;
|
||||
// parse additional arguments
|
||||
if (i < static_cast<unsigned>(argc) && args[i + 1]) {
|
||||
if (i < args.size() && args[i + 1]) {
|
||||
auto val = String(args[i + 1]);
|
||||
if (val.len() && val[i] != '-') {
|
||||
if (val == "false") {
|
||||
|
3
deps/ox/src/ox/clargs/clargs.hpp
vendored
3
deps/ox/src/ox/clargs/clargs.hpp
vendored
@ -9,6 +9,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <ox/std/hashmap.hpp>
|
||||
#include <ox/std/span.hpp>
|
||||
#include <ox/std/string.hpp>
|
||||
|
||||
namespace ox {
|
||||
@ -22,6 +23,8 @@ class ClArgs {
|
||||
public:
|
||||
ClArgs(int argc, const char **args) noexcept;
|
||||
|
||||
ClArgs(ox::SpanView<const char*> args) noexcept;
|
||||
|
||||
[[nodiscard]]
|
||||
bool getBool(ox::StringViewCR arg, bool defaultValue) const noexcept;
|
||||
|
||||
|
4
deps/ox/src/ox/fs/CMakeLists.txt
vendored
4
deps/ox/src/ox/fs/CMakeLists.txt
vendored
@ -1,3 +1,7 @@
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang")
|
||||
# enable warnings
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wunsafe-buffer-usage")
|
||||
endif()
|
||||
|
||||
add_library(
|
||||
OxFS
|
||||
|
@ -10,6 +10,8 @@
|
||||
|
||||
#include <ox/fs/ptrarith/nodebuffer.hpp>
|
||||
|
||||
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
|
||||
|
||||
namespace ox {
|
||||
|
||||
using InodeId_t = uint64_t;
|
||||
@ -771,3 +773,5 @@ using FileStore16 = FileStoreTemplate<uint16_t>;
|
||||
using FileStore32 = FileStoreTemplate<uint32_t>;
|
||||
|
||||
}
|
||||
|
||||
OX_CLANG_NOWARN_END
|
||||
|
4
deps/ox/src/ox/fs/filesystem/directory.hpp
vendored
4
deps/ox/src/ox/fs/filesystem/directory.hpp
vendored
@ -15,6 +15,8 @@
|
||||
|
||||
#include "types.hpp"
|
||||
|
||||
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
|
||||
|
||||
namespace ox {
|
||||
|
||||
template<typename InodeId_t>
|
||||
@ -333,3 +335,5 @@ using Directory16 = Directory<FileStore16, uint16_t>;
|
||||
using Directory32 = Directory<FileStore32, uint32_t>;
|
||||
|
||||
}
|
||||
|
||||
OX_CLANG_NOWARN_END
|
||||
|
@ -32,7 +32,9 @@ FileAddress::FileAddress(ox::StringViewCR path) noexcept {
|
||||
auto pathSize = path.bytes();
|
||||
m_data.path = new char[pathSize + 1];
|
||||
memcpy(m_data.path, path.data(), pathSize);
|
||||
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
|
||||
m_data.path[pathSize] = 0;
|
||||
OX_CLANG_NOWARN_END
|
||||
m_type = FileAddressType::Path;
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,8 @@
|
||||
#include <ox/model/typenamecatcher.hpp>
|
||||
#include <ox/model/types.hpp>
|
||||
|
||||
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
|
||||
|
||||
namespace ox {
|
||||
|
||||
enum class FileAddressType: int8_t {
|
||||
@ -180,3 +182,5 @@ constexpr Error model(T *h, CommonPtrWith<FileAddress> auto *fa) noexcept {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
OX_CLANG_NOWARN_END
|
||||
|
@ -11,6 +11,8 @@
|
||||
#include <ox/std/trace.hpp>
|
||||
#include "pathiterator.hpp"
|
||||
|
||||
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
|
||||
|
||||
namespace ox {
|
||||
|
||||
PathIterator::PathIterator(const char *path, std::size_t maxSize, std::size_t iterator) {
|
||||
@ -30,7 +32,7 @@ PathIterator::PathIterator(StringViewCR path): PathIterator(path.data(), path.by
|
||||
*/
|
||||
Error PathIterator::dirPath(char *out, std::size_t outSize) {
|
||||
const auto idx = ox::lastIndexOf(m_path, '/', m_maxSize);
|
||||
const auto size = static_cast<std::size_t>(idx + 1);
|
||||
const auto size = static_cast<std::size_t>(idx) + 1;
|
||||
if (idx >= 0 && size < outSize) {
|
||||
ox::memcpy(out, m_path, size);
|
||||
out[size] = 0;
|
||||
@ -183,3 +185,5 @@ const char *PathIterator::fullPath() const {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
OX_CLANG_NOWARN_END
|
||||
|
4
deps/ox/src/ox/fs/ptrarith/nodebuffer.hpp
vendored
4
deps/ox/src/ox/fs/ptrarith/nodebuffer.hpp
vendored
@ -13,6 +13,8 @@
|
||||
|
||||
#include "ptr.hpp"
|
||||
|
||||
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
|
||||
|
||||
namespace ox::ptrarith {
|
||||
|
||||
template<typename size_t, typename Item>
|
||||
@ -449,3 +451,5 @@ struct OX_PACKED Item {
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
OX_CLANG_NOWARN_END
|
||||
|
4
deps/ox/src/ox/fs/ptrarith/ptr.hpp
vendored
4
deps/ox/src/ox/fs/ptrarith/ptr.hpp
vendored
@ -10,6 +10,8 @@
|
||||
|
||||
#include <ox/std/std.hpp>
|
||||
|
||||
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
|
||||
|
||||
namespace ox::ptrarith {
|
||||
|
||||
template<typename T, typename size_t, size_t minOffset = 1>
|
||||
@ -256,3 +258,5 @@ constexpr Result<Ptr<T, size_t, minOffset>> Ptr<T, size_t, minOffset>::validate(
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
OX_CLANG_NOWARN_END
|
||||
|
5
deps/ox/src/ox/fs/test/tests.cpp
vendored
5
deps/ox/src/ox/fs/test/tests.cpp
vendored
@ -226,13 +226,14 @@ const std::map<ox::StringView, std::function<ox::Error(ox::StringView)>> tests =
|
||||
},
|
||||
};
|
||||
|
||||
int main(int argc, const char **args) {
|
||||
int main(int argc, const char **argv) {
|
||||
if (argc < 2) {
|
||||
oxError("Must specify test to run");
|
||||
return -1;
|
||||
}
|
||||
auto const args = ox::Span{argv, static_cast<size_t>(argc)};
|
||||
ox::StringView const testName = args[1];
|
||||
ox::StringView const testArg = args[2] ? args[2] : nullptr;
|
||||
ox::StringView const testArg = argc >= 3 ? args[2] : nullptr;
|
||||
auto const func = tests.find(testName);
|
||||
if (func != tests.end()) {
|
||||
oxAssert(func->second(testArg), "Test returned Error");
|
||||
|
23
deps/ox/src/ox/fs/tool.cpp
vendored
23
deps/ox/src/ox/fs/tool.cpp
vendored
@ -39,25 +39,25 @@ static ox::Result<ox::UniquePtr<ox::FileSystem>> loadFs(const char *path) noexce
|
||||
return {ox::make_unique<ox::FileSystem32>(buff.data, buff.size)};
|
||||
}
|
||||
|
||||
static ox::Error runLs(ox::FileSystem *fs, int argc, const char **argv) noexcept {
|
||||
if (argc < 2) {
|
||||
static ox::Error runLs(ox::FileSystem *fs, ox::Span<const char*> args) noexcept {
|
||||
if (args.size() < 2) {
|
||||
oxErr("Must provide a directory to ls\n");
|
||||
return OxError(1);
|
||||
}
|
||||
oxRequire(files, fs->ls(argv[1]));
|
||||
oxRequire(files, fs->ls(args[1]));
|
||||
for (const auto &file : files) {
|
||||
oxOutf("{}\n", file);
|
||||
}
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
static ox::Error runRead(ox::FileSystem *fs, int argc, const char **argv) noexcept {
|
||||
if (argc < 2) {
|
||||
static ox::Error runRead(ox::FileSystem *fs, ox::Span<const char*> args) noexcept {
|
||||
if (args.size() < 2) {
|
||||
oxErr("Must provide a path to a file to read\n");
|
||||
return OxError(1);
|
||||
}
|
||||
oxRequire(buff, fs->read(ox::StringView(argv[1])));
|
||||
fwrite(buff.data(), sizeof(decltype(buff)::value_type), buff.size(), stdout);
|
||||
oxRequire(buff, fs->read(ox::StringView(args[1])));
|
||||
std::ignore = fwrite(buff.data(), sizeof(decltype(buff)::value_type), buff.size(), stdout);
|
||||
return OxError(0);
|
||||
}
|
||||
|
||||
@ -66,13 +66,14 @@ static ox::Error run(int argc, const char **argv) noexcept {
|
||||
oxErr("OxFS file and subcommand arguments are required\n");
|
||||
return OxError(1);
|
||||
}
|
||||
const auto fsPath = argv[1];
|
||||
ox::String subCmd(argv[2]);
|
||||
auto const args = ox::Span{argv, static_cast<size_t>(argc)};
|
||||
auto const fsPath = args[1];
|
||||
ox::String subCmd(args[2]);
|
||||
oxRequire(fs, loadFs(fsPath));
|
||||
if (subCmd == "ls") {
|
||||
return runLs(fs.get(), argc - 2, argv + 2);
|
||||
return runLs(fs.get(), args + 2);
|
||||
} else if (subCmd == "read") {
|
||||
return runRead(fs.get(), argc - 2, argv + 2);
|
||||
return runRead(fs.get(), args + 2);
|
||||
}
|
||||
return OxError(1);
|
||||
}
|
||||
|
4
deps/ox/src/ox/logconn/circularbuff.hpp
vendored
4
deps/ox/src/ox/logconn/circularbuff.hpp
vendored
@ -45,6 +45,7 @@ class CirculerBuffer {
|
||||
if (sz > avail()) {
|
||||
return OxError(1, "Insufficient space in buffer");
|
||||
}
|
||||
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
|
||||
// write seg 1
|
||||
const auto seg1Sz = ox::min(sz, m_buff.size() - m_writePt);
|
||||
ox::listcpy(&m_buff[m_writePt], &buff[0], seg1Sz);
|
||||
@ -56,6 +57,7 @@ class CirculerBuffer {
|
||||
ox::listcpy(&m_buff[0], &buff[seg1Sz], seg2Sz);
|
||||
oxAssert(m_buff[0] == buff[seg1Sz], "break");
|
||||
}
|
||||
OX_ALLOW_UNSAFE_BUFFERS_END
|
||||
return {};
|
||||
}
|
||||
|
||||
@ -90,7 +92,9 @@ class CirculerBuffer {
|
||||
m_readPt -= m_buff.size();
|
||||
// read seg 2
|
||||
const auto seg2Sz = bytesRead - seg1Sz;
|
||||
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
|
||||
ox::listcpy(&out[seg1Sz], &m_buff[0], seg2Sz);
|
||||
OX_ALLOW_UNSAFE_BUFFERS_END
|
||||
}
|
||||
return bytesRead;
|
||||
}
|
||||
|
28
deps/ox/src/ox/logconn/logconn.cpp
vendored
28
deps/ox/src/ox/logconn/logconn.cpp
vendored
@ -9,8 +9,8 @@
|
||||
#ifdef OX_USE_STDLIB
|
||||
#include <cstdio>
|
||||
|
||||
#include <sys/types.h>
|
||||
#ifndef _WIN32
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
@ -25,15 +25,22 @@
|
||||
|
||||
#include "logconn.hpp"
|
||||
|
||||
#include <ox/std/bit.hpp>
|
||||
|
||||
namespace ox {
|
||||
|
||||
#ifdef _WIN32
|
||||
using Socket = SOCKET;
|
||||
using LenType = int;
|
||||
#else
|
||||
using Socket = int;
|
||||
using LenType = size_t;
|
||||
#endif
|
||||
|
||||
using namespace trace;
|
||||
|
||||
void closeSock(auto s) noexcept {
|
||||
static void closeSock(auto s) noexcept {
|
||||
#ifdef _WIN32
|
||||
closesocket(s);
|
||||
closesocket(static_cast<Socket>(s));
|
||||
#else
|
||||
close(s);
|
||||
#endif
|
||||
@ -56,8 +63,8 @@ ox::Error LoggerConn::initConn(ox::StringViewCR appName) noexcept {
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
addr.sin_port = htons(5590);
|
||||
m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
oxReturnError(OxError(static_cast<ox::ErrorCode>(connect(m_socket, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)))));
|
||||
m_socket = static_cast<int>(socket(AF_INET, SOCK_STREAM, IPPROTO_TCP));
|
||||
oxReturnError(OxError(static_cast<ox::ErrorCode>(connect(static_cast<Socket>(m_socket), reinterpret_cast<sockaddr*>(&addr), sizeof(addr)))));
|
||||
return sendInit({.appName = ox::BasicString<128>(appName)});
|
||||
}
|
||||
|
||||
@ -65,9 +72,9 @@ ox::Error LoggerConn::send(const char *buff, std::size_t len) const noexcept {
|
||||
std::size_t totalSent = 0;
|
||||
while (totalSent < len) {
|
||||
//std::fprintf(stdout, "Sending %lu/%lu bytes on socket %d\n", len, totalSent, m_socket);
|
||||
const auto sent = ::send(m_socket, buff, len, 0);
|
||||
const auto sent = ::send(static_cast<Socket>(m_socket), buff, static_cast<LenType>(len), 0);
|
||||
if (sent < 0) {
|
||||
std::fprintf(stderr, "Could not send msg\n");
|
||||
std::ignore = std::fprintf(stderr, "Could not send msg\n");
|
||||
return OxError(1, "Could not send msg");
|
||||
}
|
||||
totalSent += static_cast<std::size_t>(sent);
|
||||
@ -90,13 +97,14 @@ void LoggerConn::msgSend() noexcept {
|
||||
if (!m_running) {
|
||||
break;
|
||||
}
|
||||
std::lock_guard buffLk(m_buffMut);
|
||||
std::lock_guard const buffLk(m_buffMut);
|
||||
while (true) {
|
||||
ox::Array<char, ox::units::KB> tmp;
|
||||
Array<char, units::KB> tmp;
|
||||
const auto read = m_buff.read(tmp.data(), tmp.size());
|
||||
if (!read) {
|
||||
break;
|
||||
}
|
||||
oxAssert(read <= tmp.size(), "logger trying to read too much data");
|
||||
//std::printf("LoggerConn: sending %lu bytes\n", read);
|
||||
std::ignore = send(tmp.data(), read);
|
||||
}
|
||||
|
10
deps/ox/src/ox/mc/intops.hpp
vendored
10
deps/ox/src/ox/mc/intops.hpp
vendored
@ -57,7 +57,7 @@ static_assert(highestBit(uint64_t(1) << 31) == 31);
|
||||
static_assert(highestBit(uint64_t(1) << 63) == 63);
|
||||
|
||||
struct McInt {
|
||||
uint8_t data[9] = {};
|
||||
ox::Array<uint8_t, 9> data{};
|
||||
// length of integer in bytes
|
||||
std::size_t length = 0;
|
||||
};
|
||||
@ -104,7 +104,7 @@ constexpr McInt encodeInteger(I pInput) noexcept {
|
||||
auto intermediate =
|
||||
static_cast<uint64_t>(leVal.raw() | (negBit << (valBits - 1))) << bytes |
|
||||
static_cast<uint64_t>(bytesIndicator);
|
||||
ox::memcpy(out.data, &intermediate, sizeof(intermediate));
|
||||
ox::memcpy(&out.data[0], &intermediate, sizeof(intermediate));
|
||||
}
|
||||
out.length = bytes;
|
||||
}
|
||||
@ -160,7 +160,7 @@ constexpr Result<I> decodeInteger(Reader_c auto&rdr, std::size_t *bytesRead) noe
|
||||
ox::Array<uint32_t, 2> d = {};
|
||||
//d[0] = decoded & 0xffff'ffff;
|
||||
//d[1] = decoded >> 32;
|
||||
ox::memcpy(d.data(), &decoded, sizeof(decoded));
|
||||
ox::memcpy(&d[0], &decoded, sizeof(decoded));
|
||||
auto bit = negBit;
|
||||
for (; bit < ox::min<std::size_t>(Bits<I>, 32); ++bit) {
|
||||
d[0] |= 1 << bit;
|
||||
@ -175,7 +175,7 @@ constexpr Result<I> decodeInteger(Reader_c auto&rdr, std::size_t *bytesRead) noe
|
||||
d[0] = d[1];
|
||||
d[1] = d0Tmp;
|
||||
}
|
||||
ox::memcpy(&out, d.data(), sizeof(out));
|
||||
ox::memcpy(&out, &d[0], sizeof(out));
|
||||
return out;
|
||||
}
|
||||
}
|
||||
@ -185,7 +185,7 @@ constexpr Result<I> decodeInteger(Reader_c auto&rdr, std::size_t *bytesRead) noe
|
||||
template<typename I>
|
||||
Result<I> decodeInteger(McInt m) noexcept {
|
||||
std::size_t bytesRead{};
|
||||
BufferReader br({reinterpret_cast<const char*>(m.data), 9});
|
||||
BufferReader br({reinterpret_cast<const char*>(m.data.data()), 9});
|
||||
return decodeInteger<I>(br, &bytesRead);
|
||||
}
|
||||
|
||||
|
2
deps/ox/src/ox/mc/presenceindicator.hpp
vendored
2
deps/ox/src/ox/mc/presenceindicator.hpp
vendored
@ -147,11 +147,13 @@ constexpr FieldBitmap::FieldBitmap(uint8_t *map, std::size_t maxLen) noexcept:
|
||||
|
||||
constexpr Error FieldBitmap::set(std::size_t i, bool on) noexcept {
|
||||
if (i / 8 < m_mapLen) {
|
||||
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
|
||||
if (on) {
|
||||
m_map[i / 8] |= 1 << (i % 8);
|
||||
} else {
|
||||
m_map[i / 8] &= ~static_cast<uint8_t>(1 << (i % 8));
|
||||
}
|
||||
OX_ALLOW_UNSAFE_BUFFERS_END
|
||||
return {};
|
||||
} else {
|
||||
return OxError(McPresenceMapOverflow);
|
||||
|
10
deps/ox/src/ox/mc/read.hpp
vendored
10
deps/ox/src/ox/mc/read.hpp
vendored
@ -214,7 +214,9 @@ constexpr Error MetalClawReaderTemplate<Reader>::field(const char *name, auto *v
|
||||
auto &handler = *reader.interface();
|
||||
oxReturnError(handler.setTypeInfo("List", 0, {}, static_cast<std::size_t>(len)));
|
||||
for (std::size_t i = 0; i < len; ++i) {
|
||||
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
|
||||
oxReturnError(handler.field({}, &val[i]));
|
||||
OX_ALLOW_UNSAFE_BUFFERS_END
|
||||
}
|
||||
} else {
|
||||
oxTracef("ox.mc.read.field(T)", "{}, length: {}", name, valLen);
|
||||
@ -380,9 +382,9 @@ constexpr Error MetalClawReaderTemplate<Reader>::fieldCString(const char*, char
|
||||
// re-allocate in case too small
|
||||
safeDelete(*val);
|
||||
*val = new char[size + 1];
|
||||
auto data = *val;
|
||||
auto data = ox::Span{*val, size + 1};
|
||||
// read the string
|
||||
oxReturnError(m_reader.read(data, size));
|
||||
oxReturnError(m_reader.read(data.data(), size));
|
||||
data[size] = 0;
|
||||
}
|
||||
++m_field;
|
||||
@ -402,9 +404,9 @@ constexpr Error MetalClawReaderTemplate<Reader>::fieldCString(const char*, char
|
||||
*val = new char[size + 1];
|
||||
buffLen = size + 1;
|
||||
}
|
||||
auto data = *val;
|
||||
auto data = ox::Span{*val, size + 1};
|
||||
// read the string
|
||||
oxReturnError(m_reader.read(data, size));
|
||||
oxReturnError(m_reader.read(data.data(), size));
|
||||
data[size] = 0;
|
||||
} else {
|
||||
auto data = *val;
|
||||
|
16
deps/ox/src/ox/mc/write.hpp
vendored
16
deps/ox/src/ox/mc/write.hpp
vendored
@ -117,7 +117,7 @@ class MetalClawWriter {
|
||||
bool fieldSet = false;
|
||||
if (val && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) {
|
||||
auto mi = mc::encodeInteger(val);
|
||||
oxReturnError(m_writer.write(reinterpret_cast<const char*>(mi.data), mi.length));
|
||||
oxReturnError(m_writer.write(reinterpret_cast<const char*>(mi.data.data()), mi.length));
|
||||
fieldSet = true;
|
||||
}
|
||||
oxReturnError(m_fieldPresence.set(static_cast<std::size_t>(m_field), fieldSet));
|
||||
@ -194,7 +194,7 @@ constexpr Error MetalClawWriter<Writer>::field(const char*, const BasicString<Sm
|
||||
if (val->len() && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) {
|
||||
// write the length
|
||||
const auto strLen = mc::encodeInteger(val->len());
|
||||
oxReturnError(m_writer.write(reinterpret_cast<const char*>(strLen.data), strLen.length));
|
||||
oxReturnError(m_writer.write(reinterpret_cast<const char*>(strLen.data.data()), strLen.length));
|
||||
// write the string
|
||||
oxReturnError(m_writer.write(val->c_str(), static_cast<std::size_t>(val->len())));
|
||||
fieldSet = true;
|
||||
@ -217,7 +217,7 @@ constexpr Error MetalClawWriter<Writer>::fieldCString(const char*, const char *c
|
||||
const auto strLen = *val ? ox::strlen(*val) : 0;
|
||||
// write the length
|
||||
const auto strLenBuff = mc::encodeInteger(strLen);
|
||||
oxReturnError(m_writer.write(reinterpret_cast<const char*>(strLenBuff.data), strLenBuff.length));
|
||||
oxReturnError(m_writer.write(reinterpret_cast<const char*>(strLenBuff.data.data()), strLenBuff.length));
|
||||
// write the string
|
||||
oxReturnError(m_writer.write(*val, static_cast<std::size_t>(strLen)));
|
||||
fieldSet = true;
|
||||
@ -243,7 +243,7 @@ constexpr Error MetalClawWriter<Writer>::fieldCString(const char*, const char *v
|
||||
if (strLen && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) {
|
||||
// write the length
|
||||
const auto strLenBuff = mc::encodeInteger(strLen);
|
||||
oxReturnError(m_writer.write(reinterpret_cast<const char*>(strLenBuff.data), strLenBuff.length));
|
||||
oxReturnError(m_writer.write(reinterpret_cast<const char*>(strLenBuff.data.data()), strLenBuff.length));
|
||||
// write the string
|
||||
oxReturnError(m_writer.write(val, static_cast<std::size_t>(strLen)));
|
||||
fieldSet = true;
|
||||
@ -298,14 +298,16 @@ constexpr Error MetalClawWriter<Writer>::field(const char*, const T *val, std::s
|
||||
if (len && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) {
|
||||
// write the length
|
||||
const auto arrLen = mc::encodeInteger(len);
|
||||
oxReturnError(m_writer.write(reinterpret_cast<const char*>(arrLen.data), arrLen.length));
|
||||
oxReturnError(m_writer.write(reinterpret_cast<const char*>(arrLen.data.data()), arrLen.length));
|
||||
auto const writeIdx = m_writer.tellp();
|
||||
MetalClawWriter<Writer> writer(m_writer);
|
||||
ModelHandlerInterface handler{&writer};
|
||||
oxReturnError(handler.template setTypeInfo<T>("List", 0, {}, static_cast<std::size_t>(len)));
|
||||
// write the array
|
||||
for (std::size_t i = 0; i < len; ++i) {
|
||||
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
|
||||
oxReturnError(handler.field("", &val[i]));
|
||||
OX_ALLOW_UNSAFE_BUFFERS_END
|
||||
}
|
||||
oxReturnError(writer.finalize());
|
||||
fieldSet = writeIdx != m_writer.tellp();
|
||||
@ -324,7 +326,7 @@ constexpr Error MetalClawWriter<Writer>::field(const char*, const HashMap<String
|
||||
if (len && (!m_unionIdx.has_value() || *m_unionIdx == m_field)) {
|
||||
// write the length
|
||||
const auto arrLen = mc::encodeInteger(len);
|
||||
oxReturnError(m_writer.write(reinterpret_cast<const char*>(arrLen.data), arrLen.length));
|
||||
oxReturnError(m_writer.write(reinterpret_cast<const char*>(arrLen.data.data()), arrLen.length));
|
||||
// write map
|
||||
MetalClawWriter<Writer> writer(m_writer);
|
||||
ModelHandlerInterface handler{&writer};
|
||||
@ -395,7 +397,7 @@ Result<Buffer> writeMC(auto const&val, std::size_t buffReserveSz = 2 * units::KB
|
||||
}
|
||||
|
||||
Error writeMC(char *buff, std::size_t buffLen, auto const&val, std::size_t *sizeOut = nullptr) noexcept {
|
||||
CharBuffWriter bw(buff, buffLen);
|
||||
CharBuffWriter bw{{buff, buffLen}};
|
||||
oxReturnError(writeMC(bw, val));
|
||||
if (sizeOut) {
|
||||
*sizeOut = bw.tellp();
|
||||
|
7
deps/ox/src/ox/model/desctypes.hpp
vendored
7
deps/ox/src/ox/model/desctypes.hpp
vendored
@ -90,7 +90,7 @@ constexpr Error model(T *io, CommonPtrWith<Subscript> auto *type) noexcept {
|
||||
}
|
||||
oxReturnError(io->field("length", &type->length));
|
||||
oxReturnError(io->field("smallSzLen", &type->smallSzLen));
|
||||
return OxError(0);
|
||||
return {};
|
||||
}
|
||||
|
||||
using SubscriptStack = Vector<Subscript, 3>;
|
||||
@ -119,6 +119,7 @@ struct DescriptorField {
|
||||
subscriptLevels(pSubscriptLevels),
|
||||
subscriptStack(std::move(pSubscriptType)),
|
||||
typeId(std::move(pTypeId)) {
|
||||
oxAssert(subscriptLevels <= static_cast<int>(subscriptStack.size()), "Subscript level mismatch");
|
||||
}
|
||||
|
||||
constexpr DescriptorField(const DescriptorField &other) noexcept:
|
||||
@ -202,7 +203,7 @@ constexpr Error model(T *io, CommonPtrWith<DescriptorType> auto *type) noexcept
|
||||
oxReturnError(io->field("fieldList", &type->fieldList));
|
||||
oxReturnError(io->field("length", &type->length));
|
||||
oxReturnError(io->field("preloadable", &type->preloadable));
|
||||
return OxError(0);
|
||||
return {};
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@ -215,7 +216,7 @@ constexpr Error model(T *io, CommonPtrWith<DescriptorField> auto *field) noexcep
|
||||
// defaultValue is unused now, but leave placeholder for backwards compatibility
|
||||
int defaultValue = 0;
|
||||
oxReturnError(io->field("defaultValue", &defaultValue));
|
||||
return OxError(0);
|
||||
return {};
|
||||
}
|
||||
|
||||
template<typename ReaderBase>
|
||||
|
27
deps/ox/src/ox/model/descwrite.hpp
vendored
27
deps/ox/src/ox/model/descwrite.hpp
vendored
@ -97,8 +97,14 @@ class TypeDescWriter {
|
||||
std::size_t fields = ModelFieldCount_v<T>) noexcept;
|
||||
|
||||
template<typename T>
|
||||
constexpr Error field(StringViewCR name, const T *val, std::size_t valLen,
|
||||
const SubscriptStack &subscriptStack = {}) noexcept;
|
||||
constexpr Error field(
|
||||
StringViewCR name,
|
||||
T const*val,
|
||||
std::size_t valLen,
|
||||
SubscriptStack const&subscriptStack) noexcept;
|
||||
|
||||
template<typename T>
|
||||
constexpr Error field(StringViewCR name, T const*val, std::size_t valLen) noexcept;
|
||||
|
||||
template<typename T, bool force>
|
||||
constexpr Error field(StringViewCR name, UnionView<T, force> val) noexcept;
|
||||
@ -193,7 +199,7 @@ constexpr ox::Error TypeDescWriter::setTypeInfo(
|
||||
|
||||
// array handler
|
||||
template<typename T>
|
||||
constexpr Error TypeDescWriter::field(StringViewCR name, const T*, std::size_t, const SubscriptStack &subscriptStack) noexcept {
|
||||
constexpr Error TypeDescWriter::field(StringViewCR name, T const*, std::size_t, SubscriptStack const&subscriptStack) noexcept {
|
||||
if (m_type) {
|
||||
constexpr typename remove_pointer<T>::type *p = nullptr;
|
||||
const auto t = type(p);
|
||||
@ -204,6 +210,21 @@ constexpr Error TypeDescWriter::field(StringViewCR name, const T*, std::size_t,
|
||||
return OxError(1);
|
||||
}
|
||||
|
||||
// array handler
|
||||
template<typename T>
|
||||
constexpr Error TypeDescWriter::field(StringViewCR name, T const*, std::size_t) noexcept {
|
||||
if (m_type) {
|
||||
constexpr typename remove_pointer<T>::type *p = nullptr;
|
||||
const auto t = type(p);
|
||||
oxAssert(t != nullptr, "field(const char *name, T *val, std::size_t): Type not found or generated");
|
||||
auto const lvls = detail::indirectionLevels_v<T> + 1;
|
||||
SubscriptStack subscriptStack{lvls};
|
||||
m_type->fieldList.emplace_back(t, String(name), lvls, subscriptStack, buildTypeId(*t));
|
||||
return OxError(0);
|
||||
}
|
||||
return OxError(1);
|
||||
}
|
||||
|
||||
template<typename T, bool force>
|
||||
constexpr Error TypeDescWriter::field(StringViewCR name, UnionView<T, force> val) noexcept {
|
||||
if (m_type) {
|
||||
|
35
deps/ox/src/ox/model/modelvalue.hpp
vendored
35
deps/ox/src/ox/model/modelvalue.hpp
vendored
@ -188,8 +188,8 @@ class ModelValue {
|
||||
|
||||
constexpr Error setType(
|
||||
DescriptorType const*type,
|
||||
int subscriptLevels = 0,
|
||||
SubscriptStack const& = {}) noexcept;
|
||||
SubscriptStack const& = {},
|
||||
int subscriptLevels = 0) noexcept;
|
||||
|
||||
template<typename T>
|
||||
constexpr Error setType() noexcept;
|
||||
@ -242,7 +242,7 @@ class ModelValueArray {
|
||||
m_vec.resize(sz);
|
||||
if (sz > oldSz) {
|
||||
for (auto i = oldSz; i < sz; ++i) {
|
||||
oxReturnError(m_vec[i].setType(m_type, m_typeSubscriptLevels));
|
||||
oxReturnError(m_vec[i].setType(m_type, m_subscriptStack, m_typeSubscriptLevels));
|
||||
}
|
||||
}
|
||||
return {};
|
||||
@ -276,8 +276,9 @@ class ModelValueArray {
|
||||
|
||||
constexpr Error setType(
|
||||
DescriptorType const*type,
|
||||
int subscriptLevels,
|
||||
SubscriptStack subscriptStack) noexcept {
|
||||
SubscriptStack subscriptStack,
|
||||
int subscriptLevels) noexcept {
|
||||
oxAssert(subscriptLevels <= static_cast<int>(subscriptStack.size()), "subscript level mismatch");
|
||||
m_type = type;
|
||||
m_typeSubscriptLevels = subscriptLevels;
|
||||
m_subscriptStack = std::move(subscriptStack);
|
||||
@ -400,7 +401,7 @@ class ModelValueVector {
|
||||
m_vec.resize(sz);
|
||||
if (sz > oldSz) {
|
||||
for (auto i = oldSz; i < sz; ++i) {
|
||||
oxReturnError(m_vec[i].setType(m_type, m_typeSubscriptLevels, m_subscriptStack));
|
||||
oxReturnError(m_vec[i].setType(m_type, m_subscriptStack, m_typeSubscriptLevels));
|
||||
}
|
||||
}
|
||||
return {};
|
||||
@ -418,8 +419,9 @@ class ModelValueVector {
|
||||
|
||||
constexpr Error setType(
|
||||
DescriptorType const*type,
|
||||
int subscriptLevels,
|
||||
SubscriptStack subscriptStack) noexcept {
|
||||
SubscriptStack subscriptStack,
|
||||
int subscriptLevels) noexcept {
|
||||
oxAssert(subscriptLevels <= static_cast<int>(subscriptStack.size()), "subscript level mismatch");
|
||||
m_type = type;
|
||||
m_typeSubscriptLevels = subscriptLevels;
|
||||
m_subscriptStack = std::move(subscriptStack);
|
||||
@ -674,11 +676,11 @@ class ModelObject {
|
||||
for (const auto &f : type->fieldList) {
|
||||
auto field = make_unique<Field>();
|
||||
field->name = f.fieldName;
|
||||
oxReturnError(field->value.setType(f.type, f.subscriptLevels, f.subscriptStack));
|
||||
oxReturnError(field->value.setType(f.type, f.subscriptStack, f.subscriptLevels));
|
||||
m_fields[field->name] = &field->value;
|
||||
m_fieldsOrder.emplace_back(std::move(field));
|
||||
}
|
||||
return OxError(0);
|
||||
return {};
|
||||
}
|
||||
|
||||
};
|
||||
@ -797,12 +799,12 @@ class ModelUnion {
|
||||
auto field = make_unique<Field>();
|
||||
field->name = f.fieldName;
|
||||
field->idx = i;
|
||||
oxReturnError(field->value.setType(f.type, f.subscriptLevels));
|
||||
oxReturnError(field->value.setType(f.type, SubscriptStack{static_cast<size_t>(f.subscriptLevels)}, f.subscriptLevels));
|
||||
m_fields[field->name] = field.get();
|
||||
m_fieldsOrder.emplace_back(std::move(field));
|
||||
++i;
|
||||
}
|
||||
return OxError(0);
|
||||
return {};
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
@ -1076,20 +1078,21 @@ constexpr ModelValue::Type ModelValue::type() const noexcept {
|
||||
|
||||
constexpr Error ModelValue::setType(
|
||||
const DescriptorType *type,
|
||||
int subscriptLevels,
|
||||
SubscriptStack const&subscriptStack) noexcept {
|
||||
SubscriptStack const&subscriptStack,
|
||||
int subscriptLevels) noexcept {
|
||||
freeResources();
|
||||
oxAssert(subscriptLevels <= static_cast<int>(subscriptStack.size()), "subscript level mismatch");
|
||||
if (subscriptLevels) {
|
||||
auto const&subscript = subscriptStack[subscriptStack.size() - static_cast<size_t>(subscriptLevels)];
|
||||
if (subscript.subscriptType == Subscript::SubscriptType::InlineArray) {
|
||||
m_type = Type::InlineArray;
|
||||
m_data.array = new ModelValueArray;
|
||||
oxReturnError(m_data.array->setType(type, subscriptLevels - 1, subscriptStack));
|
||||
oxReturnError(m_data.array->setType(type, subscriptStack, subscriptLevels - 1));
|
||||
oxReturnError(m_data.array->setSize(static_cast<size_t>(subscript.length)));
|
||||
} else {
|
||||
m_type = Type::Vector;
|
||||
m_data.vec = new ModelValueVector;
|
||||
oxReturnError(m_data.vec->setType(type, subscriptLevels - 1, subscriptStack));
|
||||
oxReturnError(m_data.vec->setType(type, subscriptStack, subscriptLevels - 1));
|
||||
}
|
||||
return {};
|
||||
} else if (type->typeName == types::Bool) {
|
||||
|
4
deps/ox/src/ox/oc/read.hpp
vendored
4
deps/ox/src/ox/oc/read.hpp
vendored
@ -244,7 +244,9 @@ Error OrganicClawReader::field(const char *key, T *val, std::size_t valLen) noex
|
||||
OrganicClawReader r(srcVal);
|
||||
ModelHandlerInterface handler{&r};
|
||||
for (decltype(srcSize) i = 0; i < srcSize; ++i) {
|
||||
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
|
||||
oxReturnError(handler.field("", &val[i]));
|
||||
OX_ALLOW_UNSAFE_BUFFERS_END
|
||||
}
|
||||
return OxError(0);
|
||||
}
|
||||
@ -272,7 +274,9 @@ Error readOC(BufferView buff, auto &val) noexcept {
|
||||
Json::Value doc;
|
||||
Json::CharReaderBuilder parserBuilder;
|
||||
auto parser = UniquePtr<Json::CharReader>(parserBuilder.newCharReader());
|
||||
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
|
||||
if (!parser->parse(buff.data(), buff.data() + buff.size(), &doc, nullptr)) {
|
||||
OX_ALLOW_UNSAFE_BUFFERS_END
|
||||
return OxError(1, "Could not parse JSON");
|
||||
}
|
||||
OrganicClawReader reader(buff.data(), buff.size());
|
||||
|
2
deps/ox/src/ox/oc/write.hpp
vendored
2
deps/ox/src/ox/oc/write.hpp
vendored
@ -200,7 +200,9 @@ Error OrganicClawWriter::field(const char *key, const T *val, std::size_t len) n
|
||||
OrganicClawWriter w((Json::Value(Json::arrayValue)));
|
||||
ModelHandlerInterface<OrganicClawWriter, OpType::Write> handler{&w};
|
||||
for (std::size_t i = 0; i < len; ++i) {
|
||||
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
|
||||
oxReturnError(handler.field({}, &val[i]));
|
||||
OX_ALLOW_UNSAFE_BUFFERS_END
|
||||
}
|
||||
value(key) = w.m_json;
|
||||
}
|
||||
|
6
deps/ox/src/ox/std/CMakeLists.txt
vendored
6
deps/ox/src/ox/std/CMakeLists.txt
vendored
@ -1,3 +1,9 @@
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang")
|
||||
# enable warnings
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wunsafe-buffer-usage")
|
||||
endif()
|
||||
|
||||
|
||||
if(OX_USE_STDLIB AND OX_ENABLE_TRACEHOOK)
|
||||
add_library(
|
||||
OxTraceHook SHARED
|
||||
|
8
deps/ox/src/ox/std/algorithm.hpp
vendored
8
deps/ox/src/ox/std/algorithm.hpp
vendored
@ -8,6 +8,10 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "def.hpp"
|
||||
|
||||
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
|
||||
|
||||
namespace ox {
|
||||
|
||||
template<typename It, typename T>
|
||||
@ -40,4 +44,6 @@ constexpr OutIt copy_n(It in, Size cnt, OutIt out) {
|
||||
return out;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
OX_CLANG_NOWARN_END
|
||||
|
11
deps/ox/src/ox/std/array.hpp
vendored
11
deps/ox/src/ox/std/array.hpp
vendored
@ -9,6 +9,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "bit.hpp"
|
||||
#include "def.hpp"
|
||||
#include "error.hpp"
|
||||
#include "initializerlist.hpp"
|
||||
#include "iterator.hpp"
|
||||
@ -17,6 +18,8 @@
|
||||
#include "types.hpp"
|
||||
#include "utility.hpp"
|
||||
|
||||
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
|
||||
|
||||
namespace ox {
|
||||
|
||||
template<typename T, std::size_t ArraySize>
|
||||
@ -35,6 +38,10 @@ class Array {
|
||||
public:
|
||||
constexpr Array() noexcept = default;
|
||||
|
||||
template<typename ...Args>
|
||||
constexpr Array(Args ...list) noexcept: m_items{std::move(list)...} {
|
||||
}
|
||||
|
||||
constexpr Array(std::initializer_list<T> list) noexcept;
|
||||
|
||||
constexpr Array(const Array &other);
|
||||
@ -174,11 +181,13 @@ constexpr Array<T, ArraySize> &Array<T, ArraySize>::operator=(Array &&other) noe
|
||||
|
||||
template<typename T, std::size_t ArraySize>
|
||||
constexpr T &Array<T, ArraySize>::operator[](std::size_t i) noexcept {
|
||||
ox::primitiveAssert(__FILE__, __LINE__, i < size(), "Array access overflow");
|
||||
return m_items[i];
|
||||
}
|
||||
|
||||
template<typename T, std::size_t ArraySize>
|
||||
constexpr const T &Array<T, ArraySize>::operator[](std::size_t i) const noexcept {
|
||||
ox::primitiveAssert(__FILE__, __LINE__, i < size(), "Array access overflow");
|
||||
return m_items[i];
|
||||
}
|
||||
|
||||
@ -198,3 +207,5 @@ constexpr bool Array<T, ArraySize>::contains(const T &v) const {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
OX_CLANG_NOWARN_END
|
||||
|
39
deps/ox/src/ox/std/assert.cpp
vendored
39
deps/ox/src/ox/std/assert.cpp
vendored
@ -6,6 +6,7 @@
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include "fmt.hpp"
|
||||
#include "stacktrace.hpp"
|
||||
#include "trace.hpp"
|
||||
|
||||
@ -13,7 +14,7 @@
|
||||
|
||||
namespace ox {
|
||||
|
||||
void panic(const char *file, int line, const char *panicMsg, const Error &err) noexcept {
|
||||
void panic(StringViewCR file, int line, StringViewCR panicMsg, const Error &err) noexcept {
|
||||
oxErrf("\033[31;1;1mPANIC:\033[0m [{}:{}]: {}\n", file, line, panicMsg);
|
||||
if (err.msg) {
|
||||
oxErrf("\tError Message:\t{}\n", err.msg);
|
||||
@ -31,4 +32,40 @@ void panic(const char *file, int line, const char *panicMsg, const Error &err) n
|
||||
#endif
|
||||
}
|
||||
|
||||
void panic(const char *file, int line, const char *panicMsg, const Error &err) noexcept {
|
||||
panic(StringView{file}, line, StringView{panicMsg}, err);
|
||||
}
|
||||
|
||||
void assertFailFuncRuntime(StringViewCR file, int line, StringViewCR assertTxt, StringViewCR msg) noexcept {
|
||||
#ifdef OX_USE_STDLIB
|
||||
auto output = sfmt("\n\033[31;1;1mASSERT FAILURE:\033[0m [{}:{}]: {}\n", file, line, msg);
|
||||
output += genStackTrace(2);
|
||||
oxTracef("assert", "Failed assert: {} ({}) [{}:{}]", msg, assertTxt, file, line);
|
||||
std::abort();
|
||||
#else
|
||||
oxErrf("\n\033[31;1;1mASSERT FAILURE:\033[0m [{}:{}]: {}\n", file, line, msg);
|
||||
oxTracef("assert", "Failed assert: {} ({}) [{}:{}]", msg, assertTxt, file, line);
|
||||
constexprPanic(file, line, msg);
|
||||
#endif
|
||||
}
|
||||
|
||||
void assertFailFuncRuntime(StringViewCR file, int line, [[maybe_unused]] const Error &err, StringViewCR, StringViewCR assertMsg) noexcept {
|
||||
#if defined(OX_USE_STDLIB)
|
||||
auto msg = sfmt("\n\033[31;1;1mASSERT FAILURE:\033[0m [{}:{}]: {}\n", file, line, assertMsg);
|
||||
if (err.msg) {
|
||||
msg += sfmt("\tError Message:\t{}\n", err.msg);
|
||||
}
|
||||
msg += sfmt("\tError Code:\t{}\n", static_cast<ErrorCode>(err));
|
||||
if (err.file != nullptr) {
|
||||
msg += sfmt("\tError Location:\t{}:{}\n", err.file, err.line);
|
||||
}
|
||||
msg += genStackTrace(2);
|
||||
oxErr(msg);
|
||||
oxTracef("assert", "Failed assert: {} [{}:{}]", assertMsg, file, line);
|
||||
std::abort();
|
||||
#else
|
||||
constexprPanic(file, line, assertMsg);
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
31
deps/ox/src/ox/std/assert.hpp
vendored
31
deps/ox/src/ox/std/assert.hpp
vendored
@ -32,19 +32,13 @@ constexpr void constexprPanic(StringViewCR file, int line, StringViewCR panicMsg
|
||||
}
|
||||
}
|
||||
|
||||
void assertFailFuncRuntime(StringViewCR file, int line, StringViewCR assertTxt, StringViewCR msg) noexcept;
|
||||
void assertFailFuncRuntime(StringViewCR file, int line, const Error &err, StringViewCR, StringViewCR assertMsg) noexcept;
|
||||
|
||||
constexpr void assertFunc(StringViewCR file, int line, bool pass, [[maybe_unused]]StringViewCR assertTxt, [[maybe_unused]]StringViewCR msg) noexcept {
|
||||
if (!pass) {
|
||||
if (!std::is_constant_evaluated()) {
|
||||
#ifdef OX_USE_STDLIB
|
||||
auto output = sfmt("\n\033[31;1;1mASSERT FAILURE:\033[0m [{}:{}]: {}\n", file, line, msg);
|
||||
output += genStackTrace(2);
|
||||
oxTracef("assert", "Failed assert: {} ({}) [{}:{}]", msg, assertTxt, file, line);
|
||||
std::abort();
|
||||
#else
|
||||
oxErrf("\n\033[31;1;1mASSERT FAILURE:\033[0m [{}:{}]: {}\n", file, line, msg);
|
||||
oxTracef("assert", "Failed assert: {} ({}) [{}:{}]", msg, assertTxt, file, line);
|
||||
constexprPanic(file, line, msg);
|
||||
#endif
|
||||
assertFailFuncRuntime(file, line, assertTxt, msg);
|
||||
} else {
|
||||
while (true);
|
||||
}
|
||||
@ -54,22 +48,7 @@ constexpr void assertFunc(StringViewCR file, int line, bool pass, [[maybe_unused
|
||||
constexpr void assertFunc(StringViewCR file, int line, const Error &err, StringViewCR, StringViewCR assertMsg) noexcept {
|
||||
if (err) {
|
||||
if (!std::is_constant_evaluated()) {
|
||||
#if defined(OX_USE_STDLIB)
|
||||
auto msg = sfmt("\n\033[31;1;1mASSERT FAILURE:\033[0m [{}:{}]: {}\n", file, line, assertMsg);
|
||||
if (err.msg) {
|
||||
msg += sfmt("\tError Message:\t{}\n", err.msg);
|
||||
}
|
||||
msg += sfmt("\tError Code:\t{}\n", static_cast<ErrorCode>(err));
|
||||
if (err.file != nullptr) {
|
||||
msg += sfmt("\tError Location:\t{}:{}\n", err.file, err.line);
|
||||
}
|
||||
msg += genStackTrace(2);
|
||||
oxErr(msg);
|
||||
oxTracef("assert", "Failed assert: {} [{}:{}]", assertMsg, file, line);
|
||||
std::abort();
|
||||
#else
|
||||
constexprPanic(file, line, assertMsg);
|
||||
#endif
|
||||
assertFailFuncRuntime(file, line, err, {}, assertMsg);
|
||||
} else {
|
||||
while (true);
|
||||
}
|
||||
|
7
deps/ox/src/ox/std/basestringview.hpp
vendored
7
deps/ox/src/ox/std/basestringview.hpp
vendored
@ -9,9 +9,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "bit.hpp"
|
||||
#include "def.hpp"
|
||||
#include "cstrops.hpp"
|
||||
#include "iterator.hpp"
|
||||
|
||||
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
|
||||
|
||||
namespace ox::detail {
|
||||
|
||||
class BaseStringView {
|
||||
@ -202,7 +205,7 @@ class BaseStringView {
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr auto operator[](std::size_t i) const noexcept {
|
||||
constexpr auto &operator[](std::size_t i) const noexcept {
|
||||
return m_str[i];
|
||||
}
|
||||
|
||||
@ -215,3 +218,5 @@ class BaseStringView {
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
OX_CLANG_NOWARN_END
|
||||
|
12
deps/ox/src/ox/std/buffer.hpp
vendored
12
deps/ox/src/ox/std/buffer.hpp
vendored
@ -14,12 +14,14 @@
|
||||
#include "vector.hpp"
|
||||
#include "writer.hpp"
|
||||
|
||||
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
|
||||
|
||||
namespace ox {
|
||||
|
||||
extern template class Vector<char>;
|
||||
|
||||
using Buffer = Vector<char>;
|
||||
using BufferView = SpanView<char>;
|
||||
using BufferView = Span<const char>;
|
||||
|
||||
class BufferWriter {
|
||||
private:
|
||||
@ -100,15 +102,11 @@ class CharBuffWriter {
|
||||
char *m_buff = nullptr;
|
||||
|
||||
public:
|
||||
template<std::size_t sz>
|
||||
explicit constexpr CharBuffWriter(ox::Array<char, sz> &buff) noexcept:
|
||||
explicit constexpr CharBuffWriter(ox::Span<char> buff) noexcept:
|
||||
m_cap(buff.size()),
|
||||
m_buff(buff.data()) {
|
||||
}
|
||||
|
||||
explicit constexpr CharBuffWriter(char *buff, std::size_t size) noexcept: m_cap(size), m_buff(buff) {
|
||||
}
|
||||
|
||||
constexpr ox::Error seekp(std::size_t p) noexcept {
|
||||
m_it = p;
|
||||
return {};
|
||||
@ -237,3 +235,5 @@ extern template class WriterT<BufferWriter>;
|
||||
extern template class WriterT<CharBuffWriter>;
|
||||
|
||||
}
|
||||
|
||||
OX_CLANG_NOWARN_END
|
||||
|
5
deps/ox/src/ox/std/cstrops.hpp
vendored
5
deps/ox/src/ox/std/cstrops.hpp
vendored
@ -8,9 +8,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "def.hpp"
|
||||
#include "types.hpp"
|
||||
#include "typetraits.hpp"
|
||||
|
||||
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
|
||||
|
||||
namespace ox {
|
||||
|
||||
template<typename T1, typename T2>
|
||||
@ -113,3 +116,5 @@ constexpr int lastIndexOf(const auto &str, int character, std::size_t maxLen = 0
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
OX_CLANG_NOWARN_END
|
||||
|
19
deps/ox/src/ox/std/def.hpp
vendored
19
deps/ox/src/ox/std/def.hpp
vendored
@ -44,10 +44,6 @@
|
||||
// oxRequire Mutable
|
||||
#define oxRequireM(out, x) auto [out, oxConcat(oxRequire_err_, __LINE__)] = x; oxReturnError(oxConcat(oxRequire_err_, __LINE__))
|
||||
#define oxRequire(out, x) const oxRequireM(out, x)
|
||||
// oxRequire Mutable Throw
|
||||
#define oxRequireMT(out, x) auto [out, oxConcat(oxRequire_err_, __LINE__)] = x; oxThrowError(oxConcat(oxRequire_err_, __LINE__))
|
||||
// oxRequire Throw
|
||||
#define oxRequireT(out, x) const oxRequireMT(out, x)
|
||||
|
||||
|
||||
// Asserts
|
||||
@ -75,6 +71,21 @@ constexpr void oxAssert(const ox::Error&, const char*) noexcept {}
|
||||
#define ox_alloca(size) __builtin_alloca(size)
|
||||
#endif
|
||||
|
||||
#define OX_PRAGMA(x) _Pragma(#x)
|
||||
#ifdef __clang__
|
||||
#define OX_CLANG_NOWARN_BEGIN(warnoption) \
|
||||
OX_PRAGMA(clang diagnostic push) \
|
||||
OX_PRAGMA(clang diagnostic ignored #warnoption)
|
||||
#define OX_CLANG_NOWARN_END OX_PRAGMA(clang diagnostic pop)
|
||||
#define OX_ALLOW_UNSAFE_BUFFERS_BEGIN OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
|
||||
#define OX_ALLOW_UNSAFE_BUFFERS_END OX_CLANG_NOWARN_END
|
||||
#else
|
||||
#define OX_CLANG_NOWARN_BEGIN(warnoption)
|
||||
#define OX_CLANG_NOWARN_END
|
||||
#define OX_ALLOW_UNSAFE_BUFFERS_BEGIN
|
||||
#define OX_ALLOW_UNSAFE_BUFFERS_END
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @return an ox::MallocaPtr of the given type pointing to the requested size memory allocation
|
||||
*/
|
||||
|
9
deps/ox/src/ox/std/error.hpp
vendored
9
deps/ox/src/ox/std/error.hpp
vendored
@ -24,6 +24,7 @@ class exception {
|
||||
}
|
||||
#endif
|
||||
|
||||
#include "defines.hpp"
|
||||
#include "def.hpp"
|
||||
#include "typetraits.hpp"
|
||||
#include "utility.hpp"
|
||||
@ -332,4 +333,12 @@ constexpr Error toError(const Result<T> &r) noexcept {
|
||||
|
||||
}
|
||||
|
||||
constexpr void primitiveAssert(const char *file, int line, bool pass, const char *msg) noexcept {
|
||||
if constexpr(ox::defines::Debug) {
|
||||
if (!pass) [[unlikely]] {
|
||||
panic(file, line, msg, OxError(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
12
deps/ox/src/ox/std/fmt.hpp
vendored
12
deps/ox/src/ox/std/fmt.hpp
vendored
@ -25,6 +25,8 @@
|
||||
#include "types.hpp"
|
||||
#include "typetraits.hpp"
|
||||
|
||||
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
|
||||
|
||||
namespace ox {
|
||||
namespace detail {
|
||||
|
||||
@ -81,16 +83,16 @@ class FmtArg {
|
||||
|
||||
private:
|
||||
static constexpr auto DataSz = 23;
|
||||
char dataStr[DataSz] = {};
|
||||
ox::Array<char, DataSz> dataStr{};
|
||||
|
||||
template<typename T>
|
||||
constexpr StringView sv(const T &v, char *dataStr) noexcept {
|
||||
constexpr StringView sv(const T &v, ox::Span<char> dataStr) noexcept {
|
||||
if constexpr(is_bool_v<T>) {
|
||||
return v ? "true" : "false";
|
||||
} else if constexpr(is_integer_v<T>) {
|
||||
ox::CharBuffWriter w(dataStr, DataSz);
|
||||
ox::CharBuffWriter w{dataStr};
|
||||
std::ignore = ox::writeItoa(v, w);
|
||||
return dataStr;
|
||||
return dataStr.data();
|
||||
} else {
|
||||
return toStringView(v);
|
||||
}
|
||||
@ -225,3 +227,5 @@ constexpr Result<T> join(auto const&d, auto const&list) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
OX_CLANG_NOWARN_END
|
||||
|
5
deps/ox/src/ox/std/heapmgr.cpp
vendored
5
deps/ox/src/ox/std/heapmgr.cpp
vendored
@ -8,8 +8,11 @@
|
||||
|
||||
#include "assert.hpp"
|
||||
#include "bit.hpp"
|
||||
#include "def.hpp"
|
||||
#include "heapmgr.hpp"
|
||||
|
||||
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
|
||||
|
||||
namespace ox::heapmgr {
|
||||
|
||||
static struct HeapSegment *volatile g_heapBegin = nullptr;
|
||||
@ -142,3 +145,5 @@ void operator delete[](void *ptr, unsigned long int) noexcept {
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
OX_CLANG_NOWARN_END
|
||||
|
5
deps/ox/src/ox/std/istring.hpp
vendored
5
deps/ox/src/ox/std/istring.hpp
vendored
@ -10,6 +10,7 @@
|
||||
|
||||
#include "array.hpp"
|
||||
#include "concepts.hpp"
|
||||
#include "def.hpp"
|
||||
#include "cstrops.hpp"
|
||||
#include "memops.hpp"
|
||||
#include "error.hpp"
|
||||
@ -175,7 +176,9 @@ constexpr Error IString<StrCap>::append(const char *str, std::size_t strLen) noe
|
||||
strLen = cap() - currentLen;
|
||||
err = OxError(1, "Insufficient space for full string");
|
||||
}
|
||||
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
|
||||
ox::strncpy(m_buff.data() + currentLen, str, strLen);
|
||||
OX_CLANG_NOWARN_END
|
||||
// make sure last element is a null terminator
|
||||
m_buff[currentLen + strLen] = 0;
|
||||
m_size += strLen;
|
||||
@ -263,7 +266,7 @@ constexpr auto itoa(Integer v) noexcept {
|
||||
}();
|
||||
ox::IString<Cap> out;
|
||||
std::ignore = out.resize(out.cap());
|
||||
ox::CharBuffWriter w(out.data(), out.cap());
|
||||
ox::CharBuffWriter w{{out.data(), out.cap()}};
|
||||
std::ignore = writeItoa(v, w);
|
||||
std::ignore = out.resize(w.tellp());
|
||||
return out;
|
||||
|
9
deps/ox/src/ox/std/iterator.hpp
vendored
9
deps/ox/src/ox/std/iterator.hpp
vendored
@ -8,6 +8,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "def.hpp"
|
||||
#include "error.hpp"
|
||||
#include "math.hpp"
|
||||
|
||||
#if !__has_include(<iterator>)
|
||||
@ -38,6 +40,8 @@ struct contiguous_iterator_tag: public random_access_iterator_tag {
|
||||
#include <iterator>
|
||||
#endif
|
||||
|
||||
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
|
||||
|
||||
namespace ox {
|
||||
|
||||
template<typename Category, typename T, typename DiffType = std::ptrdiff_t,
|
||||
@ -129,14 +133,17 @@ struct SpanIterator {
|
||||
}
|
||||
|
||||
constexpr PtrType operator->() const noexcept {
|
||||
ox::primitiveAssert(__FILE__, __LINE__, m_offset < m_max, "SpanIterator access overflow");
|
||||
return &m_t[m_offset];
|
||||
}
|
||||
|
||||
constexpr RefType operator*() const noexcept {
|
||||
ox::primitiveAssert(__FILE__, __LINE__, m_offset < m_max, "SpanIterator access overflow");
|
||||
return m_t[m_offset];
|
||||
}
|
||||
|
||||
constexpr RefType operator[](std::size_t s) const noexcept {
|
||||
ox::primitiveAssert(__FILE__, __LINE__, s < m_max, "SpanIterator access overflow");
|
||||
return m_t[s];
|
||||
}
|
||||
|
||||
@ -167,3 +174,5 @@ struct SpanIterator {
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
OX_CLANG_NOWARN_END
|
||||
|
4
deps/ox/src/ox/std/memops.cpp
vendored
4
deps/ox/src/ox/std/memops.cpp
vendored
@ -10,6 +10,8 @@
|
||||
#include "types.hpp"
|
||||
#include "memops.hpp"
|
||||
|
||||
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
|
||||
|
||||
#ifndef OX_USE_STDLIB
|
||||
|
||||
#define ox_inhibit_loop_to_libcall __attribute__((__optimize__("-fno-tree-loop-distribute-patterns")))
|
||||
@ -96,3 +98,5 @@ int memcmp(const void *ptr1, const void *ptr2, std::size_t size) noexcept {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
OX_CLANG_NOWARN_END
|
||||
|
5
deps/ox/src/ox/std/memops.hpp
vendored
5
deps/ox/src/ox/std/memops.hpp
vendored
@ -8,6 +8,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "def.hpp"
|
||||
#include "types.hpp"
|
||||
#include "typetraits.hpp"
|
||||
|
||||
@ -27,6 +28,8 @@ int memcmp(const void *ptr1, const void *ptr2, std::size_t size) noexcept;
|
||||
}
|
||||
#endif
|
||||
|
||||
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
|
||||
|
||||
namespace ox {
|
||||
|
||||
template<typename T1, typename T2>
|
||||
@ -56,3 +59,5 @@ void *memsetElements(T *ptr, T val, std::size_t elements) noexcept {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
OX_CLANG_NOWARN_END
|
||||
|
4
deps/ox/src/ox/std/optional.hpp
vendored
4
deps/ox/src/ox/std/optional.hpp
vendored
@ -8,11 +8,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "bit.hpp"
|
||||
#include "initializerlist.hpp"
|
||||
#include "iterator.hpp"
|
||||
#include "memory.hpp"
|
||||
#include "new.hpp"
|
||||
#include "types.hpp"
|
||||
#include "utility.hpp"
|
||||
|
||||
|
5
deps/ox/src/ox/std/random.hpp
vendored
5
deps/ox/src/ox/std/random.hpp
vendored
@ -9,9 +9,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "bit.hpp"
|
||||
#include "def.hpp"
|
||||
#include "stddef.hpp"
|
||||
#include "types.hpp"
|
||||
|
||||
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
|
||||
|
||||
namespace ox {
|
||||
|
||||
using RandomSeed = uint64_t[2];
|
||||
@ -51,3 +54,5 @@ constexpr uint64_t Random::gen() noexcept {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
OX_CLANG_NOWARN_END
|
||||
|
157
deps/ox/src/ox/std/span.hpp
vendored
157
deps/ox/src/ox/std/span.hpp
vendored
@ -10,135 +10,21 @@
|
||||
|
||||
#include "array.hpp"
|
||||
#include "bit.hpp"
|
||||
#include "def.hpp"
|
||||
#include "iterator.hpp"
|
||||
#include "vector.hpp"
|
||||
|
||||
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
|
||||
|
||||
namespace ox {
|
||||
|
||||
template<typename T>
|
||||
class SpanView {
|
||||
|
||||
private:
|
||||
T const*m_items{};
|
||||
std::size_t m_size{};
|
||||
|
||||
public:
|
||||
using value_type = T;
|
||||
using size_type = std::size_t;
|
||||
|
||||
template<typename RefType = T const&, typename PtrType = T const*, bool reverse = false>
|
||||
using iterator = SpanIterator<T, RefType, PtrType, reverse>;
|
||||
|
||||
constexpr SpanView() noexcept {}
|
||||
|
||||
template<std::size_t sz>
|
||||
constexpr SpanView(ox::Array<T, sz> const&a) noexcept:
|
||||
m_items(a.data()),
|
||||
m_size(a.size()) {
|
||||
}
|
||||
|
||||
template<std::size_t sz, typename Allocator>
|
||||
constexpr SpanView(ox::Vector<T, sz, Allocator> const&v) noexcept:
|
||||
m_items(v.data()),
|
||||
m_size(v.size()) {
|
||||
}
|
||||
|
||||
template<std::size_t sz>
|
||||
constexpr SpanView(const T a[sz]) noexcept:
|
||||
m_items(a),
|
||||
m_size(sz) {
|
||||
}
|
||||
|
||||
constexpr SpanView(const T *a, std::size_t sz) noexcept:
|
||||
m_items(a),
|
||||
m_size(sz) {
|
||||
}
|
||||
|
||||
constexpr iterator<> begin() noexcept {
|
||||
return iterator<>(m_items, 0, m_size);
|
||||
}
|
||||
|
||||
constexpr iterator<> end() noexcept {
|
||||
return iterator<>(m_items, m_size, m_size);
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr iterator<const T&, const T*> begin() const noexcept {
|
||||
return iterator<const T&, const T*>(m_items, 0, m_size);
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr iterator<const T&, const T*> end() const noexcept {
|
||||
return iterator<const T&, const T*>(m_items, m_size, m_size);
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr iterator<const T&, const T*> cbegin() const noexcept {
|
||||
return iterator<const T&, const T*>(m_items, 0, m_size);
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr iterator<const T&, const T*> cend() const noexcept {
|
||||
return iterator<const T&, const T*>(m_items, m_size, m_size);
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr iterator<const T&, const T*, true> crbegin() const noexcept {
|
||||
return iterator<const T&, const T*, true>(m_items, m_size - 1, m_size);
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr iterator<const T&, const T*, true> crend() const noexcept {
|
||||
return iterator<const T&, const T*, true>(m_items, MaxValue<size_type>, m_size);
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr iterator<const T&, const T*, true> rbegin() const noexcept {
|
||||
return iterator<const T&, const T*, true>(m_items, m_size - 1, m_size);
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr iterator<const T&, const T*, true> rend() const noexcept {
|
||||
return iterator<const T&, const T*, true>(m_items, MaxValue<size_type>, m_size);
|
||||
}
|
||||
|
||||
constexpr const T &operator[](std::size_t i) const noexcept {
|
||||
return m_items[i];
|
||||
}
|
||||
|
||||
constexpr SpanView operator+(size_t i) const noexcept {
|
||||
return {m_items + i, m_size - i};
|
||||
}
|
||||
|
||||
constexpr SpanView operator+=(size_t i) noexcept {
|
||||
m_items += i;
|
||||
m_size -= i;
|
||||
return *this;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr T const*data() const noexcept {
|
||||
return m_items;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr std::size_t size() const noexcept {
|
||||
return m_size;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr bool empty() const noexcept {
|
||||
return m_size == 0;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class Span {
|
||||
|
||||
private:
|
||||
T *m_items{};
|
||||
const std::size_t m_size{};
|
||||
std::size_t m_size{};
|
||||
|
||||
public:
|
||||
using value_type = T;
|
||||
@ -147,20 +33,34 @@ class Span {
|
||||
template<typename RefType = T&, typename PtrType = T*, bool reverse = false>
|
||||
using iterator = SpanIterator<T, RefType, PtrType, reverse>;
|
||||
|
||||
constexpr Span() noexcept = default;
|
||||
|
||||
template<std::size_t sz>
|
||||
constexpr Span(ox::Array<T, sz> &a) noexcept:
|
||||
m_items(a.data()),
|
||||
m_size(a.size()) {
|
||||
}
|
||||
|
||||
template<std::size_t sz>
|
||||
constexpr Span(ox::Array<ox::remove_const_t<T>, sz> const&a) noexcept:
|
||||
m_items(a.data()),
|
||||
m_size(a.size()) {
|
||||
}
|
||||
|
||||
template<std::size_t sz, typename Allocator>
|
||||
constexpr Span(ox::Vector<T, sz, Allocator> &v) noexcept:
|
||||
m_items(v.data()),
|
||||
m_size(v.size()) {
|
||||
}
|
||||
|
||||
template<std::size_t sz, typename Allocator>
|
||||
constexpr Span(ox::Vector<ox::remove_const_t<T>, sz, Allocator> const&v) noexcept:
|
||||
m_items(v.data()),
|
||||
m_size(v.size()) {
|
||||
}
|
||||
|
||||
template<std::size_t sz>
|
||||
constexpr Span(T a[sz]) noexcept:
|
||||
constexpr Span(T (&a)[sz]) noexcept:
|
||||
m_items(a),
|
||||
m_size(sz) {
|
||||
}
|
||||
@ -229,13 +129,27 @@ class Span {
|
||||
}
|
||||
|
||||
constexpr T &operator[](std::size_t i) noexcept {
|
||||
ox::primitiveAssert(__FILE__, __LINE__, i < size(), "Span access overflow");
|
||||
return m_items[i];
|
||||
}
|
||||
|
||||
constexpr const T &operator[](std::size_t i) const noexcept {
|
||||
ox::primitiveAssert(__FILE__, __LINE__, i < size(), "Span access overflow");
|
||||
return m_items[i];
|
||||
}
|
||||
|
||||
constexpr Span operator+(size_t i) const noexcept {
|
||||
ox::primitiveAssert(__FILE__, __LINE__, i < size(), "Span access overflow");
|
||||
return {m_items + i, m_size - i};
|
||||
}
|
||||
|
||||
constexpr Span operator+=(size_t i) noexcept {
|
||||
ox::primitiveAssert(__FILE__, __LINE__, i < size(), "Span access overflow");
|
||||
m_items += i;
|
||||
m_size -= i;
|
||||
return *this;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr auto data() const noexcept {
|
||||
return m_items;
|
||||
@ -253,4 +167,9 @@ class Span {
|
||||
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
using SpanView = Span<const T>;
|
||||
|
||||
}
|
||||
|
||||
OX_CLANG_NOWARN_END
|
||||
|
5
deps/ox/src/ox/std/stacktrace.cpp
vendored
5
deps/ox/src/ox/std/stacktrace.cpp
vendored
@ -18,11 +18,14 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "def.hpp"
|
||||
#include "defines.hpp"
|
||||
#include "string.hpp"
|
||||
#include "trace.hpp"
|
||||
#include "vector.hpp"
|
||||
|
||||
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
|
||||
|
||||
namespace ox {
|
||||
|
||||
#if defined(OX_USE_STDLIB) && __has_include(<unistd.h>)
|
||||
@ -100,3 +103,5 @@ void printStackTrace([[maybe_unused]]unsigned shave) noexcept {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
OX_CLANG_NOWARN_END
|
||||
|
9
deps/ox/src/ox/std/string.hpp
vendored
9
deps/ox/src/ox/std/string.hpp
vendored
@ -13,6 +13,7 @@
|
||||
#endif
|
||||
|
||||
#include "algorithm.hpp"
|
||||
#include "def.hpp"
|
||||
#include "ignore.hpp"
|
||||
#include "memops.hpp"
|
||||
#include "serialize.hpp"
|
||||
@ -22,6 +23,8 @@
|
||||
#include "strops.hpp"
|
||||
#include "vector.hpp"
|
||||
|
||||
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
|
||||
|
||||
namespace ox {
|
||||
|
||||
template<typename Integer>
|
||||
@ -496,12 +499,12 @@ constexpr char &BasicString<SmallStringSize_v>::operator[](std::size_t i) noexce
|
||||
|
||||
template<std::size_t SmallStringSize_v>
|
||||
constexpr BasicString<SmallStringSize_v> BasicString<SmallStringSize_v>::substr(std::size_t pos) const noexcept {
|
||||
return BasicString(m_buff.data() + pos, m_buff.size() - pos - 1);
|
||||
return BasicString(&m_buff[pos], m_buff.size() - pos - 1);
|
||||
}
|
||||
|
||||
template<std::size_t SmallStringSize_v>
|
||||
constexpr BasicString<SmallStringSize_v> BasicString<SmallStringSize_v>::substr(std::size_t begin, std::size_t end) const noexcept {
|
||||
const auto src = m_buff.data() + begin;
|
||||
const auto src = &m_buff[begin];
|
||||
const auto size = end - begin;
|
||||
BasicString<SmallStringSize_v> out(size);
|
||||
const auto buff = out.data();
|
||||
@ -568,3 +571,5 @@ struct MaybeView<ox::BasicString<sz>> {
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
OX_CLANG_NOWARN_END
|
||||
|
3
deps/ox/src/ox/std/stringview.hpp
vendored
3
deps/ox/src/ox/std/stringview.hpp
vendored
@ -17,6 +17,8 @@
|
||||
#include "maybeview.hpp"
|
||||
#include "writer.hpp"
|
||||
|
||||
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
|
||||
|
||||
namespace ox {
|
||||
|
||||
template<std::size_t buffLen>
|
||||
@ -116,3 +118,4 @@ constexpr ox::Result<int> atoi(ox::StringViewCR str) noexcept {
|
||||
|
||||
}
|
||||
|
||||
OX_CLANG_NOWARN_END
|
||||
|
3
deps/ox/src/ox/std/strops.cpp
vendored
3
deps/ox/src/ox/std/strops.cpp
vendored
@ -6,6 +6,7 @@
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include "def.hpp"
|
||||
#include "strops.hpp"
|
||||
|
||||
static_assert(ox::strcmp("asdf", "hijk") < 0, "asdf < hijk");
|
||||
@ -17,7 +18,9 @@ static_assert(ox::strcmp("", "") == 0, "\"\" == \"\"");
|
||||
|
||||
static_assert([] {
|
||||
auto testStr = "asdf";
|
||||
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
|
||||
return ox::strchr(testStr, 0, 4) == &testStr[4];
|
||||
OX_CLANG_NOWARN_END
|
||||
}(), "ox::strchr 0");
|
||||
|
||||
static_assert([] {
|
||||
|
9
deps/ox/src/ox/std/strops.hpp
vendored
9
deps/ox/src/ox/std/strops.hpp
vendored
@ -9,18 +9,21 @@
|
||||
#pragma once
|
||||
|
||||
#include "cstrops.hpp"
|
||||
#include "def.hpp"
|
||||
#include "error.hpp"
|
||||
#include "math.hpp"
|
||||
#include "stringview.hpp"
|
||||
#include "types.hpp"
|
||||
#include "vector.hpp"
|
||||
|
||||
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
|
||||
|
||||
namespace ox {
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr ox::StringView substr(ox::StringView const&str, std::size_t pos) noexcept {
|
||||
if (str.len() >= pos) {
|
||||
return {str.data() + pos, str.len() - pos};
|
||||
return {&str[pos], str.len() - pos};
|
||||
}
|
||||
return {};
|
||||
}
|
||||
@ -28,7 +31,7 @@ constexpr ox::StringView substr(ox::StringView const&str, std::size_t pos) noexc
|
||||
[[nodiscard]]
|
||||
constexpr ox::StringView substr(ox::StringView const&str, std::size_t start, std::size_t end) noexcept {
|
||||
if (str.len() >= start && end >= start) {
|
||||
return {str.data() + start, end - start};
|
||||
return {&str[start], end - start};
|
||||
}
|
||||
return {};
|
||||
}
|
||||
@ -113,3 +116,5 @@ constexpr ox::Result<std::size_t> lastIndexOf(ox::StringViewCR str, int characte
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
OX_CLANG_NOWARN_END
|
||||
|
6
deps/ox/src/ox/std/test/tests.cpp
vendored
6
deps/ox/src/ox/std/test/tests.cpp
vendored
@ -121,7 +121,9 @@ static std::map<ox::StringView, ox::Error(*)()> tests = {
|
||||
auto a1 = static_cast<char*>(ox::heapmgr::malloc(5));
|
||||
auto a2 = static_cast<char*>(ox::heapmgr::malloc(5));
|
||||
oxAssert(a1 >= buff.front().unwrap() && a1 < buff.back().unwrap(), "malloc is broken");
|
||||
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
|
||||
oxAssert(a2 >= buff.front().unwrap() && a2 < buff.back().unwrap() && a2 > a1 + 5, "malloc is broken");
|
||||
OX_CLANG_NOWARN_END
|
||||
ox::heapmgr::free(a1);
|
||||
ox::heapmgr::free(a2);
|
||||
return OxError(0);
|
||||
@ -470,10 +472,12 @@ static std::map<ox::StringView, ox::Error(*)()> tests = {
|
||||
},
|
||||
};
|
||||
|
||||
int main(int argc, const char **args) {
|
||||
int main(int argc, const char **argv) {
|
||||
if (argc < 2) {
|
||||
oxError("Must specify test to run");
|
||||
return -1;
|
||||
}
|
||||
auto const args = ox::Span{argv, static_cast<size_t>(argc)};
|
||||
auto const testName = args[1];
|
||||
auto const func = tests.find(testName);
|
||||
if (func != tests.end()) {
|
||||
|
24
deps/ox/src/ox/std/trace.cpp
vendored
24
deps/ox/src/ox/std/trace.cpp
vendored
@ -10,6 +10,17 @@
|
||||
|
||||
namespace ox::trace {
|
||||
|
||||
static class: public Logger {
|
||||
public:
|
||||
ox::Error send(const TraceMsg&) noexcept final {
|
||||
return {};
|
||||
}
|
||||
ox::Error sendInit(const InitTraceMsg&) noexcept final {
|
||||
return {};
|
||||
}
|
||||
} defaultLogger;
|
||||
static Logger *logger = &defaultLogger;
|
||||
|
||||
void init() {
|
||||
oxTraceInitHook();
|
||||
}
|
||||
@ -19,19 +30,6 @@ void init(Logger *logger) {
|
||||
setLogger(logger);
|
||||
}
|
||||
|
||||
class NullLogger: public Logger {
|
||||
public:
|
||||
ox::Error send(const TraceMsg&) noexcept final {
|
||||
return {};
|
||||
}
|
||||
ox::Error sendInit(const InitTraceMsg&) noexcept final {
|
||||
return {};
|
||||
}
|
||||
};
|
||||
|
||||
static NullLogger defaultLogger;
|
||||
static Logger *logger = &defaultLogger;
|
||||
|
||||
void setLogger(Logger *logger) noexcept {
|
||||
trace::logger = logger;
|
||||
}
|
||||
|
6
deps/ox/src/ox/std/trace.hpp
vendored
6
deps/ox/src/ox/std/trace.hpp
vendored
@ -173,7 +173,7 @@ class OutStream {
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr OutStream &operator<<(const char *v) noexcept {
|
||||
constexpr OutStream &operator<<(StringViewCR v) noexcept {
|
||||
if (m_msg.msg.len()) {
|
||||
m_msg.msg += m_delimiter;
|
||||
}
|
||||
@ -181,6 +181,10 @@ class OutStream {
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr OutStream &operator<<(const char *v) noexcept {
|
||||
return operator<<(StringView{v});
|
||||
}
|
||||
|
||||
template<std::size_t sz>
|
||||
constexpr OutStream &operator<<(const IString<sz> &v) noexcept {
|
||||
return operator<<(v.c_str());
|
||||
|
35
deps/ox/src/ox/std/typetraits.hpp
vendored
35
deps/ox/src/ox/std/typetraits.hpp
vendored
@ -269,6 +269,41 @@ template<class T>
|
||||
constexpr bool is_move_constructible_v = detail::is_move_constructible<T>(0);
|
||||
|
||||
|
||||
template<typename T>
|
||||
struct remove_cv {
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct remove_cv<const T> {
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct remove_cv<volatile T> {
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct remove_cv<const volatile T> {
|
||||
using type = T;
|
||||
};
|
||||
|
||||
|
||||
template<typename T>
|
||||
struct remove_const {
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct remove_const<const T> {
|
||||
using type = T;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
using remove_const_t = typename remove_const<T>::type;
|
||||
|
||||
|
||||
// is String?
|
||||
|
||||
template<std::size_t SmallStringSize>
|
||||
|
11
deps/ox/src/ox/std/uuid.hpp
vendored
11
deps/ox/src/ox/std/uuid.hpp
vendored
@ -9,6 +9,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "bit.hpp"
|
||||
#include "def.hpp"
|
||||
#include "ignore.hpp"
|
||||
#include "istring.hpp"
|
||||
#include "buffer.hpp"
|
||||
@ -18,6 +19,8 @@
|
||||
#include "stringview.hpp"
|
||||
#include "strops.hpp"
|
||||
|
||||
OX_CLANG_NOWARN_BEGIN(-Wunsafe-buffer-usage)
|
||||
|
||||
namespace ox {
|
||||
|
||||
using UUIDStr = ox::IString<36>;
|
||||
@ -107,12 +110,12 @@ class UUID {
|
||||
static ox::Result<UUID> generate() noexcept;
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr auto const&value() const noexcept {
|
||||
constexpr ox::Array<uint8_t, 16> const&value() const noexcept {
|
||||
return m_value;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr auto isNull() const noexcept {
|
||||
constexpr bool isNull() const noexcept {
|
||||
if (std::is_constant_evaluated()) {
|
||||
if (ox::all_of(m_value.begin(), m_value.end(), [](auto v) { return v == 0; })) {
|
||||
return true;
|
||||
@ -187,7 +190,7 @@ class UUID {
|
||||
constexpr UUIDStr toString() const noexcept {
|
||||
UUIDStr out;
|
||||
std::ignore = out.resize(UUIDStr::cap());
|
||||
ox::CharBuffWriter bw(out.data(), UUIDStr::cap());
|
||||
ox::CharBuffWriter bw{{out.data(), UUIDStr::cap()}};
|
||||
std::ignore = toString(bw);
|
||||
out[UUIDStr::cap()] = 0;
|
||||
return out;
|
||||
@ -220,3 +223,5 @@ constexpr Error model(T *io, ox::CommonPtrWith<UUID> auto *obj) noexcept {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
OX_CLANG_NOWARN_END
|
||||
|
2
deps/ox/src/ox/std/vec.cpp
vendored
2
deps/ox/src/ox/std/vec.cpp
vendored
@ -14,7 +14,7 @@ namespace ox {
|
||||
|
||||
static_assert([] {
|
||||
Vec2 v(1, 2);
|
||||
return v.x == 1 && v.y == 2 && v[0] == 1 && v[1] == 2 && v.size() == 2;
|
||||
return v.x == 1 && v.y == 2 && v.size() == 2;
|
||||
}());
|
||||
|
||||
}
|
||||
|
196
deps/ox/src/ox/std/vec.hpp
vendored
196
deps/ox/src/ox/std/vec.hpp
vendored
@ -34,112 +34,6 @@ class Vec2 {
|
||||
float x = 0;
|
||||
float y = 0;
|
||||
|
||||
template<typename RefType = value_type&, typename PtrType = value_type*, bool reverse = false>
|
||||
struct iterator: public ox::Iterator<std::bidirectional_iterator_tag, value_type> {
|
||||
private:
|
||||
PtrType m_t = nullptr;
|
||||
size_type m_offset = 0;
|
||||
size_type m_max = 0;
|
||||
|
||||
public:
|
||||
constexpr iterator() noexcept = default;
|
||||
|
||||
constexpr iterator(PtrType t, size_type offset, size_type max) noexcept {
|
||||
m_t = t;
|
||||
m_offset = offset;
|
||||
m_max = max;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr auto offset() const noexcept {
|
||||
return m_offset;
|
||||
}
|
||||
|
||||
constexpr iterator operator+(size_type s) const noexcept {
|
||||
if constexpr(reverse) {
|
||||
return iterator(m_t, ox::max<size_type>(m_offset - s, 0), m_max);
|
||||
} else {
|
||||
return iterator(m_t, ox::min<size_type>(m_offset + s, m_max), m_max);
|
||||
}
|
||||
}
|
||||
|
||||
constexpr typename ox::Iterator<std::bidirectional_iterator_tag, value_type>::difference_type
|
||||
operator-(const iterator &other) const noexcept {
|
||||
if constexpr(reverse) {
|
||||
return m_offset + other.m_offset;
|
||||
} else {
|
||||
return m_offset - other.m_offset;
|
||||
}
|
||||
}
|
||||
|
||||
constexpr iterator operator-(size_type s) const noexcept {
|
||||
if constexpr(reverse) {
|
||||
return iterator(m_t, ox::min<size_type>(m_offset + s, m_max), m_max);
|
||||
} else {
|
||||
return iterator(m_t, ox::max<size_type>(m_offset - s, 0), m_max);
|
||||
}
|
||||
}
|
||||
|
||||
constexpr iterator &operator+=(size_type s) noexcept {
|
||||
if constexpr(reverse) {
|
||||
m_offset = ox::max<size_type>(m_offset - s, 0);
|
||||
} else {
|
||||
m_offset = ox::min(m_offset + s, m_max);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr iterator &operator-=(size_type s) noexcept {
|
||||
if constexpr(reverse) {
|
||||
m_offset = ox::min(m_offset + s, m_max);
|
||||
} else {
|
||||
m_offset = ox::max<size_type>(m_offset - s, 0);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
constexpr iterator &operator++() noexcept {
|
||||
return operator+=(1);
|
||||
}
|
||||
|
||||
constexpr iterator &operator--() noexcept {
|
||||
return operator-=(1);
|
||||
}
|
||||
|
||||
constexpr RefType operator*() const noexcept {
|
||||
return m_t[m_offset];
|
||||
}
|
||||
|
||||
constexpr RefType operator[](size_type s) const noexcept {
|
||||
return m_t[s];
|
||||
}
|
||||
|
||||
constexpr bool operator<(const iterator &other) const noexcept {
|
||||
return m_offset < other.m_offset;
|
||||
}
|
||||
|
||||
constexpr bool operator>(const iterator &other) const noexcept {
|
||||
return m_offset > other.m_offset;
|
||||
}
|
||||
|
||||
constexpr bool operator<=(const iterator &other) const noexcept {
|
||||
return m_offset <= other.m_offset;
|
||||
}
|
||||
|
||||
constexpr bool operator>=(const iterator &other) const noexcept {
|
||||
return m_offset >= other.m_offset;
|
||||
}
|
||||
|
||||
constexpr bool operator==(const iterator &other) const noexcept {
|
||||
return m_t == other.m_t && m_offset == other.m_offset && m_max == other.m_max;
|
||||
}
|
||||
|
||||
constexpr bool operator!=(const iterator &other) const noexcept {
|
||||
return m_t != other.m_t || m_offset != other.m_offset || m_max != other.m_max;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
constexpr Vec2() noexcept = default;
|
||||
|
||||
explicit constexpr Vec2(class Point const&pt) noexcept;
|
||||
@ -159,85 +53,8 @@ class Vec2 {
|
||||
}
|
||||
#endif
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr iterator<> begin() noexcept {
|
||||
return {start(), 0, size()};
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr iterator<> end() noexcept {
|
||||
return {start(), size(), size()};
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr iterator<const value_type&, const value_type*> begin() const noexcept {
|
||||
return {start(), 0, size()};
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr iterator<const value_type&, const value_type*> end() const noexcept {
|
||||
return {start(), size(), size()};
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr iterator<value_type&, value_type*, true> rbegin() noexcept {
|
||||
return {start(), size() - 1, size()};
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr iterator<value_type&, value_type*, true> rend() noexcept {
|
||||
return {start(), ox::MaxValue<size_type>, size()};
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr iterator<const value_type&, const value_type*, true> rbegin() const noexcept {
|
||||
return {start(), size() - 1, size()};
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr iterator<const value_type&, const value_type*, true> rend() const noexcept {
|
||||
return {start(), ox::MaxValue<size_type>, size()};
|
||||
}
|
||||
|
||||
constexpr auto &operator[](std::size_t i) noexcept {
|
||||
if (std::is_constant_evaluated()) {
|
||||
switch (i) {
|
||||
case 0:
|
||||
return x;
|
||||
case 1:
|
||||
return y;
|
||||
default:
|
||||
oxAssert(false, "Read past end of Vec2");
|
||||
return y;
|
||||
}
|
||||
} else {
|
||||
return start()[i];
|
||||
}
|
||||
}
|
||||
|
||||
constexpr const auto &operator[](std::size_t i) const noexcept {
|
||||
if (std::is_constant_evaluated()) {
|
||||
switch (i) {
|
||||
case 0:
|
||||
return x;
|
||||
case 1:
|
||||
return y;
|
||||
default:
|
||||
oxAssert(false, "Read past end of Vec2");
|
||||
return y;
|
||||
}
|
||||
} else {
|
||||
return start()[i];
|
||||
}
|
||||
}
|
||||
|
||||
constexpr auto operator==(const Vec2 &v) const noexcept {
|
||||
for (auto i = 0u; i < v.size(); ++i) {
|
||||
if ((*this)[i] != v[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return x == v.x && y == v.y;
|
||||
}
|
||||
|
||||
constexpr auto operator!=(const Vec2 &v) const noexcept {
|
||||
@ -292,17 +109,6 @@ class Vec2 {
|
||||
y /= i;
|
||||
return *this;
|
||||
}
|
||||
|
||||
protected:
|
||||
[[nodiscard]]
|
||||
constexpr float *start() noexcept {
|
||||
return&x;
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr const float *start() const noexcept {
|
||||
return &x;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
|
6
deps/ox/src/ox/std/vector.hpp
vendored
6
deps/ox/src/ox/std/vector.hpp
vendored
@ -20,6 +20,8 @@
|
||||
#include "types.hpp"
|
||||
#include "utility.hpp"
|
||||
|
||||
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
|
||||
|
||||
namespace ox {
|
||||
|
||||
namespace detail {
|
||||
@ -422,11 +424,13 @@ constexpr Vector<T, SmallVectorSize, Allocator> &Vector<T, SmallVectorSize, Allo
|
||||
|
||||
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
||||
constexpr T &Vector<T, SmallVectorSize, Allocator>::operator[](std::size_t i) noexcept {
|
||||
ox::primitiveAssert(__FILE__, __LINE__, i < size(), "Vector access overflow");
|
||||
return m_items[i];
|
||||
}
|
||||
|
||||
template<typename T, std::size_t SmallVectorSize, typename Allocator>
|
||||
constexpr const T &Vector<T, SmallVectorSize, Allocator>::operator[](std::size_t i) const noexcept {
|
||||
ox::primitiveAssert(__FILE__, __LINE__, i < size(), "Vector access overflow");
|
||||
return m_items[i];
|
||||
}
|
||||
|
||||
@ -707,3 +711,5 @@ constexpr auto alignOf(const Vector<T>&) noexcept {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
OX_ALLOW_UNSAFE_BUFFERS_END
|
||||
|
4
deps/teagba/include/teagba/registers.hpp
vendored
4
deps/teagba/include/teagba/registers.hpp
vendored
@ -6,6 +6,8 @@
|
||||
|
||||
#include "addresses.hpp"
|
||||
|
||||
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
|
||||
|
||||
namespace teagba {
|
||||
|
||||
inline auto bgSetSbb(volatile BgCtl &bgCtl, unsigned sbb) noexcept {
|
||||
@ -53,3 +55,5 @@ constexpr void iterateBgCtl(auto cb) noexcept {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
OX_ALLOW_UNSAFE_BUFFERS_END
|
||||
|
@ -1,4 +1,9 @@
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang")
|
||||
# enable warnings
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wunsafe-buffer-usage")
|
||||
endif()
|
||||
|
||||
project(nostalgia CXX)
|
||||
|
||||
#project packages
|
||||
|
@ -121,11 +121,20 @@ ox::Error loadSpritePalette(
|
||||
CompactPalette const&palette,
|
||||
size_t page = 0) noexcept;
|
||||
|
||||
ox::Error loadBgPalette(
|
||||
Context &ctx,
|
||||
size_t palBank,
|
||||
ox::StringViewCR palettePath) noexcept;
|
||||
|
||||
ox::Error loadBgPalette(
|
||||
Context &ctx,
|
||||
size_t palBank,
|
||||
ox::FileAddress const&paletteAddr) noexcept;
|
||||
|
||||
ox::Error loadSpritePalette(
|
||||
Context &ctx,
|
||||
ox::StringViewCR palettePath) noexcept;
|
||||
|
||||
ox::Error loadSpritePalette(
|
||||
Context &ctx,
|
||||
ox::FileAddress const&paletteAddr) noexcept;
|
||||
@ -143,6 +152,14 @@ ox::Error loadBgTileSheet(
|
||||
size_t srcTileIdx,
|
||||
size_t tileCnt) noexcept;
|
||||
|
||||
ox::Error loadBgTileSheet(
|
||||
Context &ctx,
|
||||
unsigned cbb,
|
||||
ox::StringViewCR tsPath,
|
||||
size_t dstTileIdx,
|
||||
size_t srcTileIdx,
|
||||
size_t tileCnt) noexcept;
|
||||
|
||||
ox::Error loadBgTileSheet(
|
||||
Context &ctx,
|
||||
unsigned cbb,
|
||||
@ -157,6 +174,12 @@ ox::Error loadBgTileSheet(
|
||||
CompactTileSheet const&ts,
|
||||
ox::Optional<unsigned> const&paletteBank = {}) noexcept;
|
||||
|
||||
ox::Error loadBgTileSheet(
|
||||
Context &ctx,
|
||||
unsigned cbb,
|
||||
ox::StringViewCR tilesheetPath,
|
||||
ox::Optional<unsigned> const&paletteBank) noexcept;
|
||||
|
||||
ox::Error loadBgTileSheet(
|
||||
Context &ctx,
|
||||
unsigned cbb,
|
||||
@ -168,6 +191,11 @@ ox::Error loadSpriteTileSheet(
|
||||
CompactTileSheet const&ts,
|
||||
bool loadDefaultPalette) noexcept;
|
||||
|
||||
ox::Error loadSpriteTileSheet(
|
||||
Context &ctx,
|
||||
ox::StringViewCR tilesheetPath,
|
||||
bool loadDefaultPalette = false) noexcept;
|
||||
|
||||
ox::Error loadSpriteTileSheet(
|
||||
Context &ctx,
|
||||
ox::FileAddress const&tilesheetAddr,
|
||||
|
@ -4,6 +4,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ox/std/types.hpp>
|
||||
|
||||
namespace nostalgia::core {
|
||||
|
||||
struct InitParams {
|
||||
@ -12,4 +14,4 @@ struct InitParams {
|
||||
uint_t glBlocksPerSprite = 64;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -33,7 +33,14 @@ struct TileSheetV1 {
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr bool valid(TileSheetV1 const&ts) noexcept {
|
||||
return ts.bpp == 4 || ts.bpp == 8;
|
||||
auto const bytes = static_cast<size_t>(ts.columns * ts.rows * PixelsPerTile) / (ts.bpp == 4 ? 2 : 1);
|
||||
return (ts.bpp == 4 || ts.bpp == 8) && ts.pixels.size() == bytes;
|
||||
}
|
||||
|
||||
constexpr ox::Error repair(TileSheetV1 &ts, int bpp) noexcept {
|
||||
auto const bytes = static_cast<size_t>(ts.columns * ts.rows * PixelsPerTile) / (bpp == 4 ? 2 : 1);
|
||||
ts.pixels.resize(bytes);
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
@ -65,9 +72,34 @@ struct TileSheetV2 {
|
||||
|
||||
};
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr bool valid(TileSheetV2::SubSheet const&ss, int bpp) noexcept {
|
||||
auto const bytes = static_cast<size_t>(ss.columns * ss.rows * PixelsPerTile) / (bpp == 4 ? 2 : 1);
|
||||
return ox::all_of(ss.subsheets.begin(), ss.subsheets.end(),
|
||||
[bpp, bytes](TileSheetV2::SubSheet const&s) {
|
||||
return bytes == s.pixels.size() && valid(s, bpp);
|
||||
});
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr bool valid(TileSheetV2 const&ts) noexcept {
|
||||
return ts.bpp == 4 || ts.bpp == 8;
|
||||
return (ts.bpp == 4 || ts.bpp == 8) && valid(ts.subsheet, ts.bpp);
|
||||
}
|
||||
|
||||
constexpr void repair(TileSheetV2::SubSheet &ss, int bpp) noexcept {
|
||||
auto const bytes = static_cast<size_t>(ss.columns * ss.rows * PixelsPerTile) / (bpp == 4 ? 2 : 1);
|
||||
ss.pixels.resize(bytes);
|
||||
for (auto &s : ss.subsheets) {
|
||||
repair(s, bpp);
|
||||
}
|
||||
}
|
||||
|
||||
constexpr ox::Error repair(TileSheetV2 &ts) noexcept {
|
||||
if (ts.bpp != 4 && ts.bpp != 8) {
|
||||
return OxError(1, "Unable to repair TileSheet");
|
||||
}
|
||||
repair(ts.subsheet, ts.bpp);
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
@ -110,9 +142,34 @@ struct TileSheetV3 {
|
||||
|
||||
};
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr bool valid(TileSheetV3::SubSheet const&ss, int bpp) noexcept {
|
||||
auto const bytes = static_cast<size_t>(ss.columns * ss.rows * PixelsPerTile) / (bpp == 4 ? 2 : 1);
|
||||
return ox::all_of(ss.subsheets.begin(), ss.subsheets.end(),
|
||||
[bpp, bytes](TileSheetV3::SubSheet const&s) {
|
||||
return bytes == s.pixels.size() && valid(s, bpp);
|
||||
});
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr bool valid(TileSheetV3 const&ts) noexcept {
|
||||
return ts.bpp == 4 || ts.bpp == 8;
|
||||
return (ts.bpp == 4 || ts.bpp == 8) && valid(ts.subsheet, ts.bpp);
|
||||
}
|
||||
|
||||
constexpr void repair(TileSheetV3::SubSheet &ss, int bpp) noexcept {
|
||||
auto const bytes = static_cast<size_t>(ss.columns * ss.rows * PixelsPerTile) / (bpp == 4 ? 2 : 1);
|
||||
ss.pixels.resize(bytes);
|
||||
for (auto &s : ss.subsheets) {
|
||||
repair(s, bpp);
|
||||
}
|
||||
}
|
||||
|
||||
constexpr ox::Error repair(TileSheetV3 &ts) noexcept {
|
||||
if (ts.bpp != 4 && ts.bpp != 8) {
|
||||
return OxError(1, "Unable to repair TileSheet");
|
||||
}
|
||||
repair(ts.subsheet, ts.bpp);
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
@ -173,9 +230,34 @@ struct TileSheetV4 {
|
||||
|
||||
};
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr bool valid(TileSheetV4::SubSheet const&ss, int bpp) noexcept {
|
||||
auto const bytes = static_cast<size_t>(ss.columns * ss.rows * PixelsPerTile) / (bpp == 4 ? 2 : 1);
|
||||
return ox::all_of(ss.subsheets.begin(), ss.subsheets.end(),
|
||||
[bpp, bytes](TileSheetV4::SubSheet const&s) {
|
||||
return bytes == s.pixels.size() && valid(s, bpp);
|
||||
});
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
constexpr bool valid(TileSheetV4 const&ts) noexcept {
|
||||
return ts.bpp == 4 || ts.bpp == 8;
|
||||
return (ts.bpp == 4 || ts.bpp == 8) && valid(ts.subsheet, ts.bpp);
|
||||
}
|
||||
|
||||
constexpr void repair(TileSheetV4::SubSheet &ss, int bpp) noexcept {
|
||||
auto const bytes = static_cast<size_t>(ss.columns * ss.rows * PixelsPerTile) / (bpp == 4 ? 2 : 1);
|
||||
ss.pixels.resize(bytes);
|
||||
for (auto &s : ss.subsheets) {
|
||||
repair(s, bpp);
|
||||
}
|
||||
}
|
||||
|
||||
constexpr ox::Error repair(TileSheetV4 &ts) noexcept {
|
||||
if (ts.bpp != 4 && ts.bpp != 8) {
|
||||
return OxError(1, "Unable to repair TileSheet");
|
||||
}
|
||||
repair(ts.subsheet, ts.bpp);
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
|
@ -17,6 +17,8 @@
|
||||
|
||||
#include "context.hpp"
|
||||
|
||||
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
|
||||
|
||||
namespace nostalgia::core {
|
||||
|
||||
static constexpr auto SpriteCount = 128;
|
||||
@ -283,3 +285,5 @@ uint_t spriteCount(Context&) noexcept {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
OX_ALLOW_UNSAFE_BUFFERS_END
|
||||
|
@ -25,7 +25,9 @@ using namespace nostalgia::core;
|
||||
|
||||
void panic(const char *file, int line, const char *panicMsg, ox::Error const&err) noexcept {
|
||||
// reset heap to make sure we have enough memory to allocate context data
|
||||
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
|
||||
ox::heapmgr::initHeap(HEAP_BEGIN, HEAP_END);
|
||||
OX_ALLOW_UNSAFE_BUFFERS_END
|
||||
auto tctx = turbine::init(keel::loadRomFs("").unwrap(), "Nostalgia").unwrap();
|
||||
auto ctx = init(*tctx).unwrap();
|
||||
std::ignore = initGfx(*ctx, {});
|
||||
|
@ -18,6 +18,14 @@ int tileRows(Context&) noexcept {
|
||||
return GbaTileRows;
|
||||
}
|
||||
|
||||
ox::Error loadBgPalette(
|
||||
Context &ctx,
|
||||
size_t palBank,
|
||||
ox::StringViewCR palettePath) noexcept {
|
||||
oxRequire(pal, keel::readObj<CompactPalette>(keelCtx(ctx), palettePath));
|
||||
return loadBgPalette(ctx, palBank, *pal, 0);
|
||||
}
|
||||
|
||||
ox::Error loadBgPalette(
|
||||
Context &ctx,
|
||||
size_t palBank,
|
||||
@ -26,6 +34,13 @@ ox::Error loadBgPalette(
|
||||
return loadBgPalette(ctx, palBank, *pal, 0);
|
||||
}
|
||||
|
||||
ox::Error loadSpritePalette(
|
||||
Context &ctx,
|
||||
ox::StringViewCR palettePath) noexcept {
|
||||
oxRequire(pal, keel::readObj<CompactPalette>(keelCtx(ctx), palettePath));
|
||||
return loadSpritePalette(ctx, *pal, 0);
|
||||
}
|
||||
|
||||
ox::Error loadSpritePalette(
|
||||
Context &ctx,
|
||||
ox::FileAddress const&paletteAddr) noexcept {
|
||||
@ -44,6 +59,26 @@ ox::Error loadBgTileSheet(
|
||||
return loadBgTileSheet(ctx, cbb, *ts, dstTileIdx, srcTileIdx, tileCnt);
|
||||
}
|
||||
|
||||
ox::Error loadBgTileSheet(
|
||||
Context &ctx,
|
||||
unsigned cbb,
|
||||
ox::StringViewCR tsPath,
|
||||
size_t dstTileIdx,
|
||||
size_t srcTileIdx,
|
||||
size_t tileCnt) noexcept {
|
||||
oxRequire(ts, keel::readObj<CompactTileSheet>(keelCtx(ctx), tsPath));
|
||||
return loadBgTileSheet(ctx, cbb, *ts, dstTileIdx, srcTileIdx, tileCnt);
|
||||
}
|
||||
|
||||
ox::Error loadBgTileSheet(
|
||||
Context &ctx,
|
||||
unsigned cbb,
|
||||
ox::StringViewCR tilesheetPath,
|
||||
ox::Optional<unsigned> const&paletteBank) noexcept {
|
||||
oxRequire(ts, keel::readObj<CompactTileSheet>(keelCtx(ctx), tilesheetPath));
|
||||
return loadBgTileSheet(ctx, cbb, *ts, paletteBank);
|
||||
}
|
||||
|
||||
ox::Error loadBgTileSheet(
|
||||
Context &ctx,
|
||||
unsigned cbb,
|
||||
@ -53,6 +88,14 @@ ox::Error loadBgTileSheet(
|
||||
return loadBgTileSheet(ctx, cbb, *ts, paletteBank);
|
||||
}
|
||||
|
||||
ox::Error loadSpriteTileSheet(
|
||||
Context &ctx,
|
||||
ox::StringViewCR tilesheetPath,
|
||||
bool loadDefaultPalette) noexcept {
|
||||
oxRequire(ts, readObj<CompactTileSheet>(keelCtx(ctx), tilesheetPath));
|
||||
return loadSpriteTileSheet(ctx, *ts, loadDefaultPalette);
|
||||
}
|
||||
|
||||
ox::Error loadSpriteTileSheet(
|
||||
Context &ctx,
|
||||
ox::FileAddress const&tilesheetAddr,
|
||||
@ -213,12 +256,11 @@ void puts(
|
||||
int const column,
|
||||
int const row,
|
||||
ox::StringViewCR str) noexcept {
|
||||
auto const col = static_cast<uint_t>(column);
|
||||
for (auto i = 0u; i < str.bytes(); ++i) {
|
||||
setBgTile(
|
||||
ctx,
|
||||
0,
|
||||
static_cast<int>(col + i),
|
||||
column + static_cast<int>(i),
|
||||
row,
|
||||
static_cast<uint8_t>(charMap[static_cast<uint8_t>(str[i])]));
|
||||
}
|
||||
|
@ -554,20 +554,21 @@ static ox::Result<TileSheetData> buildSetTsd(
|
||||
|
||||
static void copyPixels(
|
||||
CompactTileSheet const&ts,
|
||||
uint32_t *dst,
|
||||
ox::Span<uint32_t> dst,
|
||||
size_t const srcPxIdx,
|
||||
size_t pxlCnt) noexcept {
|
||||
size_t idx{};
|
||||
if (ts.bpp == 4) {
|
||||
for (size_t i = 0; i < pxlCnt; i += 2) {
|
||||
auto const [a, b] = get2Pixels4Bpp(ts, i + srcPxIdx);
|
||||
*(dst++) = a;
|
||||
*(dst++) = b;
|
||||
dst[idx++] = a;
|
||||
dst[idx++] = b;
|
||||
}
|
||||
} else if (ts.bpp == 8) {
|
||||
for (size_t i = 0; i < pxlCnt; i += 2) {
|
||||
auto const [a, b] = get2Pixels8Bpp(ts, i + srcPxIdx);
|
||||
*(dst++) = a;
|
||||
*(dst++) = b;
|
||||
dst[idx++] = a;
|
||||
dst[idx++] = b;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -587,7 +588,7 @@ ox::Error loadBgTileSheet(
|
||||
if (dstPxIdx + pxlCnt >= cbbPxls.size()) {
|
||||
return OxError(1, "video mem dst overflow");
|
||||
}
|
||||
auto const dst = &cbbPxls[dstPxIdx];
|
||||
auto const dst = ox::Span{cbbPxls} + dstPxIdx;
|
||||
copyPixels(ts, dst, srcPxIdx, pxlCnt);
|
||||
auto const cbbTiles = cbbPxls.size() / bytesPerTile;
|
||||
int constexpr cbbWidth = 8;
|
||||
|
@ -12,7 +12,7 @@ TileSheetClipboard::Pixel::Pixel(uint16_t pColorIdx, ox::Point pPt) noexcept {
|
||||
}
|
||||
|
||||
|
||||
void TileSheetClipboard::addPixel(const ox::Point &pt, uint16_t colorIdx) noexcept {
|
||||
void TileSheetClipboard::addPixel(ox::Point const&pt, uint16_t colorIdx) noexcept {
|
||||
m_pixels.emplace_back(colorIdx, pt);
|
||||
}
|
||||
|
||||
@ -25,18 +25,20 @@ CutPasteCommand::CutPasteCommand(
|
||||
CommandId commandId,
|
||||
TileSheet &img,
|
||||
TileSheet::SubSheetIdx subSheetIdx,
|
||||
const ox::Point &dstStart,
|
||||
const ox::Point &dstEnd,
|
||||
const TileSheetClipboard &cb) noexcept:
|
||||
ox::Point const&dstStart,
|
||||
ox::Point dstEnd,
|
||||
TileSheetClipboard const&cb) noexcept:
|
||||
m_commandId(commandId),
|
||||
m_img(img),
|
||||
m_subSheetIdx(std::move(subSheetIdx)) {
|
||||
const auto &subsheet = getSubSheet(m_img, m_subSheetIdx);
|
||||
for (const auto &p : cb.pixels()) {
|
||||
const auto dstPt = p.pt + dstStart;
|
||||
auto const&ss = getSubSheet(m_img, m_subSheetIdx);
|
||||
dstEnd.x = std::min(ss.columns * TileWidth - 1, dstEnd.x);
|
||||
dstEnd.y = std::min(ss.rows * TileHeight - 1, dstEnd.y);
|
||||
for (auto const&p : cb.pixels()) {
|
||||
auto const dstPt = p.pt + dstStart;
|
||||
if (dstPt.x <= dstEnd.x && dstPt.y <= dstEnd.y) {
|
||||
const auto idx = core::idx(subsheet, dstPt);
|
||||
m_changes.emplace_back(static_cast<uint32_t>(idx), p.colorIdx, getPixel(subsheet, m_img.bpp, idx));
|
||||
auto const idx = core::idx(ss, dstPt);
|
||||
m_changes.emplace_back(static_cast<uint32_t>(idx), p.colorIdx, getPixel(ss, m_img.bpp, idx));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ class CutPasteCommand: public TileSheetCommand {
|
||||
TileSheet &img,
|
||||
TileSheet::SubSheetIdx subSheetIdx,
|
||||
ox::Point const&dstStart,
|
||||
ox::Point const&dstEnd,
|
||||
ox::Point dstEnd,
|
||||
TileSheetClipboard const&cb) noexcept;
|
||||
|
||||
ox::Error redo() noexcept final;
|
||||
@ -83,4 +83,4 @@ class CutPasteCommand: public TileSheetCommand {
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,8 @@
|
||||
* Copyright 2016 - 2024 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#include <ox/std/algorithm.hpp>
|
||||
|
||||
#include "deletetilescommand.hpp"
|
||||
|
||||
namespace nostalgia::core {
|
||||
@ -20,11 +22,9 @@ core::DeleteTilesCommand::DeleteTilesCommand(
|
||||
// copy pixels to be erased
|
||||
{
|
||||
auto &s = getSubSheet(m_img, m_idx);
|
||||
auto &p = s.pixels;
|
||||
auto dst = m_deletedPixels.data();
|
||||
auto src = p.data() + m_deletePos;
|
||||
const auto sz = m_deleteSz * sizeof(decltype(p[0]));
|
||||
ox::memcpy(dst, src, sz);
|
||||
auto dst = m_deletedPixels.begin();
|
||||
auto src = s.pixels.begin() + m_deletePos;
|
||||
ox::copy_n(src, m_deleteSz, dst);
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,9 +32,9 @@ ox::Error core::DeleteTilesCommand::redo() noexcept {
|
||||
auto &s = getSubSheet(m_img, m_idx);
|
||||
auto &p = s.pixels;
|
||||
auto srcPos = m_deletePos + m_deleteSz;
|
||||
const auto src = p.data() + srcPos;
|
||||
const auto dst1 = p.data() + m_deletePos;
|
||||
const auto dst2 = p.data() + (p.size() - m_deleteSz);
|
||||
auto const src = &p[srcPos];
|
||||
auto const dst1 = &p[m_deletePos];
|
||||
auto const dst2 = &p[(p.size() - m_deleteSz)];
|
||||
ox::memmove(dst1, src, p.size() - srcPos);
|
||||
ox::memset(dst2, 0, m_deleteSz * sizeof(decltype(p[0])));
|
||||
return {};
|
||||
@ -43,10 +43,10 @@ ox::Error core::DeleteTilesCommand::redo() noexcept {
|
||||
ox::Error DeleteTilesCommand::undo() noexcept {
|
||||
auto &s = getSubSheet(m_img, m_idx);
|
||||
auto &p = s.pixels;
|
||||
const auto src = p.data() + m_deletePos;
|
||||
const auto dst1 = p.data() + m_deletePos + m_deleteSz;
|
||||
const auto dst2 = src;
|
||||
const auto sz = p.size() - m_deletePos - m_deleteSz;
|
||||
auto const src = &p[m_deletePos];
|
||||
auto const dst1 = &p[m_deletePos + m_deleteSz];
|
||||
auto const dst2 = src;
|
||||
auto const sz = p.size() - m_deletePos - m_deleteSz;
|
||||
ox::memmove(dst1, src, sz);
|
||||
ox::memcpy(dst2, m_deletedPixels.data(), m_deletedPixels.size());
|
||||
return {};
|
||||
|
@ -21,10 +21,9 @@ core::InsertTilesCommand::InsertTilesCommand(
|
||||
{
|
||||
auto &s = getSubSheet(m_img, m_idx);
|
||||
auto &p = s.pixels;
|
||||
auto dst = m_deletedPixels.data();
|
||||
auto src = p.data() + p.size() - m_insertCnt;
|
||||
const auto sz = m_insertCnt * sizeof(decltype(p[0]));
|
||||
ox::memcpy(dst, src, sz);
|
||||
auto dst = m_deletedPixels.begin();
|
||||
auto src = p.begin() + p.size() - m_insertCnt;
|
||||
ox::copy_n(src, m_insertCnt, dst);
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,8 +31,8 @@ ox::Error InsertTilesCommand::redo() noexcept {
|
||||
auto &s = getSubSheet(m_img, m_idx);
|
||||
auto &p = s.pixels;
|
||||
auto dstPos = m_insertPos + m_insertCnt;
|
||||
const auto dst = p.data() + dstPos;
|
||||
const auto src = p.data() + m_insertPos;
|
||||
auto const dst = &p[dstPos];
|
||||
auto const src = &p[m_insertPos];
|
||||
ox::memmove(dst, src, p.size() - dstPos);
|
||||
ox::memset(src, 0, m_insertCnt * sizeof(decltype(p[0])));
|
||||
return {};
|
||||
@ -42,11 +41,11 @@ ox::Error InsertTilesCommand::redo() noexcept {
|
||||
ox::Error InsertTilesCommand::undo() noexcept {
|
||||
auto &s = getSubSheet(m_img, m_idx);
|
||||
auto &p = s.pixels;
|
||||
const auto srcIdx = m_insertPos + m_insertCnt;
|
||||
const auto src = p.data() + srcIdx;
|
||||
const auto dst1 = p.data() + m_insertPos;
|
||||
const auto dst2 = p.data() + p.size() - m_insertCnt;
|
||||
const auto sz = p.size() - srcIdx;
|
||||
auto const srcIdx = m_insertPos + m_insertCnt;
|
||||
auto const src = &p[srcIdx];
|
||||
auto const dst1 = &p[m_insertPos];
|
||||
auto const dst2 = &p[p.size() - m_insertCnt];
|
||||
auto const sz = p.size() - srcIdx;
|
||||
ox::memmove(dst1, src, sz);
|
||||
ox::memcpy(dst2, m_deletedPixels.data(), m_deletedPixels.size());
|
||||
return {};
|
||||
|
@ -120,7 +120,7 @@ ox::StringView TileSheetEditorModel::palPath() const noexcept {
|
||||
}
|
||||
constexpr ox::StringView uuidPrefix = "uuid://";
|
||||
if (ox::beginsWith(path, uuidPrefix)) {
|
||||
auto uuid = ox::StringView(path.data() + uuidPrefix.bytes(), path.bytes() - uuidPrefix.bytes());
|
||||
auto uuid = ox::StringView(&path[uuidPrefix.bytes()], path.bytes() - uuidPrefix.bytes());
|
||||
auto out = keelCtx(m_tctx).uuidToPath.at(uuid);
|
||||
if (out.error) {
|
||||
return {};
|
||||
@ -197,7 +197,7 @@ void TileSheetEditorModel::fill(ox::Point const&pt, int palIdx) noexcept {
|
||||
if (pt.x >= s.columns * TileWidth || pt.y >= s.rows * TileHeight) {
|
||||
return;
|
||||
}
|
||||
getFillPixels(updateMap.data(), pt, oldColor);
|
||||
getFillPixels(updateMap, pt, oldColor);
|
||||
ox::Vector<std::size_t> idxList;
|
||||
auto i = core::idx(s, pt) / PixelsPerTile * PixelsPerTile;
|
||||
for (auto u : updateMap) {
|
||||
@ -281,7 +281,7 @@ bool TileSheetEditorModel::pixelSelected(std::size_t idx) const noexcept {
|
||||
return m_selection && m_selection->contains(pt);
|
||||
}
|
||||
|
||||
void TileSheetEditorModel::getFillPixels(bool *pixels, ox::Point const&pt, int oldColor) const noexcept {
|
||||
void TileSheetEditorModel::getFillPixels(ox::Span<bool> pixels, ox::Point const&pt, int oldColor) const noexcept {
|
||||
const auto &activeSubSheet = this->activeSubSheet();
|
||||
const auto tileIdx = [activeSubSheet](const ox::Point &pt) noexcept {
|
||||
return ptToIdx(pt, activeSubSheet.columns) / PixelsPerTile;
|
||||
|
@ -128,7 +128,7 @@ class TileSheetEditorModel: public ox::SignalHandler {
|
||||
bool pixelSelected(std::size_t idx) const noexcept;
|
||||
|
||||
private:
|
||||
void getFillPixels(bool *pixels, ox::Point const&pt, int oldColor) const noexcept;
|
||||
void getFillPixels(ox::Span<bool> pixels, ox::Point const&pt, int oldColor) const noexcept;
|
||||
|
||||
void pushCommand(studio::UndoCommand *cmd) noexcept;
|
||||
|
||||
|
@ -163,8 +163,8 @@ unsigned pixelCnt(TileSheet::SubSheet const&ss, int8_t pBpp) noexcept {
|
||||
ox::Error resizeSubsheet(TileSheet::SubSheet &ss, int8_t pBpp, ox::Size const&sz) noexcept {
|
||||
ox::Vector<uint8_t> out;
|
||||
oxReturnError(setPixelCount(out, pBpp, static_cast<size_t>(sz.width * sz.height) * PixelsPerTile));
|
||||
auto const w = ss.columns * TileWidth;
|
||||
auto const h = ss.rows * TileHeight;
|
||||
auto const w = ox::min<int32_t>(ss.columns, sz.width) * TileWidth;
|
||||
auto const h = ox::min<int32_t>(ss.rows, sz.height) * TileHeight;
|
||||
for (auto x = 0; x < w; ++x) {
|
||||
for (auto y = 0; y < h; ++y) {
|
||||
auto const palIdx = getPixel(ss, pBpp, {x, y});
|
||||
|
@ -24,9 +24,10 @@ static std::map<ox::StringView, ox::Error(*)()> tests = {
|
||||
},
|
||||
};
|
||||
|
||||
int main(int argc, const char **args) {
|
||||
int main(int argc, const char **argv) {
|
||||
int retval = -1;
|
||||
if (argc > 0) {
|
||||
auto const args = ox::Span{argv, static_cast<size_t>(argc)};
|
||||
auto const testName = ox::StringView(args[1]);
|
||||
if (tests.find(testName) != tests.end()) {
|
||||
retval = static_cast<int>(tests[testName]());
|
||||
|
@ -1,7 +1,6 @@
|
||||
add_executable(
|
||||
nostalgia WIN32
|
||||
app.cpp
|
||||
main.cpp
|
||||
)
|
||||
|
||||
# enable LTO
|
||||
@ -23,6 +22,8 @@ endif()
|
||||
target_link_libraries(
|
||||
nostalgia
|
||||
NostalgiaKeelModules
|
||||
NostalgiaProfile
|
||||
OlympicApplib
|
||||
OxLogConn
|
||||
)
|
||||
|
||||
|
@ -65,8 +65,8 @@ static void testKeyEventHandler(turbine::Context &tctx, turbine::Key key, bool d
|
||||
|
||||
[[maybe_unused]]
|
||||
static ox::Error runTest(turbine::Context &tctx) {
|
||||
constexpr ox::FileAddress TileSheetAddr = ox::StringLiteral("/TileSheets/Charset.ng");
|
||||
constexpr ox::FileAddress PaletteAddr = ox::StringLiteral("/Palettes/Chester.npal");
|
||||
constexpr ox::StringView TileSheetAddr{"/TileSheets/Charset.ng"};
|
||||
constexpr ox::StringView PaletteAddr{"/Palettes/Chester.npal"};
|
||||
oxRequireM(cctx, core::init(tctx));
|
||||
turbine::setApplicationData(tctx, cctx.get());
|
||||
oxRequire(tsStat, turbine::rom(tctx)->stat(PaletteAddr));
|
||||
@ -84,24 +84,24 @@ static ox::Error runTest(turbine::Context &tctx) {
|
||||
static ox::Error runTileSheetSetTest(turbine::Context &tctx) {
|
||||
// this should make the screen display 'ABCDB', with the A being upside down
|
||||
// and the first B being backwards
|
||||
constexpr ox::FileAddress PaletteAddr = ox::StringLiteral("/Palettes/Charset.npal");
|
||||
constexpr ox::StringView PaletteAddr{"/Palettes/Charset.npal"};
|
||||
oxRequireM(cctx, core::init(tctx));
|
||||
turbine::setApplicationData(tctx, cctx.get());
|
||||
oxRequire(tsStat, turbine::rom(tctx)->stat(PaletteAddr));
|
||||
core::TileSheetSet const set{
|
||||
.bpp = 4,
|
||||
.entries = {
|
||||
{ .tilesheet = ox::StringLiteral("/TileSheets/Chester.ng"), .sections{{.begin = 0, .tiles = 1}} },
|
||||
{ .tilesheet = ox::StringLiteral("/TileSheets/AB.ng"), .sections{{.begin = 0, .tiles = 2}} },
|
||||
{ .tilesheet = ox::StringLiteral("/TileSheets/CD.ng"), .sections{{.begin = 0, .tiles = 2}} },
|
||||
{ .tilesheet = ox::StringLiteral("/TileSheets/AB.ng"), .sections{{.begin = 1, .tiles = 1}} },
|
||||
{ .tilesheet = ox::StringLiteral{"/TileSheets/Chester.ng"}, .sections{{.begin = 0, .tiles = 1}} },
|
||||
{ .tilesheet = ox::StringLiteral{"/TileSheets/AB.ng"}, .sections{{.begin = 0, .tiles = 2}} },
|
||||
{ .tilesheet = ox::StringLiteral{"/TileSheets/CD.ng"}, .sections{{.begin = 0, .tiles = 2}} },
|
||||
{ .tilesheet = ox::StringLiteral{"/TileSheets/AB.ng"}, .sections{{.begin = 1, .tiles = 1}} },
|
||||
},
|
||||
};
|
||||
constexpr auto bgPalBank = 1;
|
||||
oxReturnError(core::loadBgTileSheet(*cctx, 0, set));
|
||||
oxReturnError(core::loadSpriteTileSheet(*cctx, set));
|
||||
oxReturnError(core::loadBgPalette(*cctx, bgPalBank, PaletteAddr));
|
||||
oxReturnError(core::loadBgPalette(*cctx, 0, ox::StringLiteral("/Palettes/Chester.npal")));
|
||||
oxReturnError(core::loadBgPalette(*cctx, 0, PaletteAddr));
|
||||
oxReturnError(core::loadSpritePalette(*cctx, PaletteAddr));
|
||||
core::setBgStatus(*cctx, 0, true);
|
||||
core::setBgTile(*cctx, 0, 10, 9, { .tileIdx = 1, .palBank = bgPalBank, .flipX = 0, .flipY = 1 });
|
||||
@ -147,7 +147,7 @@ static void sceneKeyEventHandler(turbine::Context &tctx, turbine::Key key, bool
|
||||
|
||||
[[maybe_unused]]
|
||||
static ox::Error runScene(turbine::Context &tctx) {
|
||||
constexpr ox::FileAddress SceneAddr = ox::StringLiteral("/Scenes/Chester.nscn");
|
||||
constexpr ox::StringView SceneAddr{"/Scenes/Chester.nscn"};
|
||||
oxRequireM(cctx, core::init(tctx));
|
||||
oxRequire(scn, keel::readObj<scene::SceneStatic>(keelCtx(tctx), SceneAddr));
|
||||
turbine::setUpdateHandler(tctx, sceneUpdateHandler);
|
||||
@ -157,7 +157,20 @@ static ox::Error runScene(turbine::Context &tctx) {
|
||||
return turbine::run(tctx);
|
||||
}
|
||||
|
||||
ox::Error run(ox::UniquePtr<ox::FileSystem> &&fs) noexcept {
|
||||
oxRequireM(tctx, turbine::init(std::move(fs), "Nostalgia"));
|
||||
namespace olympic {
|
||||
|
||||
ox::Error run(
|
||||
[[maybe_unused]] ox::StringView project,
|
||||
[[maybe_unused]] ox::StringView appName,
|
||||
[[maybe_unused]] ox::StringView projectDataDir,
|
||||
ox::SpanView<char const*> args) noexcept {
|
||||
if (args.size() < 2) {
|
||||
return OxError(1, "Please provide path to project directory or OxFS file.");
|
||||
}
|
||||
auto const path = args[1];
|
||||
oxRequireM(fs, keel::loadRomFs(path));
|
||||
oxRequireM(tctx, turbine::init(std::move(fs), project));
|
||||
return runTileSheetSetTest(*tctx);
|
||||
}
|
||||
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Copyright 2016 - 2024 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#include <ox/logconn/def.hpp>
|
||||
#include <ox/logconn/logconn.hpp>
|
||||
|
||||
#include <keel/media.hpp>
|
||||
|
||||
#include "../modules/keelmodules.hpp"
|
||||
|
||||
#include "app.hpp"
|
||||
|
||||
static ox::Error run(int argc, const char **argv) noexcept {
|
||||
#ifndef OX_BARE_METAL
|
||||
// GBA doesn't need the modules and calling this doubles the size of the
|
||||
// binary.
|
||||
nostalgia::registerKeelModules();
|
||||
#endif
|
||||
if (argc < 2) {
|
||||
return OxError(1, "Please provide path to project directory or OxFS file.");
|
||||
}
|
||||
const auto path = argv[1];
|
||||
oxRequireM(fs, keel::loadRomFs(path));
|
||||
return run(std::move(fs));
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
int WinMain() {
|
||||
auto const argc = __argc;
|
||||
auto const argv = const_cast<const char**>(__argv);
|
||||
#else
|
||||
int main(int argc, const char **argv) {
|
||||
#endif
|
||||
OX_INIT_DEBUG_LOGGER(loggerConn, "Nostalgia Player")
|
||||
ox::Error err;
|
||||
err = run(argc, argv);
|
||||
oxAssert(err, "Something went wrong...");
|
||||
if (err) {
|
||||
oxErrf("Failure: {}\n", toStr(err));
|
||||
}
|
||||
return static_cast<int>(err);
|
||||
}
|
@ -1,3 +1,8 @@
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang")
|
||||
# enable warnings
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wunsafe-buffer-usage")
|
||||
endif()
|
||||
|
||||
if(BUILDCORE_TARGET STREQUAL "gba")
|
||||
project(Olympic ASM CXX)
|
||||
else()
|
||||
|
@ -41,8 +41,7 @@ ox::Error run(
|
||||
ox::StringView project,
|
||||
ox::StringView appName,
|
||||
ox::StringView projectDataDir,
|
||||
int argc,
|
||||
char const**argv) noexcept;
|
||||
ox::SpanView<char const*> argv) noexcept;
|
||||
|
||||
}
|
||||
|
||||
@ -65,7 +64,11 @@ int main(int argc, char const**argv) {
|
||||
#if OLYMPIC_LOAD_STUDIO_MODULES
|
||||
OLYMPIC_PROJECT_NAMESPACE::registerStudioModules();
|
||||
#endif
|
||||
auto const err = olympic::run(OLYMPIC_PROJECT_NAME, OLYMPIC_APP_NAME, OLYMPIC_PROJECT_DATADIR, argc, argv);
|
||||
auto const err = olympic::run(
|
||||
OLYMPIC_PROJECT_NAME,
|
||||
OLYMPIC_APP_NAME,
|
||||
OLYMPIC_PROJECT_DATADIR,
|
||||
{argv, static_cast<size_t>(argc)});
|
||||
oxAssert(err, "Something went wrong...");
|
||||
if (err) {
|
||||
oxErrf("Failure: {}\n", toStr(err));
|
||||
|
@ -7,6 +7,8 @@
|
||||
#include <ox/claw/claw.hpp>
|
||||
#include <ox/fs/fs.hpp>
|
||||
|
||||
#include "validation.hpp"
|
||||
|
||||
namespace keel {
|
||||
|
||||
constexpr auto K1HdrSz = 40;
|
||||
@ -26,7 +28,10 @@ ox::Result<T> readAsset(ox::BufferView buff) noexcept {
|
||||
if (!err) {
|
||||
offset = K1HdrSz; // the size of K1 headers
|
||||
}
|
||||
return ox::readClaw<T>(buff + offset);
|
||||
auto out = ox::readClaw<T>(buff + offset);
|
||||
oxReturnError(out);
|
||||
oxReturnError(ensureValid(out.value));
|
||||
return out;
|
||||
}
|
||||
|
||||
ox::Result<ox::ModelObject> readAsset(ox::TypeStore &ts, ox::BufferView buff) noexcept;
|
||||
|
@ -14,8 +14,6 @@
|
||||
#include <ox/std/hashmap.hpp>
|
||||
#include <ox/std/utility.hpp>
|
||||
|
||||
#include "validation.hpp"
|
||||
|
||||
namespace keel {
|
||||
|
||||
class AssetManager;
|
||||
@ -190,7 +188,7 @@ class AssetManager {
|
||||
private:
|
||||
class AssetTypeManagerBase: public ox::SignalHandler {
|
||||
public:
|
||||
virtual ~AssetTypeManagerBase() = default;
|
||||
~AssetTypeManagerBase() override = default;
|
||||
|
||||
virtual void gc() noexcept = 0;
|
||||
};
|
||||
@ -217,7 +215,6 @@ class AssetManager {
|
||||
ox::Result<AssetRef<T>> loadAsset(ox::StringView const assetId) noexcept {
|
||||
auto &p = m_cache[assetId];
|
||||
oxRequireM(obj, m_loader(assetId));
|
||||
oxReturnError(ensureValid(obj));
|
||||
if (!p) {
|
||||
p = ox::make_unique<AssetContainer<T>>(std::move(obj));
|
||||
} else {
|
||||
|
@ -63,10 +63,8 @@ namespace detail {
|
||||
template<typename T>
|
||||
constexpr auto makeLoader(Context &ctx) {
|
||||
return [&ctx](ox::StringView assetId) -> ox::Result<T> {
|
||||
ox::StringView path;
|
||||
oxRequire(p, ctx.uuidToPath.at(assetId));
|
||||
path = *p;
|
||||
oxRequire(buff, ctx.rom->read(path));
|
||||
oxRequire(buff, ctx.rom->read(*p));
|
||||
auto [obj, err] = readAsset<T>(buff);
|
||||
if (err) {
|
||||
if (err != ox::Error_ClawTypeVersionMismatch && err != ox::Error_ClawTypeMismatch) {
|
||||
@ -84,21 +82,17 @@ ox::Result<keel::AssetRef<T>> readObjFile(
|
||||
keel::Context &ctx,
|
||||
ox::StringView assetId,
|
||||
bool forceLoad) noexcept {
|
||||
ox::UUIDStr uuidStr;
|
||||
if (beginsWith(assetId, "uuid://")) {
|
||||
assetId = substr(assetId, 7);
|
||||
oxRequire(p, keel::uuidToPath(ctx, assetId));
|
||||
} else {
|
||||
auto const [uuid, uuidErr] = getUuid(ctx, assetId);
|
||||
if (!uuidErr) {
|
||||
uuidStr = uuid.toString();
|
||||
assetId = uuidStr;
|
||||
assetId = uuid.toString();
|
||||
}
|
||||
}
|
||||
if (forceLoad) {
|
||||
ctx.assetManager.initTypeManager<T>(detail::makeLoader<T>, ctx);
|
||||
oxRequire(cached, ctx.assetManager.loadAsset<T>(assetId));
|
||||
return cached;
|
||||
return ctx.assetManager.loadAsset<T>(assetId);
|
||||
} else {
|
||||
auto [cached, err] = ctx.assetManager.getAsset<T>(assetId);
|
||||
if (err) {
|
||||
|
@ -7,8 +7,6 @@
|
||||
#include <ox/std/def.hpp>
|
||||
#include <ox/std/error.hpp>
|
||||
#include <ox/std/string.hpp>
|
||||
#include <ox/claw/read.hpp>
|
||||
#include <ox/claw/write.hpp>
|
||||
|
||||
#include "asset.hpp"
|
||||
#include "context.hpp"
|
||||
@ -119,7 +117,6 @@ class Converter: public BaseConverter {
|
||||
ox::Result<ox::UPtr<Wrap>> convertBuffToPtr(
|
||||
keel::Context &ctx, ox::BufferView const&srcBuff) const noexcept final {
|
||||
oxRequireM(src, readAsset<SrcType>(srcBuff));
|
||||
oxReturnError(ensureValid(src));
|
||||
auto dst = makeWrap<DstType>();
|
||||
oxReturnError(convert(ctx, src, wrapCast<DstType>(*dst)));
|
||||
return {std::move(dst)};
|
||||
|
@ -14,7 +14,7 @@ ox::Result<ox::UUID> readUuidHeader(ox::BufferView buff) noexcept {
|
||||
if (k1Hdr != ox::StringView(buff.data(), k1Hdr.bytes())) [[unlikely]] {
|
||||
return OxError(2, "No Keel asset header data");
|
||||
}
|
||||
return ox::UUID::fromString(ox::StringView(buff.data() + k1Hdr.bytes(), 36));
|
||||
return ox::UUID::fromString(ox::StringView(&buff[k1Hdr.bytes()], 36));
|
||||
}
|
||||
|
||||
ox::Result<ox::ModelObject> readAsset(ox::TypeStore &ts, ox::BufferView buff) noexcept {
|
||||
|
@ -9,7 +9,9 @@ namespace keel {
|
||||
static ox::Vector<Module const*> mods;
|
||||
|
||||
void registerModule(Module const*mod) noexcept {
|
||||
mods.emplace_back(mod);
|
||||
if (mod) {
|
||||
mods.emplace_back(mod);
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
|
@ -81,8 +81,8 @@ static ox::Error pack(
|
||||
return {};
|
||||
}
|
||||
|
||||
static ox::Error run(int argc, char const**argv, ox::StringView projectDataDir) noexcept {
|
||||
ox::ClArgs const args(argc, argv);
|
||||
static ox::Error run(ox::SpanView<char const*> argv, ox::StringView projectDataDir) noexcept {
|
||||
ox::ClArgs const args(argv);
|
||||
auto const argSrc = args.getString("src", "");
|
||||
auto const argRomBin = args.getString("rom-bin", "");
|
||||
auto const argManifest = args.getString("manifest", "");
|
||||
@ -103,9 +103,8 @@ ox::Error run(
|
||||
[[maybe_unused]] ox::StringView project,
|
||||
[[maybe_unused]] ox::StringView appName,
|
||||
ox::StringView projectDataDir,
|
||||
int argc,
|
||||
char const**argv) noexcept {
|
||||
return ::run(argc, argv, projectDataDir);
|
||||
ox::SpanView<char const*> argv) noexcept {
|
||||
return ::run(argv, projectDataDir);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -15,16 +15,22 @@ static ox::Error pathToInode(
|
||||
ox::FileSystem &dest,
|
||||
ox::ModelObject &obj) noexcept {
|
||||
auto &o = obj;
|
||||
auto type = static_cast<ox::FileAddressType>(o.at("type").unwrap()->get<int8_t>());
|
||||
auto &data = o.at("data").unwrap()->get<ox::ModelUnion>();
|
||||
oxRequire(typeVal, o.at("type"));
|
||||
auto const type = static_cast<ox::FileAddressType>(typeVal->get<int8_t>());
|
||||
oxRequire(dataVal, o.at("data"));
|
||||
auto &data = dataVal->get<ox::ModelUnion>();
|
||||
ox::String path;
|
||||
switch (type) {
|
||||
case ox::FileAddressType::Path:
|
||||
path = data.at("path").unwrap()->get<ox::String>();
|
||||
case ox::FileAddressType::Path: {
|
||||
oxRequire(pathVal, data.at("path"));
|
||||
path = pathVal->get<ox::String>();
|
||||
break;
|
||||
case ox::FileAddressType::ConstPath:
|
||||
path = data.at("constPath").unwrap()->get<ox::String>();
|
||||
}
|
||||
case ox::FileAddressType::ConstPath: {
|
||||
oxRequire(pathVal, data.at("constPath"));
|
||||
path = pathVal->get<ox::String>();
|
||||
break;
|
||||
}
|
||||
case ox::FileAddressType::Inode:
|
||||
case ox::FileAddressType::None:
|
||||
return {};
|
||||
@ -34,7 +40,7 @@ static ox::Error pathToInode(
|
||||
oxReturnError(keel::uuidToPath(ctx, uuid).to<ox::String>().moveTo(path));
|
||||
}
|
||||
oxRequire(s, dest.stat(path));
|
||||
oxReturnError(o.at("type").unwrap()->set(static_cast<int8_t>(ox::FileAddressType::Inode)));
|
||||
oxReturnError(typeVal->set(static_cast<int8_t>(ox::FileAddressType::Inode)));
|
||||
oxOutf("\tpath to inode: {} => {}\n", path, s.inode);
|
||||
return data.set(2, s.inode);
|
||||
}
|
||||
@ -162,12 +168,12 @@ static ox::Error copy(
|
||||
// copy
|
||||
oxRequire(fileList, src.ls(path));
|
||||
for (auto const&name : fileList) {
|
||||
auto currentFile = ox::sfmt("{}{}", path, name);
|
||||
auto const currentFile = ox::sfmt("{}{}", path, name);
|
||||
if (beginsWith(name, ".")) {
|
||||
continue;
|
||||
}
|
||||
oxRequire(stat, src.stat(currentFile));
|
||||
if (stat.fileType == ox::FileType::Directory) {
|
||||
oxRequire(srcStat, src.stat(currentFile));
|
||||
if (srcStat.fileType == ox::FileType::Directory) {
|
||||
oxReturnError(dest.mkdir(currentFile, true));
|
||||
oxReturnError(copy(manifest, src, dest, currentFile + '/', childLogPrefix));
|
||||
} else {
|
||||
@ -181,9 +187,9 @@ static ox::Error copy(
|
||||
// write file to dest
|
||||
oxReturnError(dest.write(currentFile, buff));
|
||||
status = "OK";
|
||||
oxRequire(stat, dest.stat(currentFile));
|
||||
oxRequire(dstStat, dest.stat(currentFile));
|
||||
manifest.files[currentFile] = {
|
||||
.inode = stat.inode,
|
||||
.inode = dstStat.inode,
|
||||
.type = ox::String{keel::readAssetTypeId(buff).or_value({})},
|
||||
};
|
||||
}
|
||||
|
@ -2,8 +2,6 @@
|
||||
* Copyright 2016 - 2024 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
||||
*/
|
||||
|
||||
#include <ox/claw/read.hpp>
|
||||
|
||||
#include <keel/media.hpp>
|
||||
#include <keel/typeconv.hpp>
|
||||
|
||||
|
@ -25,9 +25,10 @@ static std::map<ox::StringView, ox::Error(*)()> tests = {
|
||||
},
|
||||
};
|
||||
|
||||
int main(int argc, const char **args) {
|
||||
int main(int argc, const char **argv) {
|
||||
int retval = -1;
|
||||
if (argc > 0) {
|
||||
auto const args = ox::Span{argv, static_cast<size_t>(argc)};
|
||||
auto testName = args[1];
|
||||
if (tests.find(testName) != tests.end()) {
|
||||
retval = static_cast<int>(tests[testName]());
|
||||
|
@ -52,8 +52,7 @@ static ox::Error runApp(
|
||||
static ox::Error run(
|
||||
ox::StringViewCR appName,
|
||||
ox::StringViewCR projectDataDir,
|
||||
int,
|
||||
char const**) {
|
||||
ox::SpanView<const char*>) {
|
||||
// seed UUID generator
|
||||
auto const time = std::time(nullptr);
|
||||
ox::UUID::seedGenerator({
|
||||
@ -74,9 +73,8 @@ ox::Error run(
|
||||
ox::StringView project,
|
||||
ox::StringView appName,
|
||||
ox::StringView projectDataDir,
|
||||
int argc,
|
||||
char const**argv) noexcept {
|
||||
return studio::run(ox::sfmt("{} {}", project, appName), projectDataDir, argc, argv);
|
||||
ox::SpanView<char const*> args) noexcept {
|
||||
return studio::run(ox::sfmt("{} {}", project, appName), projectDataDir, args);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -63,12 +63,14 @@ void NewMenu::addItemMaker(ox::UniquePtr<studio::ItemMaker> &&im) noexcept {
|
||||
|
||||
void NewMenu::drawNewItemType(studio::StudioContext &sctx) noexcept {
|
||||
drawWindow(sctx.tctx, &m_open, [this] {
|
||||
auto items = ox_malloca(m_types.size() * sizeof(char const*), char const*, nullptr);
|
||||
auto const allocSz = m_types.size() * sizeof(char const*);
|
||||
auto mem = ox_malloca(allocSz, char const*, nullptr);
|
||||
auto items = ox::Span{mem.get(), allocSz};
|
||||
for (auto i = 0u; auto const&im : m_types) {
|
||||
items.get()[i] = im->typeName.c_str();
|
||||
items[i] = im->typeName.c_str();
|
||||
++i;
|
||||
}
|
||||
ImGui::ListBox("Item Type", &m_selectedType, items.get(), static_cast<int>(m_types.size()));
|
||||
ImGui::ListBox("Item Type", &m_selectedType, items.data(), static_cast<int>(m_types.size()));
|
||||
drawFirstPageButtons();
|
||||
});
|
||||
}
|
||||
@ -116,11 +118,12 @@ void NewMenu::drawLastPageButtons(studio::StudioContext &sctx) noexcept {
|
||||
|
||||
void NewMenu::finish(studio::StudioContext &sctx) noexcept {
|
||||
if (m_itemName.len() == 0) {
|
||||
oxLogError(OxError(1, "New file error: no file name"));
|
||||
return;
|
||||
}
|
||||
auto const&typeMaker = *m_types[static_cast<std::size_t>(m_selectedType)];
|
||||
if (sctx.project->exists(typeMaker.itemPath(m_itemName))) {
|
||||
oxLogError(OxError(1, "New file error: File already exists"));
|
||||
oxLogError(OxError(1, "New file error: file already exists"));
|
||||
return;
|
||||
}
|
||||
auto const [path, err] = typeMaker.write(sctx, m_itemName);
|
||||
|
@ -21,7 +21,9 @@ namespace studio {
|
||||
static ox::Vector<studio::Module const*> modules;
|
||||
|
||||
void registerModule(studio::Module const*mod) noexcept {
|
||||
modules.emplace_back(mod);
|
||||
if (mod) {
|
||||
modules.emplace_back(mod);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -238,18 +240,18 @@ void StudioUI::loadEditorMaker(studio::EditorMaker const&editorMaker) noexcept {
|
||||
}
|
||||
}
|
||||
|
||||
void StudioUI::loadModule(studio::Module const*mod) noexcept {
|
||||
for (auto const&editorMaker : mod->editors(m_sctx)) {
|
||||
void StudioUI::loadModule(studio::Module const&mod) noexcept {
|
||||
for (auto const&editorMaker : mod.editors(m_sctx)) {
|
||||
loadEditorMaker(editorMaker);
|
||||
}
|
||||
for (auto &im : mod->itemMakers(m_sctx)) {
|
||||
for (auto &im : mod.itemMakers(m_sctx)) {
|
||||
m_newMenu.addItemMaker(std::move(im));
|
||||
}
|
||||
}
|
||||
|
||||
void StudioUI::loadModules() noexcept {
|
||||
for (auto const mod : modules) {
|
||||
loadModule(mod);
|
||||
loadModule(*mod);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -69,7 +69,7 @@ class StudioUI: public ox::SignalHandler {
|
||||
|
||||
void loadEditorMaker(studio::EditorMaker const&editorMaker) noexcept;
|
||||
|
||||
void loadModule(studio::Module const*mod) noexcept;
|
||||
void loadModule(studio::Module const&mod) noexcept;
|
||||
|
||||
void loadModules() noexcept;
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <ox/std/defines.hpp>
|
||||
#include <ox/std/string.hpp>
|
||||
|
||||
namespace studio {
|
||||
|
||||
@ -24,4 +25,4 @@ ox::Result<ox::String> saveFile(ox::Vector<FDFilterItem> const&exts) noexcept;
|
||||
|
||||
ox::Result<ox::String> chooseDirectory() noexcept;
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -189,7 +189,7 @@ bool BeginPopup(turbine::Context &ctx, ox::CStringView popupName, bool &show, Im
|
||||
* @param selectedIdx
|
||||
* @return true if new value selected, false otherwise
|
||||
*/
|
||||
bool ComboBox(ox::CStringView lbl, ox::SpanView<ox::String> list, size_t &selectedIdx) noexcept;
|
||||
bool ComboBox(ox::CStringView lbl, ox::Span<const ox::String> list, size_t &selectedIdx) noexcept;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -223,7 +223,7 @@ bool ListBox(
|
||||
* @param selIdx
|
||||
* @return true if new value selected, false otherwise
|
||||
*/
|
||||
bool ListBox(ox::CStringView name, ox::SpanView<ox::String> const&list, size_t &selIdx) noexcept;
|
||||
bool ListBox(ox::CStringView name, ox::Span<const ox::String> const&list, size_t &selIdx) noexcept;
|
||||
|
||||
class FilePicker {
|
||||
private:
|
||||
|
@ -22,10 +22,12 @@ static ox::Result<ox::String> toResult(nfdresult_t r, NFD::UniquePathN const&pat
|
||||
switch (r) {
|
||||
case NFD_OKAY: {
|
||||
ox::String out;
|
||||
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
|
||||
for (auto i = 0u; path.get()[i]; ++i) {
|
||||
auto const c = static_cast<char>(path.get()[i]);
|
||||
std::ignore = out.append(&c, 1);
|
||||
}
|
||||
OX_ALLOW_UNSAFE_BUFFERS_END
|
||||
return out;
|
||||
}
|
||||
case NFD_CANCEL:
|
||||
@ -35,11 +37,11 @@ static ox::Result<ox::String> toResult(nfdresult_t r, NFD::UniquePathN const&pat
|
||||
}
|
||||
}
|
||||
|
||||
ox::Result<ox::String> saveFile(ox::Vector<FDFilterItem> const&filters) noexcept {
|
||||
ox::Result<ox::String> saveFile(ox::Vector<FDFilterItem> const&exts) noexcept {
|
||||
NFD::Guard const guard;
|
||||
NFD::UniquePathN path;
|
||||
ox::Vector<nfdnfilteritem_t, 5> filterItems(filters.size());
|
||||
for (auto i = 0u; auto const&f : filters) {
|
||||
ox::Vector<nfdnfilteritem_t, 5> filterItems(exts.size());
|
||||
for (auto i = 0u; auto const&f : exts) {
|
||||
filterItems[i].name = f.name.data();
|
||||
filterItems[i].spec = f.spec.data();
|
||||
++i;
|
||||
|
@ -87,7 +87,7 @@ bool BeginPopup(turbine::Context &ctx, ox::CStringView popupName, bool &show, Im
|
||||
|
||||
bool ComboBox(
|
||||
ox::CStringView lbl,
|
||||
ox::SpanView<ox::String> list,
|
||||
ox::Span<const ox::String> list,
|
||||
size_t &selectedIdx) noexcept {
|
||||
bool out{};
|
||||
auto const first = selectedIdx < list.size() ? list[selectedIdx].c_str() : "";
|
||||
@ -155,7 +155,7 @@ bool ListBox(
|
||||
return out;
|
||||
}
|
||||
|
||||
bool ListBox(ox::CStringView name, ox::SpanView<ox::String> const&list, size_t &selIdx) noexcept {
|
||||
bool ListBox(ox::CStringView name, ox::Span<const ox::String> const&list, size_t &selIdx) noexcept {
|
||||
return ListBox(name, [list](size_t i) -> ox::CStringView {
|
||||
return list[i];
|
||||
}, list.size(), selIdx);
|
||||
|
@ -47,12 +47,14 @@ static ox::Result<std::size_t> findPreloadSection() noexcept {
|
||||
constexpr auto headerP1Len = ox::strlen(headerP2);
|
||||
constexpr auto headerP2Len = ox::strlen(headerP1);
|
||||
constexpr auto headerLen = headerP1Len + headerP2Len;
|
||||
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
|
||||
for (auto current = MEM_ROM; current < reinterpret_cast<char*>(0x0a000000); current += headerLen) {
|
||||
if (memcmp(current, headerP1, headerP1Len) == 0 &&
|
||||
memcmp(current + headerP1Len, headerP2, headerP2Len) == 0) {
|
||||
return reinterpret_cast<std::size_t>(current + headerLen);
|
||||
}
|
||||
}
|
||||
OX_ALLOW_UNSAFE_BUFFERS_END
|
||||
return OxError(1);
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user