Compare commits

..

13 Commits

25 changed files with 173 additions and 155 deletions

View File

@ -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"
]
}
]
}

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

@ -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```:

View File

@ -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);
}

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 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>

View File

@ -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) {

View File

@ -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) {

View File

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

View File

@ -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
}
}

View File

@ -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);
}

View File

@ -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

View File

@ -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));
}
}
}
}

View File

@ -103,10 +103,12 @@ 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};
}
@ -229,10 +231,12 @@ 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,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;
}

View File

@ -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());

View File

@ -107,12 +107,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;

View File

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

View File

@ -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;
};
}
}

View File

@ -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));
}
}
}

View File

@ -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 {
};
}
}

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 = 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});

View File

@ -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;

View File

@ -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 {

View File

@ -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)};

View File

@ -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>

View File

@ -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;
}
}