Compare commits

..

No commits in common. "72f4db3d5ea1fc6da4f0b73a9df456932b868718" and "3c7652efc205cb3acdb993d7eeb1e2c2d894c2cb" have entirely different histories.

25 changed files with 155 additions and 173 deletions

44
.vs/launch.vs.json Normal file
View File

@ -0,0 +1,44 @@
{
"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"
]
}
]
}

10
deps/ox/ox-docs.md vendored
View File

@ -176,10 +176,14 @@ ox::Result<int> f2() noexcept {
```
```oxRequire``` is not quite as versatile, but it should still cleanup a lot of otherwise less ideal code.
```oxRequire``` by default creates a const, but there is also an ```oxRequireM``` (oxRequire Mutable)
variant for creating a non-const value.
```oxRequire``` also has variants for throwing the error and for making to value non-const:
* ```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
@ -203,7 +207,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 should be used only when there is an error that is not technically fatal, but
It shuld 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```:

View File

@ -9,8 +9,8 @@
#ifdef OX_USE_STDLIB
#include <cstdio>
#ifndef _WIN32
#include <sys/types.h>
#ifndef _WIN32
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
@ -25,22 +25,15 @@
#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;
static void closeSock(auto s) noexcept {
void closeSock(auto s) noexcept {
#ifdef _WIN32
closesocket(static_cast<Socket>(s));
closesocket(s);
#else
close(s);
#endif
@ -63,8 +56,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 = 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)))));
m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
oxReturnError(OxError(static_cast<ox::ErrorCode>(connect(m_socket, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)))));
return sendInit({.appName = ox::BasicString<128>(appName)});
}
@ -72,9 +65,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(static_cast<Socket>(m_socket), buff, static_cast<LenType>(len), 0);
const auto sent = ::send(m_socket, buff, len, 0);
if (sent < 0) {
std::ignore = std::fprintf(stderr, "Could not send msg\n");
std::fprintf(stderr, "Could not send msg\n");
return OxError(1, "Could not send msg");
}
totalSent += static_cast<std::size_t>(sent);
@ -97,14 +90,13 @@ void LoggerConn::msgSend() noexcept {
if (!m_running) {
break;
}
std::lock_guard const buffLk(m_buffMut);
std::lock_guard buffLk(m_buffMut);
while (true) {
Array<char, units::KB> tmp;
ox::Array<char, ox::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);
}

View File

@ -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 {};
return OxError(0);
}
using SubscriptStack = Vector<Subscript, 3>;
@ -119,7 +119,6 @@ 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:
@ -203,7 +202,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 {};
return OxError(0);
}
template<typename T>
@ -216,7 +215,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 {};
return OxError(0);
}
template<typename ReaderBase>

View File

@ -97,14 +97,8 @@ class TypeDescWriter {
std::size_t fields = ModelFieldCount_v<T>) noexcept;
template<typename T>
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;
constexpr Error field(StringViewCR name, const T *val, std::size_t valLen,
const SubscriptStack &subscriptStack = {}) noexcept;
template<typename T, bool force>
constexpr Error field(StringViewCR name, UnionView<T, force> val) noexcept;
@ -199,7 +193,7 @@ constexpr ox::Error TypeDescWriter::setTypeInfo(
// array handler
template<typename T>
constexpr Error TypeDescWriter::field(StringViewCR name, T const*, std::size_t, SubscriptStack const&subscriptStack) noexcept {
constexpr Error TypeDescWriter::field(StringViewCR name, const T*, std::size_t, const SubscriptStack &subscriptStack) noexcept {
if (m_type) {
constexpr typename remove_pointer<T>::type *p = nullptr;
const auto t = type(p);
@ -210,21 +204,6 @@ constexpr Error TypeDescWriter::field(StringViewCR name, T const*, 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) {

View File

@ -188,8 +188,8 @@ class ModelValue {
constexpr Error setType(
DescriptorType const*type,
SubscriptStack const& = {},
int subscriptLevels = 0) noexcept;
int subscriptLevels = 0,
SubscriptStack const& = {}) 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_subscriptStack, m_typeSubscriptLevels));
oxReturnError(m_vec[i].setType(m_type, m_typeSubscriptLevels));
}
}
return {};
@ -276,9 +276,8 @@ class ModelValueArray {
constexpr Error setType(
DescriptorType const*type,
SubscriptStack subscriptStack,
int subscriptLevels) noexcept {
oxAssert(subscriptLevels <= static_cast<int>(subscriptStack.size()), "subscript level mismatch");
int subscriptLevels,
SubscriptStack subscriptStack) noexcept {
m_type = type;
m_typeSubscriptLevels = subscriptLevels;
m_subscriptStack = std::move(subscriptStack);
@ -401,7 +400,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_subscriptStack, m_typeSubscriptLevels));
oxReturnError(m_vec[i].setType(m_type, m_typeSubscriptLevels, m_subscriptStack));
}
}
return {};
@ -419,9 +418,8 @@ class ModelValueVector {
constexpr Error setType(
DescriptorType const*type,
SubscriptStack subscriptStack,
int subscriptLevels) noexcept {
oxAssert(subscriptLevels <= static_cast<int>(subscriptStack.size()), "subscript level mismatch");
int subscriptLevels,
SubscriptStack subscriptStack) noexcept {
m_type = type;
m_typeSubscriptLevels = subscriptLevels;
m_subscriptStack = std::move(subscriptStack);
@ -676,11 +674,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.subscriptStack, f.subscriptLevels));
oxReturnError(field->value.setType(f.type, f.subscriptLevels, f.subscriptStack));
m_fields[field->name] = &field->value;
m_fieldsOrder.emplace_back(std::move(field));
}
return {};
return OxError(0);
}
};
@ -799,12 +797,12 @@ class ModelUnion {
auto field = make_unique<Field>();
field->name = f.fieldName;
field->idx = i;
oxReturnError(field->value.setType(f.type, SubscriptStack{static_cast<size_t>(f.subscriptLevels)}, f.subscriptLevels));
oxReturnError(field->value.setType(f.type, f.subscriptLevels));
m_fields[field->name] = field.get();
m_fieldsOrder.emplace_back(std::move(field));
++i;
}
return {};
return OxError(0);
}
[[nodiscard]]
@ -1078,21 +1076,20 @@ constexpr ModelValue::Type ModelValue::type() const noexcept {
constexpr Error ModelValue::setType(
const DescriptorType *type,
SubscriptStack const&subscriptStack,
int subscriptLevels) noexcept {
int subscriptLevels,
SubscriptStack const&subscriptStack) 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, subscriptStack, subscriptLevels - 1));
oxReturnError(m_data.array->setType(type, subscriptLevels - 1, subscriptStack));
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, subscriptStack, subscriptLevels - 1));
oxReturnError(m_data.vec->setType(type, subscriptLevels - 1, subscriptStack));
}
return {};
} else if (type->typeName == types::Bool) {

View File

@ -174,13 +174,11 @@ 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];
}

View File

@ -6,7 +6,6 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
#include "fmt.hpp"
#include "stacktrace.hpp"
#include "trace.hpp"
@ -14,7 +13,7 @@
namespace ox {
void panic(StringViewCR file, int line, StringViewCR panicMsg, const Error &err) noexcept {
void panic(const char *file, int line, const char *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);
@ -32,40 +31,4 @@ void panic(StringViewCR file, int line, StringViewCR panicMsg, const Error &err)
#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
}
}

View File

@ -32,13 +32,19 @@ 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()) {
assertFailFuncRuntime(file, line, assertTxt, msg);
#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
} else {
while (true);
}
@ -48,7 +54,22 @@ 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()) {
assertFailFuncRuntime(file, line, err, {}, assertMsg);
#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
} else {
while (true);
}

View File

@ -44,6 +44,10 @@
// 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

View File

@ -24,7 +24,6 @@ class exception {
}
#endif
#include "defines.hpp"
#include "def.hpp"
#include "typetraits.hpp"
#include "utility.hpp"
@ -333,12 +332,4 @@ 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));
}
}
}
}

View File

@ -103,12 +103,10 @@ class SpanView {
}
constexpr const T &operator[](std::size_t i) const noexcept {
ox::primitiveAssert(__FILE__, __LINE__, i < size(), "Span access overflow");
return m_items[i];
}
constexpr SpanView operator+(size_t i) const noexcept {
ox::primitiveAssert(__FILE__, __LINE__, i < size(), "Span access overflow");
return {m_items + i, m_size - i};
}
@ -231,12 +229,10 @@ class Span {
}
constexpr T &operator[](std::size_t i) noexcept {
ox::primitiveAssert(__FILE__, __LINE__, i < size(), "Span overflow");
return m_items[i];
}
constexpr const T &operator[](std::size_t i) const noexcept {
ox::primitiveAssert(__FILE__, __LINE__, i < size(), "Span overflow");
return m_items[i];
}

View File

@ -10,17 +10,6 @@
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();
}
@ -30,6 +19,19 @@ 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;
}

View File

@ -173,7 +173,7 @@ class OutStream {
return *this;
}
constexpr OutStream &operator<<(StringViewCR v) noexcept {
constexpr OutStream &operator<<(const char *v) noexcept {
if (m_msg.msg.len()) {
m_msg.msg += m_delimiter;
}
@ -181,10 +181,6 @@ 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());

View File

@ -107,12 +107,12 @@ class UUID {
static ox::Result<UUID> generate() noexcept;
[[nodiscard]]
constexpr ox::Array<uint8_t, 16> const&value() const noexcept {
constexpr auto const&value() const noexcept {
return m_value;
}
[[nodiscard]]
constexpr bool isNull() const noexcept {
constexpr auto 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;

View File

@ -422,13 +422,11 @@ 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];
}

View File

@ -4,8 +4,6 @@
#pragma once
#include <ox/std/types.hpp>
namespace nostalgia::core {
struct InitParams {

View File

@ -12,7 +12,7 @@ TileSheetClipboard::Pixel::Pixel(uint16_t pColorIdx, ox::Point pPt) noexcept {
}
void TileSheetClipboard::addPixel(ox::Point const&pt, uint16_t colorIdx) noexcept {
void TileSheetClipboard::addPixel(const ox::Point &pt, uint16_t colorIdx) noexcept {
m_pixels.emplace_back(colorIdx, pt);
}
@ -25,20 +25,18 @@ CutPasteCommand::CutPasteCommand(
CommandId commandId,
TileSheet &img,
TileSheet::SubSheetIdx subSheetIdx,
ox::Point const&dstStart,
ox::Point dstEnd,
TileSheetClipboard const&cb) noexcept:
const ox::Point &dstStart,
const ox::Point &dstEnd,
const TileSheetClipboard &cb) noexcept:
m_commandId(commandId),
m_img(img),
m_subSheetIdx(std::move(subSheetIdx)) {
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;
const auto &subsheet = getSubSheet(m_img, m_subSheetIdx);
for (const auto &p : cb.pixels()) {
const auto dstPt = p.pt + dstStart;
if (dstPt.x <= dstEnd.x && dstPt.y <= dstEnd.y) {
auto const idx = core::idx(ss, dstPt);
m_changes.emplace_back(static_cast<uint32_t>(idx), p.colorIdx, getPixel(ss, m_img.bpp, idx));
const auto idx = core::idx(subsheet, dstPt);
m_changes.emplace_back(static_cast<uint32_t>(idx), p.colorIdx, getPixel(subsheet, m_img.bpp, idx));
}
}
}

View File

@ -68,7 +68,7 @@ class CutPasteCommand: public TileSheetCommand {
TileSheet &img,
TileSheet::SubSheetIdx subSheetIdx,
ox::Point const&dstStart,
ox::Point dstEnd,
ox::Point const&dstEnd,
TileSheetClipboard const&cb) noexcept;
ox::Error redo() noexcept final;

View File

@ -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 = ox::min<int32_t>(ss.columns, sz.width) * TileWidth;
auto const h = ox::min<int32_t>(ss.rows, sz.height) * TileHeight;
auto const w = ss.columns * TileWidth;
auto const h = ss.rows * TileHeight;
for (auto x = 0; x < w; ++x) {
for (auto y = 0; y < h; ++y) {
auto const palIdx = getPixel(ss, pBpp, {x, y});

View File

@ -7,8 +7,6 @@
#include <ox/claw/claw.hpp>
#include <ox/fs/fs.hpp>
#include "validation.hpp"
namespace keel {
constexpr auto K1HdrSz = 40;
@ -28,10 +26,7 @@ ox::Result<T> readAsset(ox::BufferView buff) noexcept {
if (!err) {
offset = K1HdrSz; // the size of K1 headers
}
auto out = ox::readClaw<T>(buff + offset);
oxReturnError(out);
oxReturnError(ensureValid(out.value));
return out;
return ox::readClaw<T>(buff + offset);
}
ox::Result<ox::ModelObject> readAsset(ox::TypeStore &ts, ox::BufferView buff) noexcept;

View File

@ -14,6 +14,8 @@
#include <ox/std/hashmap.hpp>
#include <ox/std/utility.hpp>
#include "validation.hpp"
namespace keel {
class AssetManager;
@ -188,7 +190,7 @@ class AssetManager {
private:
class AssetTypeManagerBase: public ox::SignalHandler {
public:
~AssetTypeManagerBase() override = default;
virtual ~AssetTypeManagerBase() = default;
virtual void gc() noexcept = 0;
};
@ -215,6 +217,7 @@ 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 {

View File

@ -7,6 +7,8 @@
#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"
@ -117,6 +119,7 @@ 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)};

View File

@ -2,6 +2,8 @@
* Copyright 2016 - 2024 Gary Talent (gary@drinkingtea.net). All rights reserved.
*/
#include <ox/claw/read.hpp>
#include <keel/media.hpp>
#include <keel/typeconv.hpp>

View File

@ -5,7 +5,6 @@
#pragma once
#include <ox/std/defines.hpp>
#include <ox/std/string.hpp>
namespace studio {