DeferredWindowEvents moved to boo

This commit is contained in:
Jack Andersen 2016-05-10 18:50:26 -10:00
parent f86b9706d4
commit b3e77c4384
6 changed files with 305 additions and 7 deletions

View File

@ -200,6 +200,7 @@ add_library(boo
include/boo/IWindow.hpp include/boo/IWindow.hpp
include/boo/IApplication.hpp include/boo/IApplication.hpp
include/boo/ThreadLocalPtr.hpp include/boo/ThreadLocalPtr.hpp
include/boo/DeferredWindowEvents.hpp
include/boo/System.hpp include/boo/System.hpp
include/boo/boo.hpp include/boo/boo.hpp
InputDeviceClasses.cpp InputDeviceClasses.cpp

View File

@ -0,0 +1,273 @@
#ifndef BOO_DEFERREDWINDOWEVENTS_HPP
#define BOO_DEFERREDWINDOWEVENTS_HPP
#include <boo/boo.hpp>
#include <mutex>
#include <condition_variable>
namespace boo
{
template <class Receiver>
struct DeferredWindowEvents : public IWindowCallback
{
Receiver& m_rec;
std::mutex m_mt;
std::condition_variable m_resizeCv;
DeferredWindowEvents(Receiver& rec) : m_rec(rec) {}
bool m_destroyed = false;
void destroyed()
{
m_destroyed = true;
}
bool m_hasResize = false;
SWindowRect m_latestResize;
void resized(const SWindowRect& rect)
{
std::unique_lock<std::mutex> lk(m_mt);
m_latestResize = rect;
m_hasResize = true;
m_resizeCv.wait_for(lk, std::chrono::milliseconds(500));
}
struct Command
{
enum class Type
{
MouseDown,
MouseUp,
MouseMove,
MouseEnter,
MouseLeave,
Scroll,
TouchDown,
TouchUp,
TouchMove,
CharKeyDown,
CharKeyUp,
SpecialKeyDown,
SpecialKeyUp,
ModKeyDown,
ModKeyUp
} m_type;
SWindowCoord m_coord;
EMouseButton m_button;
EModifierKey m_mods;
SScrollDelta m_scroll;
STouchCoord m_tCoord;
uintptr_t m_tid;
unsigned long m_charcode;
ESpecialKey m_special;
bool m_isRepeat;
void dispatch(Receiver& rec) const
{
switch (m_type)
{
case Type::MouseDown:
rec.mouseDown(m_coord, m_button, m_mods);
break;
case Type::MouseUp:
rec.mouseUp(m_coord, m_button, m_mods);
break;
case Type::MouseMove:
rec.mouseMove(m_coord);
break;
case Type::MouseEnter:
rec.mouseEnter(m_coord);
break;
case Type::MouseLeave:
rec.mouseLeave(m_coord);
break;
case Type::Scroll:
rec.scroll(m_coord, m_scroll);
break;
case Type::TouchDown:
rec.touchDown(m_tCoord, m_tid);
break;
case Type::TouchUp:
rec.touchUp(m_tCoord, m_tid);
break;
case Type::TouchMove:
rec.touchMove(m_tCoord, m_tid);
break;
case Type::CharKeyDown:
rec.charKeyDown(m_charcode, m_mods, m_isRepeat);
break;
case Type::CharKeyUp:
rec.charKeyUp(m_charcode, m_mods);
break;
case Type::SpecialKeyDown:
rec.specialKeyDown(m_special, m_mods, m_isRepeat);
break;
case Type::SpecialKeyUp:
rec.specialKeyUp(m_special, m_mods);
break;
case Type::ModKeyDown:
rec.modKeyDown(m_mods, m_isRepeat);
break;
case Type::ModKeyUp:
rec.modKeyUp(m_mods);
break;
default: break;
}
}
Command(Type tp) : m_type(tp) {}
};
std::vector<Command> m_cmds;
void mouseDown(const SWindowCoord& coord, EMouseButton button, EModifierKey mods)
{
std::unique_lock<std::mutex> lk(m_mt);
m_cmds.emplace_back(Command::Type::MouseDown);
m_cmds.back().m_coord = coord;
m_cmds.back().m_button = button;
m_cmds.back().m_mods = mods;
}
void mouseUp(const SWindowCoord& coord, EMouseButton button, EModifierKey mods)
{
std::unique_lock<std::mutex> lk(m_mt);
m_cmds.emplace_back(Command::Type::MouseUp);
m_cmds.back().m_coord = coord;
m_cmds.back().m_button = button;
m_cmds.back().m_mods = mods;
}
void mouseMove(const SWindowCoord& coord)
{
std::unique_lock<std::mutex> lk(m_mt);
m_cmds.emplace_back(Command::Type::MouseMove);
m_cmds.back().m_coord = coord;
}
void mouseEnter(const SWindowCoord& coord)
{
std::unique_lock<std::mutex> lk(m_mt);
m_cmds.emplace_back(Command::Type::MouseEnter);
m_cmds.back().m_coord = coord;
}
void mouseLeave(const SWindowCoord& coord)
{
std::unique_lock<std::mutex> lk(m_mt);
m_cmds.emplace_back(Command::Type::MouseLeave);
m_cmds.back().m_coord = coord;
}
void scroll(const SWindowCoord& coord, const SScrollDelta& scroll)
{
std::unique_lock<std::mutex> lk(m_mt);
m_cmds.emplace_back(Command::Type::Scroll);
m_cmds.back().m_coord = coord;
m_cmds.back().m_scroll = scroll;
}
void touchDown(const STouchCoord& coord, uintptr_t tid)
{
std::unique_lock<std::mutex> lk(m_mt);
m_cmds.emplace_back(Command::Type::TouchDown);
m_cmds.back().m_tCoord = coord;
m_cmds.back().m_tid = tid;
}
void touchUp(const STouchCoord& coord, uintptr_t tid)
{
std::unique_lock<std::mutex> lk(m_mt);
m_cmds.emplace_back(Command::Type::TouchUp);
m_cmds.back().m_tCoord = coord;
m_cmds.back().m_tid = tid;
}
void touchMove(const STouchCoord& coord, uintptr_t tid)
{
std::unique_lock<std::mutex> lk(m_mt);
m_cmds.emplace_back(Command::Type::TouchMove);
m_cmds.back().m_tCoord = coord;
m_cmds.back().m_tid = tid;
}
void charKeyDown(unsigned long charCode, EModifierKey mods, bool isRepeat)
{
std::unique_lock<std::mutex> lk(m_mt);
m_cmds.emplace_back(Command::Type::CharKeyDown);
m_cmds.back().m_charcode = charCode;
m_cmds.back().m_mods = mods;
m_cmds.back().m_isRepeat = isRepeat;
}
void charKeyUp(unsigned long charCode, EModifierKey mods)
{
std::unique_lock<std::mutex> lk(m_mt);
m_cmds.emplace_back(Command::Type::CharKeyUp);
m_cmds.back().m_charcode = charCode;
m_cmds.back().m_mods = mods;
}
void specialKeyDown(ESpecialKey key, EModifierKey mods, bool isRepeat)
{
std::unique_lock<std::mutex> lk(m_mt);
m_cmds.emplace_back(Command::Type::SpecialKeyDown);
m_cmds.back().m_special = key;
m_cmds.back().m_mods = mods;
m_cmds.back().m_isRepeat = isRepeat;
}
void specialKeyUp(ESpecialKey key, EModifierKey mods)
{
std::unique_lock<std::mutex> lk(m_mt);
m_cmds.emplace_back(Command::Type::SpecialKeyUp);
m_cmds.back().m_special = key;
m_cmds.back().m_mods = mods;
}
void modKeyDown(EModifierKey mod, bool isRepeat)
{
std::unique_lock<std::mutex> lk(m_mt);
m_cmds.emplace_back(Command::Type::ModKeyDown);
m_cmds.back().m_mods = mod;
m_cmds.back().m_isRepeat = isRepeat;
}
void modKeyUp(EModifierKey mod)
{
std::unique_lock<std::mutex> lk(m_mt);
m_cmds.emplace_back(Command::Type::ModKeyUp);
m_cmds.back().m_mods = mod;
}
ITextInputCallback* getTextInputCallback() {return m_rec.getTextInputCallback();}
void dispatchEvents()
{
std::unique_lock<std::mutex> lk(m_mt);
bool destroyed = m_destroyed;
bool hasResize = m_hasResize;
if (hasResize)
m_hasResize = false;
SWindowRect latestResize = m_latestResize;
std::vector<Command> cmds;
m_cmds.swap(cmds);
lk.unlock();
if (destroyed)
{
m_rec.destroyed();
return;
}
if (hasResize)
m_rec.resized(latestResize, latestResize);
for (const Command& cmd : cmds)
cmd.dispatch(m_rec);
}
};
}
#endif // BOO_DEFERREDWINDOWEVENTS_HPP

View File

@ -56,6 +56,9 @@ struct IAudioVoice
{ {
virtual ~IAudioVoice() = default; virtual ~IAudioVoice() = default;
/** Set sample rate into voice (may result in audio discontinuities) */
virtual void resetSampleRate(double sampleRate)=0;
/** Reset channel-gains to voice defaults */ /** Reset channel-gains to voice defaults */
virtual void setDefaultMatrixCoefficients()=0; virtual void setDefaultMatrixCoefficients()=0;

View File

@ -8,5 +8,6 @@
#include "inputdev/DualshockPad.hpp" #include "inputdev/DualshockPad.hpp"
#include "graphicsdev/IGraphicsCommandQueue.hpp" #include "graphicsdev/IGraphicsCommandQueue.hpp"
#include "graphicsdev/IGraphicsDataFactory.hpp" #include "graphicsdev/IGraphicsDataFactory.hpp"
#include "DeferredWindowEvents.hpp"
#endif // BOO_HPP #endif // BOO_HPP

View File

@ -18,6 +18,7 @@ AudioVoice::~AudioVoice()
void AudioVoice::setPitchRatio(double ratio) void AudioVoice::setPitchRatio(double ratio)
{ {
m_pitchRatio = ratio;
if (m_dynamicRate) if (m_dynamicRate)
{ {
soxr_error_t err = soxr_set_io_ratio(m_src, ratio, m_parent.mixInfo().m_periodFrames); soxr_error_t err = soxr_set_io_ratio(m_src, ratio, m_parent.mixInfo().m_periodFrames);
@ -52,11 +53,18 @@ AudioVoiceMono::AudioVoiceMono(BaseAudioVoiceEngine& root, IAudioMix& parent, IA
double sampleRate, bool dynamicRate) double sampleRate, bool dynamicRate)
: AudioVoice(root, parent, cb, dynamicRate) : AudioVoice(root, parent, cb, dynamicRate)
{ {
soxr_io_spec_t ioSpec = soxr_io_spec(SOXR_INT16_I, parent.mixInfo().m_sampleFormat); resetSampleRate(sampleRate);
soxr_quality_spec_t qSpec = soxr_quality_spec(SOXR_20_BITQ, dynamicRate ? SOXR_VR : 0); }
void AudioVoiceMono::resetSampleRate(double sampleRate)
{
soxr_delete(m_src);
soxr_io_spec_t ioSpec = soxr_io_spec(SOXR_INT16_I, m_parent.mixInfo().m_sampleFormat);
soxr_quality_spec_t qSpec = soxr_quality_spec(SOXR_20_BITQ, m_dynamicRate ? SOXR_VR : 0);
soxr_error_t err; soxr_error_t err;
m_src = soxr_create(sampleRate, parent.mixInfo().m_sampleRate, 1, m_src = soxr_create(sampleRate, m_parent.mixInfo().m_sampleRate, 1,
&err, &ioSpec, &qSpec, nullptr); &err, &ioSpec, &qSpec, nullptr);
if (err) if (err)
@ -66,6 +74,7 @@ AudioVoiceMono::AudioVoiceMono(BaseAudioVoiceEngine& root, IAudioMix& parent, IA
} }
soxr_set_input_fn(m_src, soxr_input_fn_t(SRCCallback), this, 0); soxr_set_input_fn(m_src, soxr_input_fn_t(SRCCallback), this, 0);
setPitchRatio(m_pitchRatio);
} }
size_t AudioVoiceMono::SRCCallback(AudioVoiceMono* ctx, int16_t** data, size_t frames) size_t AudioVoiceMono::SRCCallback(AudioVoiceMono* ctx, int16_t** data, size_t frames)
@ -146,11 +155,18 @@ AudioVoiceStereo::AudioVoiceStereo(BaseAudioVoiceEngine& root, IAudioMix& parent
double sampleRate, bool dynamicRate) double sampleRate, bool dynamicRate)
: AudioVoice(root, parent, cb, dynamicRate) : AudioVoice(root, parent, cb, dynamicRate)
{ {
soxr_io_spec_t ioSpec = soxr_io_spec(SOXR_INT16_I, parent.mixInfo().m_sampleFormat); resetSampleRate(sampleRate);
soxr_quality_spec_t qSpec = soxr_quality_spec(SOXR_20_BITQ, dynamicRate ? SOXR_VR : 0); }
void AudioVoiceStereo::resetSampleRate(double sampleRate)
{
soxr_delete(m_src);
soxr_io_spec_t ioSpec = soxr_io_spec(SOXR_INT16_I, m_parent.mixInfo().m_sampleFormat);
soxr_quality_spec_t qSpec = soxr_quality_spec(SOXR_20_BITQ, m_dynamicRate ? SOXR_VR : 0);
soxr_error_t err; soxr_error_t err;
m_src = soxr_create(sampleRate, parent.mixInfo().m_sampleRate, 2, m_src = soxr_create(sampleRate, m_parent.mixInfo().m_sampleRate, 2,
&err, &ioSpec, &qSpec, nullptr); &err, &ioSpec, &qSpec, nullptr);
if (!m_src) if (!m_src)
@ -160,6 +176,7 @@ AudioVoiceStereo::AudioVoiceStereo(BaseAudioVoiceEngine& root, IAudioMix& parent
} }
soxr_set_input_fn(m_src, soxr_input_fn_t(SRCCallback), this, 0); soxr_set_input_fn(m_src, soxr_input_fn_t(SRCCallback), this, 0);
setPitchRatio(m_pitchRatio);
} }
size_t AudioVoiceStereo::SRCCallback(AudioVoiceStereo* ctx, int16_t** data, size_t frames) size_t AudioVoiceStereo::SRCCallback(AudioVoiceStereo* ctx, int16_t** data, size_t frames)

View File

@ -33,7 +33,8 @@ protected:
IAudioVoiceCallback* m_cb; IAudioVoiceCallback* m_cb;
/* Sample-rate converter */ /* Sample-rate converter */
soxr_t m_src; soxr_t m_src = nullptr;
double m_pitchRatio = 1.0;
bool m_dynamicRate; bool m_dynamicRate;
/* Running bool */ /* Running bool */
@ -56,6 +57,7 @@ public:
class AudioVoiceMono : public AudioVoice class AudioVoiceMono : public AudioVoice
{ {
AudioMatrixMono m_matrix; AudioMatrixMono m_matrix;
void resetSampleRate(double sampleRate);
static size_t SRCCallback(AudioVoiceMono* ctx, static size_t SRCCallback(AudioVoiceMono* ctx,
int16_t** data, size_t requestedLen); int16_t** data, size_t requestedLen);
@ -75,6 +77,7 @@ public:
class AudioVoiceStereo : public AudioVoice class AudioVoiceStereo : public AudioVoice
{ {
AudioMatrixStereo m_matrix; AudioMatrixStereo m_matrix;
void resetSampleRate(double sampleRate);
static size_t SRCCallback(AudioVoiceStereo* ctx, static size_t SRCCallback(AudioVoiceStereo* ctx,
int16_t** data, size_t requestedLen); int16_t** data, size_t requestedLen);