plugin_host窗口位置保, channel_rack控件

This commit is contained in:
Nanako 2024-03-01 09:08:47 +08:00
parent fbd7e63756
commit cb3b2e0c6a
18 changed files with 156 additions and 26 deletions

View File

@ -12,6 +12,7 @@
#include "spdlog/async.h"
#include "spdlog/spdlog.h"
#include "spdlog/sinks/basic_file_sink.h"
#include "thread_message/thread_message_hubs.h"
bool g_is_running = true;
bool g_exit_requested = false;
@ -50,6 +51,7 @@ void application::init(const window_params& in_window_params, int argc, char** a
int application::run() {
const ImGuiIO& io = ImGui::GetIO();
while (!g_exit_requested) {
g_main_thread_hub.process_messages();
g_window_manager.tick();
g_exit_requested = g_exit_requested || g_window_manager.should_close();
tick(io.DeltaTime);

View File

@ -48,6 +48,10 @@ GLFWwindow* window_manager::create_plugin_host_window(plugin_host* host) {
return host_window_map_[host];
auto editor_size = host->get_editor_size();
auto new_window = glfwCreateWindow(editor_size.x, editor_size.y, host->name.c_str(), nullptr, nullptr);
if (host_window_pos_map_.contains(host)) {
auto pos = host_window_pos_map_[host];
glfwSetWindowPos(new_window, pos.x, pos.y);
}
host_window_map_[host] = new_window;
return new_window;
}
@ -55,8 +59,11 @@ GLFWwindow* window_manager::create_plugin_host_window(plugin_host* host) {
void window_manager::destroy_plugin_host_window(plugin_host* host) {
if (!host_window_map_.contains(host))
return;
int x, y;
glfwGetWindowPos(host_window_map_[host], &x, &y);
glfwDestroyWindow(host_window_map_[host]);
host_window_map_.erase(host);
host_window_pos_map_[host] = ImVec2(x, y);
}
void window_manager::resize_plugin_host_window(plugin_host* host, int width, int height) {
@ -75,13 +82,11 @@ void window_manager::update_host_window() {
std::vector<plugin_host*> host_editor_to_close;
for (const auto& [host, window]: host_window_map_) {
if (glfwWindowShouldClose(window)) {
host->close_editor();
glfwDestroyWindow(window);
host_editor_to_close.push_back(host);
}
}
for (auto host: host_editor_to_close) {
host_window_map_.erase(host);
host->try_close_editor();
}
idle_plugin_host_window();
}

View File

@ -3,6 +3,8 @@
#include "misc/singleton/singleton.h"
#include <map>
#include "imgui.h"
class plugin_host;
class window_manager : public singleton_t<window_manager> {
@ -30,6 +32,7 @@ private:
GLFWwindow* main_window_;
std::map<plugin_host*, GLFWwindow*> host_window_map_;
std::map<plugin_host*, ImVec2> host_window_pos_map_;
};
DEFINE_SINGLETON_INSTANCE(window_manager)

View File

@ -9,8 +9,28 @@ plugin_host::~plugin_host() {
}
void plugin_host::try_open_editor() {
if (!has_editor())
return;
editor_window = g_window_manager.create_plugin_host_window(this);
open_editor(editor_window);
editor_opened = true;
}
void plugin_host::try_close_editor() {
if (!has_editor())
return;
close_editor();
editor_opened = false;
g_window_manager.destroy_plugin_host_window(this);
}
void plugin_host::toggle_editor() {
if (!has_editor())
return;
if (editor_opened)
try_close_editor();
else
try_open_editor();
}
void plugin_host::init_channel_interface() {

View File

@ -23,8 +23,8 @@ public:
virtual void process(uint32_t frame_num) = 0;
void try_open_editor();
virtual void open_editor(GLFWwindow* window) = 0;
virtual void close_editor() = 0;
void try_close_editor();
virtual void toggle_editor();
virtual void idle_editor() {}
[[nodiscard]] virtual bool has_editor() const { return false; }
@ -40,4 +40,8 @@ public:
channel_interface* channel = nullptr;
std::vector<mixer_track*> owner_tracks;
GLFWwindow* editor_window = nullptr;
bool editor_opened = false;
protected:
virtual void open_editor(GLFWwindow* window) = 0;
virtual void close_editor() = 0;
};

View File

@ -24,6 +24,28 @@ void plugin_host_manager::release() {
}
}
plugin_host* plugin_host_manager::create_instrument_plugin_host(const char* path) {
auto host = load_plugin(path);
if (host) {
register_instrument_plugin(host);
}
return host;
}
void plugin_host_manager::remove_instrument_plugin_host(plugin_host* host) {
g_audio_thread_hub.push_message([host, this]() {
auto find = std::ranges::find(instrument_plugins_, host);
if (find != instrument_plugins_.end()) {
plugin_hosts_.erase(std::ranges::find(plugin_hosts_, host));
instrument_plugins_.erase(find);
g_main_thread_hub.push_message([host, this]() {
on_instrument_removed.broadcast(host);
delete host;
});
}
});
}
plugin_host* plugin_host_manager::load_plugin(const char* path) {
auto host = new vst2_plugin_host();
try {
@ -36,16 +58,21 @@ plugin_host* plugin_host_manager::load_plugin(const char* path) {
host->init_channel_interface();
host->on_update_buffer_size(g_audio_device_manager.get_buffer_size());
host->on_update_sample_rate(g_audio_device_manager.get_sample_rate());
plugin_hosts_.push_back(host);
return host;
}
void plugin_host_manager::register_instrument_plugin(plugin_host* host) {
g_audio_thread_hub.push_message([this, host]() {
instrument_track* instrument_track = g_mixer.create_instrument_track(host);
host->channel->set_input_channel(instrument_track->get_channel_interface()->input_channel_nodes);
host->channel->set_output_channel(instrument_track->get_channel_interface()->output_channel_nodes);
host->owner_tracks.push_back(instrument_track);
host->update_channel_node_name();
plugin_hosts_.push_back(host);
g_main_thread_hub.push_message([host, this]() {
on_instrument_added.broadcast(host);
});
});
return host;
}
void plugin_host_manager::process(uint32_t in_frames) const {

View File

@ -1,4 +1,5 @@
#pragma once
#include "misc/delegates.h"
#include "misc/singleton/singleton.h"
class plugin_host;
@ -9,16 +10,23 @@ public:
void init(singleton_initliazer& initliazer) override;
void release() override;
plugin_host* load_plugin(const char* path);
plugin_host* create_instrument_plugin_host(const char* path);
void remove_instrument_plugin_host(plugin_host* host);
const std::vector<plugin_host*>& get_plugin_hosts() { return plugin_hosts_; }
void process(uint32_t in_frames) const;
const char* get_name() override { return "plugin_host_manager"; }
private:
multicast_delegate<plugin_host*> on_instrument_added;
multicast_delegate<plugin_host*> on_instrument_removed;
private:
plugin_host* load_plugin(const char* path);
void register_instrument_plugin(plugin_host* host);
void on_mixer_track_removed(mixer_track* track);
std::vector<plugin_host*> instrument_plugins_{};
std::vector<plugin_host*> plugin_hosts_{};
};

View File

@ -216,20 +216,6 @@ void vst2_plugin_host::process(uint32_t frame_num) {
effect_->processReplacing(effect_, channel->get_input_headers(), channel->get_output_headers(), frame_num);
}
void vst2_plugin_host::open_editor(GLFWwindow* window) {
if (!has_editor())
return;
void* window_handle = glfwGetWindowHandle(window);
dispatch(effEditOpen, 0, 0, window_handle);
}
void vst2_plugin_host::close_editor() {
if (!has_editor())
return;
dispatch(effEditClose);
}
void vst2_plugin_host::idle_editor() {
plugin_host::idle_editor();
dispatch(effEditIdle);
@ -259,6 +245,19 @@ std::string vst2_plugin_host::load_vendor() const {
return buffer;
}
void vst2_plugin_host::open_editor(GLFWwindow* window) {
if (!has_editor())
return;
void* window_handle = glfwGetWindowHandle(window);
dispatch(effEditOpen, 0, 0, window_handle);
}
void vst2_plugin_host::close_editor() {
if (!has_editor())
return;
dispatch(effEditClose);
}
VstIntPtr vst2_plugin_host::dispatch(VstInt32 opcode, VstInt32 index, VstIntPtr value, void* ptr, float opt) const {
return effect_->dispatcher(effect_, opcode, index, value, ptr, opt);

View File

@ -22,14 +22,15 @@ public:
void process(uint32_t frame_num) override;
void open_editor(GLFWwindow* window) override;
void close_editor() override;
void idle_editor() override;
[[nodiscard]] bool has_editor() const override;
[[nodiscard]] ImVec2 get_editor_size() const override;
[[nodiscard]] std::string load_name() const override;
[[nodiscard]] std::string load_vendor() const override;
protected:
void open_editor(GLFWwindow* window) override;
void close_editor() override;
private:
VstIntPtr dispatch(VstInt32 opcode, VstInt32 index = 0, VstIntPtr value = 0, void* ptr = nullptr, float opt = 0) const;
AEffect* effect_;

View File

@ -429,7 +429,7 @@ public:
constexpr static const unsigned int INVALID_ID = (unsigned int)~0;
private:
unsigned int id_;
static unsigned int CURRENT_ID;
CORE_API static unsigned int CURRENT_ID;
static int get_new_id()
{

View File

@ -0,0 +1,8 @@
#include "compound_widget.h"
void compound_widget::set_content(const std::shared_ptr<widget>& content) {
child_ = content;
}
void compound_widget::on_paint(ImGuiIO& io) {
}

View File

@ -0,0 +1,10 @@
#pragma once
#include "widget.h"
class compound_widget : public widget {
public:
void set_content(const std::shared_ptr<widget>& content);
void on_paint(ImGuiIO& io) override;
private:
std::shared_ptr<widget> child_;
};

View File

@ -0,0 +1 @@
#include "leaf_widget.h"

View File

@ -0,0 +1,7 @@
#pragma once
#include "widget.h"
class leaf_widget : public widget {
public:
};

View File

@ -0,0 +1 @@
#include "panel_widget.h"

View File

@ -0,0 +1,7 @@
#pragma once
#include "widget.h"
class panel_widget : public widget {
public:
};

11
core/widget/widget.cpp Normal file
View File

@ -0,0 +1,11 @@
#include "widget.h"
#include <random>
ImGuiID widget::generate_widget_id() {
// random number generator
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<ImGuiID> dis(0, std::numeric_limits<ImGuiID>::max());
return dis(gen);
}

16
core/widget/widget.h Normal file
View File

@ -0,0 +1,16 @@
#pragma once
#include "imgui.h"
class geometry;
class CORE_API widget : public std::enable_shared_from_this<widget> {
public:
virtual ~widget() = default;
virtual void tick() {}
virtual void on_paint(ImGuiIO& io) = 0;
virtual void on_arrange_children(const geometry& allotted_geometry) {}
[[nodiscard]] virtual ImVec2 compute_desired_size() const { return {0, 0}; }
static ImGuiID generate_widget_id();
};