diff --git a/src/internal/mana_lib.hpp b/src/internal/mana_lib.hpp index a5d8dee..7a81e35 100644 --- a/src/internal/mana_lib.hpp +++ b/src/internal/mana_lib.hpp @@ -4,6 +4,7 @@ #include "mana_arena.h" #include "mana_c_api.h" #include +#include #include #include #include @@ -157,6 +158,199 @@ class IManaSink IManaSink &operator=(const IManaSink &) = delete; }; +#if 0 +class ManaSinkProxy: public IManaSink +{ + public: + explicit ManaSinkProxy(IManaSink *sink) + : sink_(sink) + { + } + + void init(int plugin_argc, const char **plugin_argv) override + { + pre_init(plugin_argc, plugin_argv); + sink_->init(plugin_argc, plugin_argv); + post_init(plugin_argc, plugin_argv); + } + + void shutdown() override + { + pre_shutdown(); + sink_->shutdown(); + post_shutdown(); + } + + void begin_run(const char *descriptor_json) override + { + pre_begin_run(descriptor_json); + sink_->begin_run(descriptor_json); + post_begin_run(descriptor_json); + } + + void end_run(const char *descriptor_json) override + { + pre_shutdown(); + sink_->end_run(descriptor_json); + post_shutdown(); + } + + void process_event(uint16_t eventIndex, mana_offset_array_t *arrays, size_t arrayCount, + size_t totalBytes) override + { + pre_process_event(eventIndex, arrays, arrayCount, totalBytes); + sink_->process_event(eventIndex, arrays, arrayCount, totalBytes); + post_process_event(eventIndex, arrays, arrayCount, totalBytes); + } + + void process_system_event(const uint32_t *data, size_t size) override + { + pre_process_system_event(data, size); + sink_->process_system_event(data, size); + post_process_system_event(data, size); + } + + IManaSink *sink() { return sink_; } + + protected: + virtual void pre_init(int plugin_argc, const char **plugin_argv) + { + (void)plugin_argc; + (void)plugin_argv; + } + virtual void post_init(int plugin_argc, const char **plugin_argv) + { + (void)plugin_argc; + (void)plugin_argv; + } + virtual void pre_shutdown() {} + virtual void post_shutdown() {} + virtual void pre_begin_run(const char *descriptor_json) { (void)descriptor_json; } + virtual void post_begin_run(const char *descriptor_json) { (void)descriptor_json; } + virtual void pre_process_event(uint16_t eventIndex, mana_offset_array_t *arrays, + size_t arrayCount, size_t totalBytes) + { + (void)eventIndex; + (void)arrays; + (void)arrayCount; + (void)totalBytes; + } + virtual void post_process_event(uint16_t eventIndex, mana_offset_array_t *arrays, + size_t arrayCount, size_t totalBytes) + { + (void)eventIndex; + (void)arrays; + (void)arrayCount; + (void)totalBytes; + } + virtual void pre_process_system_event(const uint32_t *data, size_t size) + { + (void)data; + (void)size; + } + virtual void post_process_system_event(const uint32_t *data, size_t size) + { + (void)data; + (void)size; + } + + private: + IManaSink *sink_; +}; +#endif + +class ManaSinkPerfProxy: public IManaSink +{ + public: + struct Perf + { + using clock = std::chrono::high_resolution_clock; + using time_point = std::chrono::time_point; + using duration = std::chrono::microseconds; + template static duration duration_cast(const T &dt) + { + return std::chrono::duration_cast(dt); + } + std::vector eventHits; + std::vector eventBytes; + duration dt_init; + duration dt_shutdown; + duration dt_beginRun; + duration dt_endRun; + std::vector dt_processEvent; + time_point t_beginRun; + time_point t_endRun; + }; + + explicit ManaSinkPerfProxy(IManaSink *sink) + : sink_(sink) + { + } + + const Perf &perf() const { return perf_; } + + void init(int plugin_argc, const char **plugin_argv) override + { + auto t = Perf::clock::now(); + sink_->init(plugin_argc, plugin_argv); + perf_.dt_init = Perf::duration_cast(Perf::clock::now() - t); + } + + void shutdown() override + { + auto t = Perf::clock::now(); + sink_->shutdown(); + perf_.dt_shutdown = Perf::duration_cast(Perf::clock::now() - t); + } + + void begin_run(const char *descriptor_json) override + { + perf_.eventHits.clear(); + perf_.eventBytes.clear(); + perf_.dt_beginRun = perf_.dt_endRun = {}; + perf_.dt_processEvent.clear(); + perf_.t_endRun = {}; + + perf_.t_beginRun = Perf::clock::now(); + sink_->begin_run(descriptor_json); + perf_.dt_beginRun = Perf::duration_cast(Perf::clock::now() - perf_.t_beginRun); + } + + void end_run(const char *descriptor_json) override + { + auto t = Perf::clock::now(); + sink_->end_run(descriptor_json); + perf_.t_endRun = Perf::clock::now(); + perf_.dt_endRun = Perf::duration_cast(perf_.t_endRun - t); + } + + void process_event(uint16_t eventIndex, mana_offset_array_t *arrays, size_t arrayCount, + size_t totalBytes) override + { + size_t size = eventIndex + 1; + perf_.eventHits.resize(std::max(perf_.eventHits.size(), size)); + perf_.eventBytes.resize(std::max(perf_.eventBytes.size(), size)); + perf_.dt_processEvent.resize(std::max(perf_.dt_processEvent.size(), size)); + + auto t = Perf::clock::now(); + sink_->process_event(eventIndex, arrays, arrayCount, totalBytes); + auto dt = Perf::duration_cast(Perf::clock::now() - t); + + perf_.eventHits[eventIndex]++; + perf_.eventBytes[eventIndex] += totalBytes; + perf_.dt_processEvent[eventIndex] += dt; + } + + void process_system_event(const uint32_t *data, size_t size) override + { + sink_->process_system_event(data, size); + } + + private: + IManaSink *sink_; + Perf perf_; +}; + // wraps a mana_api.h mana_sink_plugin_t instance struct ManaCSink: public IManaSink {