pluginbridge / Source /Helper /HelperPluginHost.h
Sitar118
fix: replace CARemoteLayerServer with CAContext+CALayerHost for cross-process GUI
0548359
Raw
History Blame Contribute Delete
3.09 kB
#pragma once
#include <juce_audio_processors/juce_audio_processors.h>
#include <juce_gui_basics/juce_gui_basics.h>
#include <thread>
#include <atomic>
#include "SharedAudioBuffer.h"
class HelperPluginHost
{
public:
HelperPluginHost();
~HelperPluginHost();
// Plugin lifecycle
bool loadPlugin(const juce::String& path, double sampleRate, int blockSize);
void unloadPlugin();
bool isLoaded() const { return plugin != nullptr; }
juce::String getPluginName() const;
int getParameterCount() const;
// Audio processing (shared memory)
void setSharedAudio(SharedAudioBuffer* shm, SharedSemaphore* inSem, SharedSemaphore* outSem);
void startProcessing();
void stopProcessing();
// Parameters
struct ParamInfo {
int index;
juce::String id;
juce::String name;
float value;
juce::String displayText;
};
std::vector<ParamInfo> searchParams(const juce::String& keyword) const;
std::vector<std::pair<int, float>> getParams(const std::vector<int>& ids) const;
bool setParams(const std::map<int, float>& values);
// GUI via CARemoteLayerServer
void showGui();
void hideGui();
int getGuiWidth() const { return guiWidth; }
int getGuiHeight() const { return guiHeight; }
void setLayerPortName(const juce::String& name) { layerPortName = name; }
juce::String getLayerPortName() const { return layerPortName; }
// Event injection (from host process)
void injectMouseDown(float x, float y, int button);
void injectMouseUp(float x, float y, int button);
void injectMouseMove(float x, float y);
void injectMouseDrag(float x, float y, int button);
void injectMouseScroll(float x, float y, float dx, float dy);
void injectKeyDown(int keyCode, const juce::String& chars, int modifiers);
void injectKeyUp(int keyCode, const juce::String& chars, int modifiers);
// State
juce::String getStateBase64() const;
bool setStateBase64(const juce::String& base64State);
void configure(double sampleRate, int blockSize, int channels);
// Callbacks
std::function<void(const juce::String& portName, int width, int height)> onGuiCreated;
std::function<void(int w, int h)> onGuiResized;
private:
void audioProcessingLoop();
juce::AudioPluginFormatManager formatManager;
std::unique_ptr<juce::AudioPluginInstance> plugin;
std::unique_ptr<juce::AudioProcessorEditor> editor;
std::thread audioThread;
std::atomic<bool> processing{false};
SharedAudioBuffer* sharedAudio = nullptr;
SharedSemaphore* inputSem = nullptr;
SharedSemaphore* outputSem = nullptr;
double currentSampleRate = 44100.0;
int currentBlockSize = 512;
int currentChannels = 2;
// GUI
int guiWidth = 0;
int guiHeight = 0;
juce::String layerPortName;
// ObjC objects (stored as void* to avoid ObjC in header)
void* caContext = nullptr; // CAContext* — cross-process layer server
void* guiWindow = nullptr; // NSWindow* — off-screen, ordered-front for compositing
};