mirror of
https://github.com/halleysfifthinc/AVCLAN-Mockingboard.git
synced 2026-10-21 01:30:45 +00:00
Redesign (simplify) top-level avclan interface to use expected/nullable unique_ptr
- Peripheral::read/send now return `expected<unique_ptr<Frame>, Error>` for a unified success/error interface. - Peripheral::route returns `expected<unique_ptr<Frame>, Error>` to distinguish intent: (intentional) non-response vs unable to respond - Other functions with optional message semantics (handle,poll,react) return a unique_ptr whose ownership-state indicates response intent (i.e. send new message) Bundled necessary changes: - Switch Frame allocation from global to local (enabled via member function new/delete) - Add new header-library tl::expected to shim avr-libstdcpp Unrelated: Defensive `continue` added after `route`, to reduce Bus activity check latency Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+17
-3
@@ -31,11 +31,14 @@
|
||||
|
||||
#include <concepts>
|
||||
#include <cstdio>
|
||||
#include <memory>
|
||||
#include <new>
|
||||
|
||||
#include "avclan.h"
|
||||
#include "bus.hpp"
|
||||
#include "frame.hpp"
|
||||
#include "hal/phy.h"
|
||||
#include "stdshim.hpp"
|
||||
|
||||
namespace {
|
||||
using Read = avclan::detail::Error::Read;
|
||||
@@ -191,7 +194,8 @@ void Bus::mute(bool mute) {
|
||||
muted_ = mute; // Only update muted_ *AFTER* hardware has finished muting
|
||||
};
|
||||
|
||||
auto Bus::read(uint16_t address, Frame *in, Frame::Print print) -> Read {
|
||||
auto Bus::read(uint16_t address, Frame::Print print)
|
||||
-> expected<std::unique_ptr<Frame>, Error::Read> {
|
||||
struct errtype {
|
||||
Read errno;
|
||||
uint16_t val;
|
||||
@@ -199,6 +203,12 @@ auto Bus::read(uint16_t address, Frame *in, Frame::Print print) -> Read {
|
||||
|
||||
using enum Read;
|
||||
|
||||
std::unique_ptr<Frame> in(new (std::nothrow) Frame);
|
||||
if (!in) {
|
||||
err.errno = POOL_EMPTY;
|
||||
goto handle_err;
|
||||
}
|
||||
|
||||
{ // bound handle lifetime
|
||||
auto handle = get();
|
||||
|
||||
@@ -277,6 +287,7 @@ auto Bus::read(uint16_t address, Frame *in, Frame::Print print) -> Read {
|
||||
handle_err:;
|
||||
fputs("ERR(read): ", stdout);
|
||||
switch (err.errno) {
|
||||
case POOL_EMPTY: puts("failed Frame alloc"); break;
|
||||
case BAD_STARTBIT: fputs("bad start bit (other)", stdout); break;
|
||||
case STARTBIT_TOO_SHORT: fputs("bad start bit (short)", stdout); break;
|
||||
case STARTBIT_TOO_LONG: fputs("bad start bit (long)", stdout); break;
|
||||
@@ -297,7 +308,7 @@ auto Bus::read(uint16_t address, Frame *in, Frame::Print print) -> Read {
|
||||
printf("; read 0x%02X", err.val);
|
||||
}
|
||||
}
|
||||
putchar('\n');
|
||||
puts(":");
|
||||
}
|
||||
|
||||
// Only print if some data has been correctly received
|
||||
@@ -307,7 +318,10 @@ auto Bus::read(uint16_t address, Frame *in, Frame::Print print) -> Read {
|
||||
in->print(print);
|
||||
}
|
||||
|
||||
return err.errno;
|
||||
if (err.errno != Read{0})
|
||||
return unexpected(err.errno);
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
auto Bus::send(const Frame *out, Frame::Print print) -> Send {
|
||||
|
||||
Reference in New Issue
Block a user