diff --git a/xybrid/nodelib/instrumentcore.h b/xybrid/nodelib/instrumentcore.h index d6b0aeb..bc04779 100644 --- a/xybrid/nodelib/instrumentcore.h +++ b/xybrid/nodelib/instrumentcore.h @@ -8,6 +8,8 @@ #include "data/node.h" +#include "util/mem.h" + namespace Xybrid::Data { class CommandPort; class AudioPort; @@ -23,9 +25,6 @@ namespace Xybrid::NodeLib { * Not mandatory by any means, but handles all the "standard" commands for you. */ class InstrumentCore { - double time; - double smpTime; - public: class Note { friend class InstrumentCore; @@ -50,6 +49,8 @@ namespace Xybrid::NodeLib { std::array ptr; }; + template inline T& scratchAs() { return *(reinterpret_cast(reinterpret_cast(&scratch))); } + Note() = default; Note(InstrumentCore*, uint16_t id); @@ -79,12 +80,19 @@ namespace Xybrid::NodeLib { void startTick(Note&, double tickTime); void process(Note&, double smpTime); }; + private: + // + + double time; + double smpTime; + + public: double volume = 1.0; double pan = 0.0; - std::unordered_map activeNotes; - std::unordered_multimap activeTweens; + std::pmr::unordered_map activeNotes = {16, Util::ralloc}; + std::pmr::unordered_multimap activeTweens = {16, Util::ralloc}; std::function paramFilter; std::unordered_map> globalParam; diff --git a/xybrid/util/mem.cpp b/xybrid/util/mem.cpp new file mode 100644 index 0000000..5608f76 --- /dev/null +++ b/xybrid/util/mem.cpp @@ -0,0 +1,15 @@ +#include "mem.h" + +using namespace Xybrid::Util; + +std::pmr::synchronized_pool_resource Xybrid::Util::rpool; // instantiate +decltype(Xybrid::Util::ralloc) Xybrid::Util::ralloc(&rpool); + +namespace { + static bool _____ = [] { // static init hackery to force pre-reservation of a certain chunk size + const constexpr size_t rsize = 1024*1024*128; + auto r = rpool.allocate(rsize); + rpool.deallocate(r, rsize); + return false; + }(); +} diff --git a/xybrid/util/mem.h b/xybrid/util/mem.h new file mode 100644 index 0000000..0581dc1 --- /dev/null +++ b/xybrid/util/mem.h @@ -0,0 +1,48 @@ +#pragma once + +#include +#include +#include +#include +#include + +namespace Xybrid::Util { + extern std::pmr::synchronized_pool_resource rpool; + extern std::pmr::polymorphic_allocator ralloc; + + template + class ResourcePool { + typedef char slot[sizeof(T)]; + std::list pages; + + std::deque avail; + std::pmr::unordered_set used = {rpool}; + + void newPage() { + auto p = pages.emplace_back(); + for (size_t i = 0; i < PSIZE; i++) avail.push_back(&p[i]); + //avail.res + } + + public: + typedef T type; + static const constexpr size_t pageSize = PSIZE; + + template + T* getNew(Arg... args) { + if (avail.empty()) newPage(); + T* n = avail.pop_back(); + new (n) T(args...); + used.insert(n); + return n; + } + + void del(T* n) { + if (!used.contains(n)) return; // not mine + n->~T(); // destroy object + used.erase(n); + avail.push_back(n); + } + + }; +}