Files
Alicho/examples/plugin_host_demo.cpp
2025-10-28 10:27:49 +08:00

341 lines
14 KiB
C++

// ================================================================================================
// Audio Backend - 插件沙盒系统演示
// ================================================================================================
// 描述: 演示插件沙盒和隔离系统的完整使用方法
// ================================================================================================
#include <audio_backend/plugin_host.h>
#include <iostream>
#include <thread>
#include <chrono>
using namespace audio_backend::plugin;
// ================================================================================================
// 示例插件事件监听器
// ================================================================================================
class DemoPluginEventListener : public IPluginHostEventListener {
public:
void on_plugin_loaded(const std::string& instance_id, const PluginInfo& info) override {
std::cout << "[EVENT] 插件已加载: " << instance_id
<< " (" << info.plugin_name << " v" << info.plugin_version.to_string() << ")\n";
}
void on_plugin_unloaded(const std::string& instance_id) override {
std::cout << "[EVENT] 插件已卸载: " << instance_id << "\n";
}
void on_plugin_activated(const std::string& instance_id) override {
std::cout << "[EVENT] 插件已激活: " << instance_id << "\n";
}
void on_plugin_deactivated(const std::string& instance_id) override {
std::cout << "[EVENT] 插件已停用: " << instance_id << "\n";
}
void on_plugin_state_changed(
const std::string& instance_id,
PluginState old_state,
PluginState new_state) override {
std::cout << "[EVENT] 插件状态变化: " << instance_id
<< " " << get_state_name(old_state)
<< " -> " << get_state_name(new_state) << "\n";
}
void on_plugin_error(
const std::string& instance_id,
const ErrorInfo& error) override {
std::cout << "[ERROR] 插件错误: " << instance_id
<< " - " << error.to_string() << "\n";
}
void on_plugin_crashed(
const std::string& instance_id,
const std::string& crash_reason) override {
std::cout << "[CRASH] 插件崩溃: " << instance_id
<< " - " << crash_reason << "\n";
}
void on_plugin_performance_warning(
const std::string& instance_id,
const std::string& warning) override {
std::cout << "[WARN] 插件性能警告: " << instance_id
<< " - " << warning << "\n";
}
void on_sandbox_violation(
const std::string& instance_id,
const std::string& violation_type) override {
std::cout << "[SECURITY] 沙违规: " << instance_id
<< " - " << violation_type << "\n";
}
};
// ================================================================================================
// 系统信息演示
// ================================================================================================
void demo_system_info() {
std::cout << "\n=== 系统信息演示 ===\n";
// 打印插件宿主系统信息
print_plugin_host_info();
// 检查沙盒支持
auto sandbox_types = get_supported_sandbox_types();
std::cout << "\n当前平台支持沙盒类型:\n";
for (const auto& type : sandbox_types) {
std::cout << " - " << get_sandbox_type_name(type) << "\n";
}
std::cout << "推荐的沙盒类型: " << get_sandbox_type_name(get_recommended_sandbox_type()) << "\n";
}
// ================================================================================================
// 基本插件管理演示
// ================================================================================================
void demo_basic_plugin_management() {
std::cout << "\n=== 基本插件管理演示 ===\n";
// 创建插件宿主管理器
std::cout << "创建插件宿主管器...\n";
auto host_manager = create_plugin_host_manager();
if (!host_manager || !host_manager->is_initialized()) {
std::cerr << "插件宿主管理器始化失败!\n";
return;
}
// 添加事件监听器
auto listener = std::make_shared<DemoPluginEventListener>();
host_manager->add_event_listener(listener);
// 配置沙盒
auto effect_config = create_audio_effect_sandbox_config();
std::cout << "沙盒配置:\n";
std::cout << " 最大内存: " << effect_config.limits.max_memory_bytes / (1024 * 1024) << " MB\n";
std::cout << " 最大CPU: " << effect_config.limits.max_cpu_percent << "%\n";
std::cout << " 最大线程数: " << effect_config.limits.max_threads << "\n";
std::cout << " 网络访问: " << (effect_config.security.allow_network_access ? "允许" : "禁止") << "\n";
// 模拟插件路径(实际使用时需要真实的插件文件)
std::string demo_plugin_path = "demo_effect_plugin.dll";
std::string instance_id = "demo_effect_1";
std::cout << "\n尝试加载插件: " << demo_plugin_path << "\n";
// 同步加载插件(这里会失败,因为插件文件不存在,但演示了流程)
auto load_result = host_manager->load_plugin(
demo_plugin_path,
instance_id,
effect_config,
true // auto_activate
);
if (load_result == common::ErrorCode::SUCCESS) {
std::cout << "插件加载成功!\n";
// 获取插件信息
auto plugin_info = host_manager->get_plugin_instance_info(instance_id);
if (plugin_info) {
std::cout << "插件状态: " << get_state_name(plugin_info->current_state) << "\n";
}
// 获取性能指标
auto metrics = host_manager->get_plugin_metrics(instance_id);
std::cout << "性能指标:\n";
std::cout << " CPU使用率: " << metrics.cpu_usage << "%\n";
std::cout << " 内存使用: " << metrics.memory_usage / (1024 * 1024) << " MB\n";
// 等待一段时间模拟处理
std::this_thread::sleep_for(std::chrono::seconds(2));
// 卸载插件
std::cout << "\n卸载插件...\n";
host_manager->unload_plugin(instance_id, true);
} else {
std::cout << "插件加载失败 (预期的,因为演插件文件不存在): "
<< common::get_error_description(load_result) << "\n";
}
// 获取宿主统计信息
auto stats = host_manager->get_host_statistics();
std::cout << "\n宿主统计信息:\n";
std::cout << " 总加载插件数: " << stats.total_plugins_loaded << "\n";
std::cout << " 总卸载插件数: " << stats.total_plugins_unloaded << "\n";
std::cout << " 总崩溃次数: " << stats.total_plugin_crashes << "\n";
}
// ================================================================================================
// 沙盒配置演示
// ================================================================================================
void demo_sandbox_configurations() {
std::cout << "\n=== 沙盒配置演示 ===\n";
// 演示不同类型的沙盒配置
std::cout << "\n1. 音频效果器沙盒配置:\n";
auto effect_config = create_audio_effect_sandbox_config();
std::cout << " 内存限制: " << effect_config.limits.max_memory_bytes / (1024 * 1024) << " MB\n";
std::cout << " CPU限制: " << effect_config.limits.max_cpu_percent << "%\n";
std::cout << " 处理时间限制: " << effect_config.limits.max_processing_time_ms << " ms\n";
std::cout << "\n2. 乐器沙盒配置:\n";
auto instrument_config = create_instrument_sandbox_config();
std::cout << " 内存限制: " << instrument_config.limits.max_memory_bytes / (1024 * 1024) << " MB\n";
std::cout << " CPU限制: " << instrument_config.limits.max_cpu_percent << "%\n";
std::cout << " 处理时间限制: " << instrument_config.limits.max_processing_time_ms << " ms\n";
std::cout << "\n3. 分析器沙盒配置:\n";
auto analyzer_config = create_analyzer_sandbox_config();
std::cout << " 内存限制: " << analyzer_config.limits.max_memory_bytes / (1024 * 1024) << " MB\n";
std::cout << " CPU限制: " << analyzer_config.limits.max_cpu_percent << "%\n";
std::cout << " 文件访问: " << (analyzer_config.security.allow_file_system_access ? "允许" : "禁止") << "\n";
std::cout << "\n4. 严格安全模式配置:\n";
auto strict_config = SandboxConfig::strict();
std::cout << " 内存限制: " << strict_config.limits.max_memory_bytes / (1024 * 1024) << " MB\n";
std::cout << " CPU限制: " << strict_config.limits.max_cpu_percent << "%\n";
std::cout << " 网络访问: " << (strict_config.security.allow_network_access ? "允许" : "禁止") << "\n";
std::cout << " 文件系统访问: " << (strict_config.security.allow_file_system_access ? "允许" : "禁止") << "\n";
}
// ================================================================================================
// 音频处理演示
// ================================================================================================
void demo_audio_processing() {
std::cout << "\n=== 音频处理演示 ===\n";
// 创建音频缓冲区
engine::AudioConfig audio_config;
audio_config.sample_rate = 48000;
audio_config.channels = 2;
audio_config.format = engine::AudioFormat::FLOAT32;
audio_config.frames_per_buffer = 512;
engine::AudioBuffer input_buffer(audio_config);
engine::AudioBuffer output_buffer(audio_config);
std::cout << "音频配置:\n";
std::cout << " 采样率: " << audio_config.sample_rate << " Hz\n";
std::cout << " 声道数: " << audio_config.channels << "\n";
std::cout << " 格式: " << engine::get_format_name(audio_config.format) << "\n";
std::cout << " 缓冲区大小: " << audio_config.frames_per_buffer << "\n";
std::cout << " 延迟: " << audio_config.get_latency_ms() << " ms\n";
// 创建处理上下文
PluginProcessContext context;
context.sample_rate = audio_config.sample_rate;
context.block_size = audio_config.frames_per_buffer;
context.is_playing = true;
context.tempo = 120.0;
// 创建MIDI事件
std::vector<MidiEvent> midi_in;
std::vector<MidiEvent> midi_out;
// 添加一些示例MIDI件
midi_in.emplace_back(0, 0x90, 60, 100); // Note On C4, velocity 100
midi_in.emplace_back(256, 0x80, 60, 0); // Note Off C4
std::cout << "\nMIDI事件:\n";
for (const auto& event : midi_in) {
if (event.is_note_on()) {
std::cout << " 时间戳 " << event.timestamp << ": Note On, 音符 "
<< (int)event.get_note() << ", 力度 " << (int)event.get_velocity() << "\n";
} else if (event.is_note_off()) {
std::cout << " 时间戳 " << event.timestamp << ": Note Off, 音符 "
<< (int)event.get_note() << "\n";
}
}
std::cout << "\n模拟音频处理...\n";
// 这里通常会调用插件的音频处理方法
// 由于没有真实插件,我们只是演示数据结构
std::cout << "输入缓冲区大小: " << input_buffer.size_bytes() << " 字节\n";
std::cout << "输出缓冲区大小: " << output_buffer.size_bytes() << " 字节\n";
}
// ================================================================================================
// 插件发现演示
// ================================================================================================
void demo_plugin_discovery() {
std::cout << "\n=== 插件发现演示 ===\n";
auto host_manager = create_plugin_host_manager();
if (!host_manager) {
std::cerr << "无法创建插件宿管理器\n";
return;
}
// 演示插件目录扫描
std::vector<std::string> search_paths = {
"/usr/lib/vst",
"/usr/local/lib/vst",
"C:/Program Files/VSTPlugins",
"C:/Program Files (x86)/VSTPlugins",
"/Library/Audio/Plug-Ins/VST",
"~/Library/Audio/Plug-Ins/VST"
};
std::cout << "搜索插件路径:\n";
for (const auto& path : search_paths) {
std::cout << " - " << path << "\n";
// 尝试扫描目录(大部分路径在演示环境中不存在)
try {
auto plugin_paths = host_manager->scan_plugin_directory(path, false);
std::cout << " 发现 " << plugin_paths.size() << " 个插件\n";
// 扫描前几个插件的信息
for (size_t i = 0; i < std::min(plugin_paths.size(), size_t(3)); ++i) {
auto info = host_manager->scan_plugin_info(plugin_paths[i]);
if (info) {
std::cout << " 插件: " << info->plugin_name
<< " v" << info->plugin_version.to_string()
<< " (" << get_format_name(info->plugin_format) << ")\n";
}
}
} catch (const std::exception& e) {
// 路径不存在或无法访问是正常的
std::cout << " (路径不存在或无访问)\n";
}
}
}
// ================================================================================================
// 主函数
// ================================================================================================
int main() {
std::cout << "====================================\n";
std::cout << "Audio Backend 插件沙盒系统演示\n";
std::cout << "====================================\n";
try {
// 系统信息演示
demo_system_info();
// 沙盒配置演示
demo_sandbox_configurations();
// 音频处理演示
demo_audio_processing();
// 插件发现演示
demo_plugin_discovery();
// 基本插件管理演示
demo_basic_plugin_management();
std::cout << "\n====================================\n";
std::cout << "演示完成\n";
std::cout << "====================================\n";
} catch (const std::exception& e) {
std::cerr << "演示过程中发生误: " << e.what() << "\n";
return 1;
}
return 0;
}