diff --git a/src/backend/CMakeLists.txt b/src/backend/CMakeLists.txt index 069eba7..1376449 100644 --- a/src/backend/CMakeLists.txt +++ b/src/backend/CMakeLists.txt @@ -35,6 +35,8 @@ setup_project_options( INTERFACE_TARGET config_target ) +add_definitions(-D_WIN32_WINNT=0x0A00 -DWIN32_LEAN_AND_MEAN -DNOMINMAX) + # NOTE: 硬编码构建目录可能会降低灵活性。 # 通常,更推荐的做法是让用户在调用 CMake 时通过 -B 参数来指定构建目录, # 以支持灵活的 out-of-source builds。 @@ -50,7 +52,7 @@ find_package(gRPC CONFIG REQUIRED) find_package(Protobuf CONFIG REQUIRED) find_package(ZeroMQ CONFIG REQUIRED) find_package(spdlog CONFIG REQUIRED) -find_package(Boost CONFIG REQUIRED COMPONENTS system interprocess lockfree asio process) +find_package(Boost CONFIG REQUIRED COMPONENTS system interprocess lockfree asio process uuid circular_buffer thread) # --- Protocol Buffers 编译 (Protocol Buffers Compilation) --- # 使用自定义函数编译 .proto 文件,自动生成 C++ 源代码和 gRPC 服务代码。 diff --git a/src/backend/src/engine/CMakeLists.txt b/src/backend/src/engine/CMakeLists.txt index 5222a98..12826a2 100644 --- a/src/backend/src/engine/CMakeLists.txt +++ b/src/backend/src/engine/CMakeLists.txt @@ -30,14 +30,9 @@ target_link_libraries(${PROJECT_NAME} PRIVATE gRPC::grpc++ protobuf::libprotobuf libzmq - Boost::process - Boost::interprocess - Boost::system - Boost::lockfree - Boost::asio AlichoProto AlichoMisc ws2_32 + Boost::process ) -target_compile_definitions(${PROJECT_NAME} PRIVATE _WIN32_WINNT=0x0A00 WIN32_LEAN_AND_MEAN) target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src) diff --git a/src/backend/src/engine/src/main.cpp b/src/backend/src/engine/src/main.cpp index 8948958..69c63b3 100644 --- a/src/backend/src/engine/src/main.cpp +++ b/src/backend/src/engine/src/main.cpp @@ -1,21 +1,29 @@ +#include "ipc/shm_manager.h" #include "plugin_manage/plugin_host_manager.h" -#include "rpc/rpc_session.h" #include +#include "ipc/ipc_node.h" +#include "rpc/engine_rpc.h" + + int main(int argc, char *argv[]) { - std::filesystem::path path(R"(D:\Projects\Alicho\src\backend\src\vst2_host\test\4Front Piano x64.dll)"); - plugin_host_manager::get_instance().load_plugin(path); + shm_manager::get_instance().init(true); + engine_ipc_node node; + + // std::filesystem::path path(R"(D:\Projects\Alicho\src\backend\src\vst2_host\test\4Front Piano x64.dll)"); + // plugin_host_manager::get_instance().load_plugin(path); uint32_t times = 0; while (true) { // 模拟主循环 std::this_thread::sleep_for(std::chrono::milliseconds(100)); - if (++times > 10) { - break; // 运行10次后退出 - } + node.process_rpc(); + // if (++times > 10) { + // break; // 运行10次后退出 + // } } return 0; diff --git a/src/backend/src/engine/src/plugin_manage/plugin_host_manager.cpp b/src/backend/src/engine/src/plugin_manage/plugin_host_manager.cpp index 721c893..5338faf 100644 --- a/src/backend/src/engine/src/plugin_manage/plugin_host_manager.cpp +++ b/src/backend/src/engine/src/plugin_manage/plugin_host_manager.cpp @@ -1,5 +1,8 @@ #include "plugin_host_manager.h" +#include +#include + #include "plugin_instance.h" plugin_host_manager::~plugin_host_manager() { diff --git a/src/backend/src/engine/src/plugin_manage/plugin_host_manager.h b/src/backend/src/engine/src/plugin_manage/plugin_host_manager.h index 6eb05d5..c02e5a5 100644 --- a/src/backend/src/engine/src/plugin_manage/plugin_host_manager.h +++ b/src/backend/src/engine/src/plugin_manage/plugin_host_manager.h @@ -4,7 +4,6 @@ #include "lazy_singleton.h" #include "plugin_instance.h" -#include "rpc/rpc_session.h" class plugin_host_manager : public lazy_singleton { public: @@ -33,5 +32,4 @@ private: std::unordered_map> plugin_instances_; std::atomic_uint32_t plugin_id_ = 1; boost::asio::io_context io_context_; - rpc_server rpc_server_{ io_context_ }; }; diff --git a/src/backend/src/engine/src/rpc/engine_rpc.cpp b/src/backend/src/engine/src/rpc/engine_rpc.cpp index ddf2a9a..6df69b9 100644 --- a/src/backend/src/engine/src/rpc/engine_rpc.cpp +++ b/src/backend/src/engine/src/rpc/engine_rpc.cpp @@ -1,10 +1,5 @@ #include "engine_rpc.h" -void __rpc_handler_func_PROCESS_DONE(uint64_t seq_id, const rpc::process_done& body) { - +namespace engine_rpc { + RPC_REG(LOG, log_impl) } - -void __rpc_handler_func_REGISTER_HOST(uint64_t seq_id, const rpc::register_host& body) { - -} - diff --git a/src/backend/src/engine/src/rpc/engine_rpc.h b/src/backend/src/engine/src/rpc/engine_rpc.h index 7e9dda3..d8562aa 100644 --- a/src/backend/src/engine/src/rpc/engine_rpc.h +++ b/src/backend/src/engine/src/rpc/engine_rpc.h @@ -1,8 +1,20 @@ #pragma once -#include "rpc/common.h" #include "rpc/rpc_type.h" #include "rpc/rpc_manager.h" -REGISTER_RPC_HANDLER(LOG, rpc::log) -REGISTER_RPC_HANDLER(REGISTER_HOST, rpc::register_host) -REGISTER_RPC_HANDLER(PROCESS_DONE, rpc::process_done) +namespace engine_rpc { + struct log_impl : log { + void process() { + const auto str = get_str(); + spdlog::log(level, "[Engine] {}", str->c_str()); + destory_str(); + } + }; + + struct test { + uint32_t id; + void process() { + spdlog::info("收到测试消息,ID: {}", id); + } + }; +} diff --git a/src/backend/src/misc/CMakeLists.txt b/src/backend/src/misc/CMakeLists.txt index ed4bf91..75f8f8f 100644 --- a/src/backend/src/misc/CMakeLists.txt +++ b/src/backend/src/misc/CMakeLists.txt @@ -33,3 +33,10 @@ target_link_libraries(${PROJECT_NAME} PRIVATE config_target) target_link_libraries(${PROJECT_NAME} PUBLIC spdlog::spdlog) target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src) add_os_definitions(${PROJECT_NAME}) +target_link_libraries(${PROJECT_NAME} PUBLIC + Boost::circular_buffer + Boost::uuid + Boost::thread + Boost::interprocess + Boost::lockfree +) diff --git a/src/backend/src/misc/src/ipc/ipc_node.cpp b/src/backend/src/misc/src/ipc/ipc_node.cpp new file mode 100644 index 0000000..5a7a0fb --- /dev/null +++ b/src/backend/src/misc/src/ipc/ipc_node.cpp @@ -0,0 +1 @@ +#include "ipc_node.h" diff --git a/src/backend/src/misc/src/ipc/ipc_node.h b/src/backend/src/misc/src/ipc/ipc_node.h new file mode 100644 index 0000000..edd976b --- /dev/null +++ b/src/backend/src/misc/src/ipc/ipc_node.h @@ -0,0 +1,108 @@ +#pragma once +#include +#include +#include + +#include "shm_manager.h" +#include "rpc/rpc_manager.h" + +namespace bi = boost::interprocess; +namespace bc = boost::container; + +class ipc_node { +public: + friend class engine_ipc_node; + friend class plugin_ipc_node; + + using queue_t = boost::lockfree::spsc_queue>; + + ~ipc_node() { + close_queue(); + } + + void create_queue(const std::string& in_name) { + rpc_queue = shm_manager::msg_construct(in_name.c_str()); + if (!rpc_queue) { + throw std::runtime_error("无法创建IPC队列"); + } + is_queue_owner = true; + } + void open_queue(const std::string& in_name) { + auto [queue_ptr, size] = shm_manager::msg_find(in_name.c_str()); + if (!queue_ptr) { + throw std::runtime_error("无法打开IPC队列"); + } + rpc_queue = queue_ptr; + is_queue_owner = false; + } + void close_queue() { + if (!rpc_queue) + return; + if (is_queue_owner) { + shm_manager::msg_destroy_ptr(rpc_queue); + } + rpc_queue = nullptr; + is_queue_owner = false; + } + + template + void call_rpc(const Msg& in_msg) { + auto message_id = Msg::rpc_id; + + auto data_ptr = reinterpret_cast(std::addressof(in_msg)); + auto data_size = sizeof(Msg); + + rpc_message_t msg; + msg.message_id = message_id; + msg.data.insert(msg.data.end(), data_ptr, data_ptr + data_size); + + rpc_queue->push(std::move(msg)); + } + + void process_rpc() { + rpc_message_t msg; + while (rpc_queue->pop(msg)) { + // 处理消息 + rpc_message_handler::get_instance().handle_message(msg); + } + } +protected: + queue_t* rpc_queue; + bool is_queue_owner = false; +private: + ipc_node(): rpc_queue(nullptr) { + } +}; + +class engine_ipc_node { +public: + engine_ipc_node() { + engine_queue.create_queue("engine_queue"); + } + + void process_rpc() { + engine_queue.process_rpc(); + } +private: + ipc_node engine_queue; +}; + +class plugin_ipc_node { +public: + plugin_ipc_node(const std::string& in_queue_name) { + engine_queue.open_queue("engine_queue"); + plugin_queue.create_queue(in_queue_name); + } + + template + void call_rpc(const Msg& in_msg) { + engine_queue.call_rpc(in_msg); + } + + void process_rpc() { + plugin_queue.process_rpc(); + } +private: + ipc_node engine_queue; + ipc_node plugin_queue; +}; diff --git a/src/backend/src/misc/src/ipc/plugin_sandbox_data.cpp b/src/backend/src/misc/src/ipc/plugin_sandbox_data.cpp new file mode 100644 index 0000000..8bc40f3 --- /dev/null +++ b/src/backend/src/misc/src/ipc/plugin_sandbox_data.cpp @@ -0,0 +1 @@ +#include "plugin_sandbox_data.h" diff --git a/src/backend/src/misc/src/ipc/plugin_sandbox_data.h b/src/backend/src/misc/src/ipc/plugin_sandbox_data.h new file mode 100644 index 0000000..b87c8b2 --- /dev/null +++ b/src/backend/src/misc/src/ipc/plugin_sandbox_data.h @@ -0,0 +1,9 @@ +#pragma once +#include + +class plugin_sandbox_data { +public: + boost::atomic ready{ false }; + boost::atomic frame_counter{0}; + char name[256]; +}; diff --git a/src/backend/src/misc/src/ipc/shm_audio_buffer.cpp b/src/backend/src/misc/src/ipc/shm_audio_buffer.cpp new file mode 100644 index 0000000..7984203 --- /dev/null +++ b/src/backend/src/misc/src/ipc/shm_audio_buffer.cpp @@ -0,0 +1 @@ +#include "shm_audio_buffer.h" diff --git a/src/backend/src/misc/src/ipc/shm_audio_buffer.h b/src/backend/src/misc/src/ipc/shm_audio_buffer.h new file mode 100644 index 0000000..1371c9d --- /dev/null +++ b/src/backend/src/misc/src/ipc/shm_audio_buffer.h @@ -0,0 +1,158 @@ +// shm_audio_buffer.h +#pragma once +#include +#include +#include +#include +#include +#include +#include "shm_manager.h" + +namespace bi = boost::interprocess; +namespace bc = boost::container; + +class shm_audio_buffer { +public: + using segment_manager = bi::managed_shared_memory::segment_manager; + using mutex_type = bi::interprocess_mutex; + using scoped_lock = bi::scoped_lock; + + using buffer_allocator_t = bi::allocator; + using channel_vec_t = bc::vector; + using channel_allocator_t = bi::allocator; + using channel_container_t = bc::vector; + + // 构造函数显式接收分配器 + explicit shm_audio_buffer() + : buffers{shm_manager::ab_mgr()} + { + auto* shm = shm_manager::get_instance().get_audio_buffer_shm(); + if (!shm) { + throw std::runtime_error("Shared memory segment not initialized"); + } + } + + // 设置通道数 + void channels(size_t in_ch) { + if (in_ch == 0) { + throw std::invalid_argument("Channel count must be greater than 0"); + } + + auto alloc = shm_manager::ab_mgr(); + buffers.clear(); + buffers.reserve(in_ch); + + for (size_t i = 0; i < in_ch; ++i) { + buffers.emplace_back(alloc); + } + } + + // 获取通道数 + [[nodiscard]] size_t channels() const { + return buffers.size(); + } + + // 设置块大小 + void block_size(size_t in_size) { + if (buffers.empty()) { + throw std::logic_error("Channels must be set before block size"); + } + + for (auto& buf : buffers) { + buf.resize(in_size, 0.0f); // 初始化为0 + } + } + + // 获取块大小 + [[nodiscard]] size_t block_size() const { + if (buffers.empty()) return 0; + return buffers[0].size(); + } + + // 获取指定通道的数据指针 + [[nodiscard]] float* data(size_t ch) { + if (ch >= buffers.size()) { + throw std::out_of_range("Channel index out of range"); + } + return buffers[ch].data(); + } + + [[nodiscard]] const float* data(size_t ch) const { + if (ch >= buffers.size()) { + throw std::out_of_range("Channel index out of range"); + } + return buffers[ch].data(); + } + + // 获取所有通道的指针数组 + [[nodiscard]] bc::vector headers() { + bc::vector ptrs; + ptrs.reserve(buffers.size()); + + for (auto& buf : buffers) { + ptrs.push_back(buf.data()); + } + return ptrs; + } + + [[nodiscard]] bc::vector headers() const { + bc::vector ptrs; + ptrs.reserve(buffers.size()); + + for (const auto& buf : buffers) { + ptrs.push_back(buf.data()); + } + return ptrs; + } + + // 获取指定通道的向量引用 + [[nodiscard]] channel_vec_t& block(size_t ch) { + if (ch >= buffers.size()) { + throw std::out_of_range("Channel index out of range"); + } + return buffers[ch]; + } + + [[nodiscard]] const channel_vec_t& block(size_t ch) const { + if (ch >= buffers.size()) { + throw std::out_of_range("Channel index out of range"); + } + return buffers[ch]; + } + + // 清空所有缓冲区数据 + void clear() { + for (auto& buf : buffers) { + std::ranges::fill(buf, 0.0f); + } + } + + // 复制数据到缓冲区 + void copy_from(size_t ch, const float* src, size_t samples) { + if (ch >= buffers.size()) { + throw std::out_of_range("Channel index out of range"); + } + + if (samples > buffers[ch].size()) { + throw std::out_of_range("Sample count exceeds buffer size"); + } + + std::copy_n(src, samples, buffers[ch].begin()); + } + + // 复制数据从缓冲区 + void copy_to(size_t ch, float* dst, size_t samples) const { + if (ch >= buffers.size()) { + throw std::out_of_range("Channel index out of range"); + } + + if (samples > buffers[ch].size()) { + throw std::out_of_range("Sample count exceeds buffer size"); + } + + std::copy_n(buffers[ch].begin(), samples, dst); + } + +private: + channel_container_t buffers; +}; \ No newline at end of file diff --git a/src/backend/src/misc/src/ipc/shm_manager.cpp b/src/backend/src/misc/src/ipc/shm_manager.cpp new file mode 100644 index 0000000..1fc955f --- /dev/null +++ b/src/backend/src/misc/src/ipc/shm_manager.cpp @@ -0,0 +1,15 @@ +#include "shm_manager.h" + +#include "shm_audio_buffer.h" + +bool shm_manager::allocate_shm() { + try { + message_shm_block = create_shm_block(message_shm_name, message_shm_size); + audio_buffer_shm_block = create_shm_block(audio_buffer_shm_name, audio_buffer_shm_size); + str_shm_block = create_shm_block(string_shm_name, str_shm_size); + return true; + } catch (const bi::interprocess_exception& e) { + spdlog::error("无法创建共享内存:{}", e.what()); + return false; + } +} diff --git a/src/backend/src/misc/src/ipc/shm_manager.h b/src/backend/src/misc/src/ipc/shm_manager.h new file mode 100644 index 0000000..be52204 --- /dev/null +++ b/src/backend/src/misc/src/ipc/shm_manager.h @@ -0,0 +1,127 @@ +#pragma once +#include +#include +#include +#include +#include + +#include "lazy_singleton.h" +#include "rpc/common.h" + +class shm_audio_buffer; + +/** + * 共享内存管理类,管理共享内存的创建和销毁 + * 会在内存已满时自动创建新的共享内存段 + * 同时管理Plugin Sandbox的插槽和AudioBuffer + */ +class shm_manager : public lazy_singleton { +public: + using shm_ptr = std::shared_ptr; + + const char* message_shm_name = "alicho_message_ipc_memory"; + const char* audio_buffer_shm_name = "alicho_audio_buffer_ipc_memory"; + const char* string_shm_name = "alicho_string_memory"; + const size_t message_shm_size = 1024 * 1024 * 256; // 256MB + const size_t audio_buffer_shm_size = 1024 * 1024 * 512; // 512MB + const size_t str_shm_size = 1024 * 1024 * 256; // 256MB + + void init(bool in_is_engine = false) { + is_engine = in_is_engine; + allocate_shm(); + } + ~shm_manager() { + if (is_engine) { + bi::shared_memory_object::remove(message_shm_name); + bi::shared_memory_object::remove(audio_buffer_shm_name); + bi::shared_memory_object::remove(string_shm_name); + } + } + + template + static auto msg_mgr() { + return T{ get_instance().message_shm_block->get_segment_manager() }; + } + template + static auto ab_mgr() { + return T{ get_instance().audio_buffer_shm_block->get_segment_manager() }; + } + template + static auto msg_construct(const char* name) { + return get_instance().message_shm_block->construct(name)(); + } + template + static auto ab_construct(const char* name) { + return get_instance().audio_buffer_shm_block->construct(name)(); + } + template + static auto msg_find(const char* name) { + return get_instance().message_shm_block->find(name); + } + template + static auto ab_find(const char* name) { + return get_instance().audio_buffer_shm_block->find(name); + } + template + static auto msg_find_or_construct(const char* name) { + return get_instance().message_shm_block->find_or_construct(name)(); + } + template + static auto ab_find_or_construct(const char* name) { + return get_instance().audio_buffer_shm_block->find_or_construct(name)(); + } + template + static void msg_destroy(const char* name) { + get_instance().message_shm_block->destroy(name); + } + template + static void ab_destroy(const char* name) { + get_instance().audio_buffer_shm_block->destroy(name); + } + template + static void msg_destroy_ptr(const T* ptr) { + get_instance().message_shm_block->destroy_ptr(ptr); + } + template + static void ab_destroy_ptr(const T* ptr) { + get_instance().audio_buffer_shm_block->destroy_ptr(ptr); + } + + shm_string* create_str(const std::string& id, const std::string& str) { + const auto ptr = str_shm_block->find_or_construct(id.c_str())(str.c_str(), + char_allocator{ str_shm_block->get_segment_manager() }); + return ptr; + } + shm_string* create_str(const std::string& id) { + return create_str(id, ""); + } + shm_string* find_str(const std::string& id) { + auto [ptr, size] = str_shm_block->find(id.c_str()); + return ptr; + } + void destroy_str(const std::string& id) { + str_shm_block->destroy(id.c_str()); + } + void destroy_str(shm_string* ptr) { + str_shm_block->destroy_ptr(ptr); + } + + auto* get_message_shm() { return message_shm_block.get(); } + auto* get_audio_buffer_shm() { return audio_buffer_shm_block.get(); } +private: + // 分配新的共享内存段 + bool allocate_shm(); + + auto create_shm_block(const std::string& in_name, size_t in_size) { + if (is_engine) { + bi::shared_memory_object::remove(in_name.c_str()); + return std::make_shared(bi::open_or_create, in_name.c_str(), in_size); + } + return std::make_shared(bi::open_only, in_name.c_str()); + } + + bool is_engine = false; + shm_ptr message_shm_block; + shm_ptr audio_buffer_shm_block; + shm_ptr str_shm_block; +}; diff --git a/src/backend/src/misc/src/rpc/common.h b/src/backend/src/misc/src/rpc/common.h index 0504634..e301d49 100644 --- a/src/backend/src/misc/src/rpc/common.h +++ b/src/backend/src/misc/src/rpc/common.h @@ -1,7 +1,12 @@ #pragma once #include +#include #include +#include + +namespace bi = boost::interprocess; +namespace bc = boost::container; constexpr size_t AUDIO_BLOCK_SIZE = 4096; // 最大音频块大小 constexpr size_t QUEUE_CAPACITY = 4; // 音频队列容量 @@ -16,6 +21,15 @@ struct audio_block { // 单生产者单消费者无锁队列 using lock_free_queue = boost::lockfree::spsc_queue>; +template +using allocator_t = bi::allocator; + +using char_allocator = allocator_t; +using shm_string = bc::basic_string, char_allocator>; + +template +struct msg_id_t{}; + // 根据 plugin_id 生成 IPC 资源名称 inline std::string get_uds_path() { #if ALICHO_PLATFORM_WINDOWS diff --git a/src/backend/src/misc/src/rpc/rpc_manager.h b/src/backend/src/misc/src/rpc/rpc_manager.h index b234db4..22056ed 100644 --- a/src/backend/src/misc/src/rpc/rpc_manager.h +++ b/src/backend/src/misc/src/rpc/rpc_manager.h @@ -1,11 +1,26 @@ #pragma once #include +#include #include "lazy_singleton.h" #include "rpc_type.h" #include "common.h" +#include "ipc/shm_manager.h" -using rpc_callback = std::function&)>; +using rpc_callback = std::function; + +namespace bc = boost::container; + +struct rpc_message_t { + using alloca_t = allocator_t; + + rpc_message_t() : message_id(rpc::message_type::WTF), + data(shm_manager::msg_mgr()) { + } + + rpc::message_type message_id; + bc::vector data; +}; class rpc_message_handler : public lazy_singleton { public: @@ -15,33 +30,29 @@ public: handlers_[type] = std::move(handler); } - void handle_message(const rpc::rpc_header& in_header, const std::vector& in_payload) { - const auto& it = handlers_.find(in_header.type); + void handle_message(const rpc_message_t& in_msg) { + const auto& it = handlers_.find(in_msg.message_id); if (it != handlers_.end()) { - it->second(in_header.seq_id, in_payload); + spdlog::info("处理RPC消息,ID: {}", static_cast(in_msg.message_id)); + it->second(in_msg.data.data()); } else { - spdlog::warn("未处理的RPC消息类型: {}", static_cast(in_header.type)); + spdlog::warn("未处理的RPC消息类型: {}", static_cast(in_msg.message_id)); } } private: std::unordered_map handlers_; }; -template +template struct rpc_handler_register { - explicit rpc_handler_register(rpc::message_type in_type, const std::function& in_func) { - auto cast_func = [in_func](uint64_t in_seq_id, const std::vector& msg) { -#if ALICHO_DEBUG - assert(msg.size() == sizeof(T)); -#endif - auto payload = reinterpret_cast(msg.data()); - in_func(in_seq_id, *payload); + explicit rpc_handler_register(rpc::message_type in_type) { + auto real_func = [] (const void* payload){ + ((Msg*)payload)->process(); }; - rpc_message_handler::get_instance().register_rpc_handler(in_type, cast_func); + rpc_message_handler::get_instance().register_rpc_handler(in_type, real_func); } }; -#define REGISTER_RPC_HANDLER(type, body_type) \ - void __rpc_handler_func_##type(uint64_t seq_id, const body_type& body); \ - static rpc_handler_register __rpc_handler_register_##type(rpc::message_type::type, __rpc_handler_func_##type); +#define RPC_REG(type, t) \ + inline static auto t##_register = rpc_handler_register(rpc::message_type::##type); \ diff --git a/src/backend/src/misc/src/rpc/rpc_type.h b/src/backend/src/misc/src/rpc/rpc_type.h index 40cb5af..7f135c3 100644 --- a/src/backend/src/misc/src/rpc/rpc_type.h +++ b/src/backend/src/misc/src/rpc/rpc_type.h @@ -1,8 +1,16 @@ // RPC调用消息体结构, 由AudioEngine和PluginHost之间传输 #pragma once -#include +#include +#include #include +#include "ipc/shm_manager.h" +#include "common.h" + +namespace bc = boost::container; + +#define DEFINE_ID(type) static constexpr auto rpc_id = rpc::message_type::##type; + namespace rpc { enum class message_type : uint32_t { WTF = 0, // 未知消息类型, 用于调试 @@ -18,36 +26,35 @@ namespace rpc { SET_PARAMETER, // 设置参数 SHUTDOWN // 关闭插件 }; - - struct rpc_header { - message_type type; // 消息类型 - uint64_t seq_id; // 消息序列号 - uint32_t payload_size; // 有效载荷大小 - }; } -namespace rpc { +namespace engine_rpc { struct log { - uint32_t id; // 插件ID - spdlog::level::level_enum level; - std::array str; - }; + DEFINE_ID(LOG) - struct register_host { - uint32_t id; - }; + log() : level(spdlog::level::info) { + id = boost::uuids::random_generator()(); + } - struct process_done { - uint32_t id; // 插件ID - }; - - struct parameter_value_changed { - uint32_t id; // 插件ID - uint32_t parameter_id; // 参数ID - float value; // 新值 + void set_str(const std::string& in_str) { + auto str = shm_manager::get_instance().create_str(get_id(), in_str); + *str = in_str.c_str(); + } + void set_level(spdlog::level::level_enum in_level) { + level = in_level; + } + protected: + void destory_str() { + shm_manager::get_instance().destroy_str(get_id()); + } + auto get_id() const { + return boost::uuids::to_string(id) + "-log_shm_string"; + } + auto get_str() const { + return shm_manager::get_instance().find_str(get_id()); + } + protected: + boost::uuids::uuid id; + spdlog::level::level_enum level; }; } - -namespace rpc { - -} diff --git a/src/backend/src/misc/src/rpc/session.cpp b/src/backend/src/misc/src/rpc/session.cpp deleted file mode 100644 index faa2293..0000000 --- a/src/backend/src/misc/src/rpc/session.cpp +++ /dev/null @@ -1,41 +0,0 @@ -#include "session.h" - -#include "rpc_manager.h" - -void rpc::session::start() { - do_read_header(); -} - -void rpc::session::stop() { - -} - -void rpc::session::do_read_header() { - auto self = shared_from_this(); - // 读取消息到 read_queue_ 中 - auto func = [self](boost::system::error_code ec, std::size_t in_size) { - if (ec) - return; - self->do_read_body(); - }; - boost::asio::async_read(socket_, boost::asio::buffer{read_header_, 4}, func); -} - -void rpc::session::do_read_body() { - auto self = shared_from_this(); - auto func = [self](boost::system::error_code ec, std::size_t in_size) { - if (ec) - return; - // 处理读取到的消息 - rpc_message_handler::get_instance().handle_message(self->read_header_, self->read_body_); - }; - read_body_.resize(read_header_.payload_size); - boost::asio::async_read(socket_, boost::asio::buffer(read_body_, read_header_.payload_size), func); -} - -void rpc::session::do_write() { -} - -void rpc::server::do_accept() { - -} diff --git a/src/backend/src/misc/src/rpc/session.h b/src/backend/src/misc/src/rpc/session.h deleted file mode 100644 index b11cf30..0000000 --- a/src/backend/src/misc/src/rpc/session.h +++ /dev/null @@ -1,72 +0,0 @@ -#pragma once -#include -#include -#include - -#include "common.h" -#include "rpc_type.h" - -namespace rpc { - class session : public std::enable_shared_from_this { - public: - explicit session(boost::asio::local::stream_protocol::socket&& in_socket) - : socket_(std::move(in_socket)) { - } - - void start(); - void stop(); - - template - auto async_call(Msg&& msg) { - // 这里可以实现异步调用逻辑 - // 比如将消息放入写队列,触发写操作等 - return boost::asio::post(socket_.get_executor(), [this, msg = std::forward(msg)]() mutable { - write_queue_.emplace_back(std::move(msg)); - if (write_queue_.size() == 1) { - do_write(); - } - }); - } - private: - void do_read_header(); - void do_read_body(); - void do_write(); - - boost::asio::local::stream_protocol::socket socket_; - - rpc_header read_header_; - std::vector read_body_; - - std::deque> write_queue_; // 写队列, 用于发送消息 - std::atomic_uint32_t next_id_{ 1 }; - }; - - class server : public std::enable_shared_from_this { - public: - explicit server(boost::asio::io_context& io_context) : acceptor_(io_context, - boost::asio::local::stream_protocol::endpoint(get_uds_path()), false) { - } - - private: - void do_accept(); - - boost::asio::local::stream_protocol::acceptor acceptor_;; - }; - - class client { - public: - explicit client(boost::asio::io_context& io_context) { - boost::asio::local::stream_protocol::socket socket_(io_context); - socket_.connect(get_uds_path()); - session_ = std::make_shared(std::move(socket_)); - session_->start(); - } - - template - auto async_call(Msg&& msg) { - - } - private: - std::shared_ptr session_; - }; -} diff --git a/src/backend/src/vst2_host/CMakeLists.txt b/src/backend/src/vst2_host/CMakeLists.txt index 24421de..a7f2b65 100644 --- a/src/backend/src/vst2_host/CMakeLists.txt +++ b/src/backend/src/vst2_host/CMakeLists.txt @@ -17,10 +17,6 @@ target_link_libraries(${PROJECT_NAME} PRIVATE config_target glfw AlichoMisc - Boost::interprocess - Boost::lockfree - Boost::asio - Boost::system ) target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src) register_plugin_host(${PROJECT_NAME}) diff --git a/src/backend/src/vst2_host/src/main.cpp b/src/backend/src/vst2_host/src/main.cpp index dc83c3b..65f5ef9 100644 --- a/src/backend/src/vst2_host/src/main.cpp +++ b/src/backend/src/vst2_host/src/main.cpp @@ -7,13 +7,24 @@ #include "spdlog/spdlog.h" #include +#include "ipc/ipc_node.h" + namespace bi = boost::interprocess; int main(int argc, char *argv[]) { - if (argc != 3) - return 1; + // if (argc != 3) + // return 1; + shm_manager::get_instance().init(); + engine_rpc::log t{}; + t.set_str("Hello from Plugin Sandbox!"); + t.set_level(spdlog::level::info); + + plugin_ipc_node node("plugin1"); + node.call_rpc(t); + +#if 0 std::string shm_input_path = argv[1]; std::string shm_output_path = argv[2]; @@ -65,5 +76,6 @@ int main(int argc, char *argv[]) bi::shared_memory_object::remove(shm_input_path.c_str()); bi::shared_memory_object::remove(shm_output_path.c_str()); +#endif return 0; } diff --git a/src/backend/vcpkg.json b/src/backend/vcpkg.json index 8ef420e..16a2160 100644 --- a/src/backend/vcpkg.json +++ b/src/backend/vcpkg.json @@ -14,5 +14,17 @@ }, { "name" : "boost-lockfree", "version>=" : "1.88.0" + }, { + "name" : "tbb", + "version>=" : "2022.1.0" + }, { + "name" : "boost-circular-buffer", + "version>=" : "1.88.0" + }, { + "name" : "boost-uuid", + "version>=" : "1.88.0" + }, { + "name" : "boost-thread", + "version>=" : "1.88.0" } ] } \ No newline at end of file