#include "Pattern.h" #include "Singleton/MidiSequencer.h" #include "Singleton/PortAudioAPI.h" #include "Pattern/PatternInstance.h" #include "Thread/MainThreadEventList.h" DECLARE_THREAD_MESSAGE(FPortAudioAPI, DestroyPatternInstance, FPattern* Pattern; FPatternInstance* Instance; ) { Args.Pattern->DestroyInstance(Args.Instance); } DECLARE_THREAD_MESSAGE(FMainThreadEventList, OnCreatePatternInstance, FPatternInstance* Instance; ) { FMidiSequencer::Get().OnCreatePatternInstance.Broadcast(Args.Instance); } DECLARE_THREAD_MESSAGE(FMainThreadEventList, OnDestroyPatternInstance, FPatternInstance* Instance; ) { FMidiSequencer::Get().OnDeletePatternInstance.Broadcast(Args.Instance); delete Args.Instance; } DECLARE_PROMISE_THREAD_MESSAGE(FPortAudioAPI, CreatePatternInstance, FPatternInstance*, FPattern* Pattern; int32 TrackIndex; AudioFrame Pos; AudioFrame PatternBegin; AudioFrame PatternEnd; ) { FPatternInstance* NewInstance = Args.Pattern->CreateInstance(Args.TrackIndex,Args.Pos, Args.PatternBegin, Args.PatternEnd); Done(NewInstance); PUSH_THREAD_EVENT(OnCreatePatternInstance, NewInstance); } TFuture FPattern::RequestCreateInstance(int32 TrackIndex, AudioFrame Pos, AudioFrame PatternBegin, AudioFrame PatternEnd) { return PUSH_THREAD_EVENT(CreatePatternInstance, this, TrackIndex, Pos, PatternBegin, PatternEnd); } void FPattern::RequestDestroyInstance(FPatternInstance* Instance) { PUSH_THREAD_EVENT(DestroyPatternInstance, this, Instance); } FPatternInstance* FPattern::CreateInstance(int32 TrackIndex, AudioFrame InPos, AudioFrame PatternBegin, AudioFrame PatternEnd) { FPatternInstance* Instance = new FPatternInstance(this, TrackIndex, InPos, TRange(PatternBegin, PatternEnd)); Instances.Add(Instance); return Instance; } void FPattern::DestroyInstance(FPatternInstance* Instance) { if (Instances.RemoveSingle(Instance) == 0) return; PUSH_THREAD_EVENT(OnDestroyPatternInstance, Instance); } void FPattern::ProcessInstances(AudioFrame SequencePos, uint32 InLength) { for (const auto Instance : Instances) { Instance->Process(SequencePos, InLength); } }