From 4701bf580b75a7d77a460c6f14f9fc31fb109bbb Mon Sep 17 00:00:00 2001 From: Charles McGarvey Date: Mon, 31 Aug 2009 15:39:39 -0600 Subject: [PATCH] cleaned up dispatcher --- extra/yoink.ebuild | 3 +- src/Moof/Camera.cc | 2 +- src/Moof/Camera.hh | 2 +- src/Moof/Dispatcher.cc | 100 ++++++++++++++++++++-------------------- src/Moof/Dispatcher.hh | 9 ++-- src/Moof/Sound.cc | 102 +++++++++++++++++++++++++++++++++++------ src/Moof/Sound.hh | 4 ++ src/Moof/Texture.cc | 2 +- src/YoinkApp.cc | 14 +++++- src/YoinkApp.hh | 3 +- 10 files changed, 164 insertions(+), 77 deletions(-) diff --git a/extra/yoink.ebuild b/extra/yoink.ebuild index 52e26c7..932251e 100644 --- a/extra/yoink.ebuild +++ b/extra/yoink.ebuild @@ -20,7 +20,8 @@ RDEPEND="media-libs/libsdl[opengl] media-libs/sdl-image[png] virtual/opengl media-libs/sdl-sound[mikmod, vorbis] - media-libs/openal" + media-libs/openal + media-libs/freealut" DEPEND="${RDEPEND} dev-libs/boost dev-util/pkgconfig" diff --git a/src/Moof/Camera.cc b/src/Moof/Camera.cc index b38dd14..376e2c5 100644 --- a/src/Moof/Camera.cc +++ b/src/Moof/Camera.cc @@ -84,7 +84,7 @@ void Camera::lookAt(const Vector3& point) calculateSecondary(); } -void Camera::adjustFromInput(const Event& event) +void Camera::handleEvent(const Event& event) { switch (event.type) { diff --git a/src/Moof/Camera.hh b/src/Moof/Camera.hh index 63d0074..24632a5 100644 --- a/src/Moof/Camera.hh +++ b/src/Moof/Camera.hh @@ -70,7 +70,7 @@ public: return frustum_; } - void adjustFromInput(const Event& event); + void handleEvent(const Event& event); void update(Scalar t, Scalar dt); private: diff --git a/src/Moof/Dispatcher.cc b/src/Moof/Dispatcher.cc index e0d3d21..9e652a3 100644 --- a/src/Moof/Dispatcher.cc +++ b/src/Moof/Dispatcher.cc @@ -37,14 +37,14 @@ namespace Mf { Notification::~Notification() {} -class Dispatcher::DispatcherImpl +struct Dispatcher::Impl { -public: - DispatcherImpl() : id(1) {} + Impl() : + id(1) {} - Dispatcher::Handler getNewHandlerID() + Dispatcher::Handler getNewHandler() { - id += 4; + id += 2; return (Dispatcher::Handler)id; } @@ -55,78 +55,76 @@ public: typedef std::multimap HandlerLookup; typedef HandlerLookup::iterator HandlerIter; - unsigned long long id; - CallbackLookup callbacks; - HandlerLookup handlers; + inline Handler addHandler(const std::string& message, + const Function& callback, Handler id) + { + callbacks.insert(std::make_pair(message, std::make_pair(id, callback))); + handlers.insert(std::make_pair(id, message)); + + return id; + } + + inline void removeHandler(Handler id) + { + std::pair matching(handlers.equal_range(id)); + + for (HandlerIter it = matching.first; it != matching.second; ++it) + { + CallbackIter first = callbacks.find((*it).second); + CallbackIter last = callbacks.end(); + + for (CallbackIter jt = first; jt != last; ++jt) + { + if (((*jt).second).first == id) + { + callbacks.erase(jt); + break; + } + } + } + + handlers.erase(id); + } + + unsigned long id; + + CallbackLookup callbacks; + HandlerLookup handlers; }; Dispatcher::Dispatcher() : - impl_(new Dispatcher::DispatcherImpl) {} + impl_(new Dispatcher::Impl) {} -// TODO these methods are ugly - Dispatcher::Handler Dispatcher::addHandler(const std::string& message, const Function& callback) { - return addHandler(message, callback, impl_->getNewHandlerID()); + return addHandler(message, callback, impl_->getNewHandler()); } Dispatcher::Handler Dispatcher::addHandler(const std::string& message, const Function& callback, Handler id) { - std::pair - callbackPair(message, Dispatcher::DispatcherImpl::Callback(id, callback)); - - std::pair handlerPair(id, message); - - impl_->callbacks.insert(callbackPair); - impl_->handlers.insert(handlerPair); - - return id; + // pass through + return impl_->addHandler(message, callback, id); } void Dispatcher::removeHandler(Handler id) { - std::pair - handlers(impl_->handlers.equal_range(id)); - - Dispatcher::DispatcherImpl::HandlerIter it; - for (it = handlers.first; it != handlers.second; ++it) - { - Dispatcher::DispatcherImpl::CallbackIter first = impl_->callbacks.find((*it).second); - Dispatcher::DispatcherImpl::CallbackIter last = impl_->callbacks.end(); - - Dispatcher::DispatcherImpl::CallbackIter jt; - for (jt = first; jt != last; ++jt) - { - if (((*jt).second).first == id) - { - impl_->callbacks.erase(jt); - break; - } - } - } - - impl_->handlers.erase(id); + // pass through + return impl_->removeHandler(id); } -void Dispatcher::dispatch(const std::string& message) -{ - dispatch(message, Notification()); -} - -void Dispatcher::dispatch(const std::string& message, const Notification& param) +void Dispatcher::dispatch(const std::string& message, const Notification* param) { - std::pair + std::pair callbacks(impl_->callbacks.equal_range(message)); - Dispatcher::DispatcherImpl::CallbackIter it; - for (it = callbacks.first; it != callbacks.second; ++it) + for (Impl::CallbackIter it = callbacks.first; it != callbacks.second; ++it) { Function callback = ((*it).second).second; callback(param); diff --git a/src/Moof/Dispatcher.hh b/src/Moof/Dispatcher.hh index ec143b4..5747f85 100644 --- a/src/Moof/Dispatcher.hh +++ b/src/Moof/Dispatcher.hh @@ -59,7 +59,7 @@ class Dispatcher : public Singleton { public: typedef void* Handler; - typedef boost::function Function; + typedef boost::function Function; Dispatcher(); @@ -69,12 +69,11 @@ public: void removeHandler(Handler id); - void dispatch(const std::string& message); - void dispatch(const std::string& message, const Notification& param); + void dispatch(const std::string& message, const Notification* param = 0); private: - class DispatcherImpl; - boost::shared_ptr impl_; + class Impl; + boost::shared_ptr impl_; }; diff --git a/src/Moof/Sound.cc b/src/Moof/Sound.cc index 9a632eb..59acfaa 100644 --- a/src/Moof/Sound.cc +++ b/src/Moof/Sound.cc @@ -36,6 +36,7 @@ #include "Mippleton.hh" #include "Sound.hh" +#define BUFFER_SIZE (8 * 4096) namespace Mf { @@ -60,20 +61,26 @@ struct Sound::Impl struct Buffer : public Mippleton { Buffer(const std::string& name) : - Mippleton(name), - object(0) - {} + Mippleton(name) + { + objects[0] = 0; + objects[1] = 0; + } ~Buffer() { - alDeleteBuffers(1, &object); + alDeleteBuffers(2, objects); + + if (sound) Sound_FreeSample(sound); } + + void loadFromFile(const std::string& filePath, bool stream) { - if (object != 0) return; + if (objects[0] != 0) return; - Sound_Sample* sound = Sound_NewSampleFromFile(filePath.c_str(), - NULL, 8096); + sound = Sound_NewSampleFromFile(filePath.c_str(), + NULL, BUFFER_SIZE); if (!sound) { @@ -81,25 +88,49 @@ struct Sound::Impl exit(1); } + if (!stream) + { unsigned decoded = Sound_DecodeAll(sound); if (decoded == 0) { std::cout << "decoded no bytes" << std::endl; exit(1); } + + alGenBuffers(2, objects); + alBufferData(objects[0], getAudioFormat(sound->actual), sound->buffer, + sound->buffer_size, sound->actual.rate); std::cerr << "buffer size: " << sound->buffer_size << std::endl; std::cerr << "channels: " << (int)sound->actual.channels << std::endl; std::cerr << "format: " << sound->actual.format << std::endl; std::cerr << "frequency: " << sound->actual.rate << std::endl; - alGenBuffers(1, &object); - alBufferData(object, getAudioFormat(sound->actual), sound->buffer, - sound->buffer_size, sound->actual.rate); - Sound_FreeSample(sound); + sound = 0; + } + else + { + std::cerr << "buffer size: " << sound->buffer_size << std::endl; + std::cerr << "channels: " << (int)sound->actual.channels << std::endl; + std::cerr << "format: " << sound->actual.format << std::endl; + std::cerr << "frequency: " << sound->actual.rate << std::endl; + alGenBuffers(2, objects); + } + } + + bool stream(ALuint buffer) + { + int bytes = Sound_Decode(sound); + + if (bytes < BUFFER_SIZE) return false; + + alBufferData(buffer, getAudioFormat(sound->actual), sound->buffer, + sound->buffer_size, sound->actual.rate); + return false; } - ALuint object; + Sound_Sample* sound; + ALuint objects[2]; //ALfloat location[] = {0.0f, 0.0f, 0.0f}; //ALfloat location2[] = {0.0f, 0.0f, 0.0f}; @@ -120,12 +151,24 @@ struct Sound::Impl ALfloat location[] = {0.0f, 0.0f, 0.0f}; alGenSources(1, &source_); - alSourcei(source_, AL_BUFFER, buffer_->object); + alSourcef(source_, AL_PITCH, 1.0f); alSourcef(source_, AL_GAIN, 1.0f); alSourcefv(source_, AL_POSITION, location); alSourcefv(source_, AL_VELOCITY, location); alSourcei(source_, AL_LOOPING, AL_FALSE); + + if (!stream) + { + alSourcei(source_, AL_BUFFER, buffer_->objects[0]); + } + else + { + buffer_->stream(buffer_->objects[0]); + buffer_->stream(buffer_->objects[1]); + + alSourceQueueBuffers(source_, 2, buffer_->objects); + } } ~Impl() @@ -136,11 +179,24 @@ struct Sound::Impl void update() { + int finished = 0; + + alGetSourcei(source_, AL_BUFFERS_PROCESSED, &finished); + + while (finished-- > 0) + { + ALuint buffer; + + alSourceUnqueueBuffers(source_, 1, &buffer); + buffer_->stream(buffer); + alSourceQueueBuffers(source_, 1, &buffer); + } } boost::shared_ptr buffer_; ALuint source_; + bool playing; }; @@ -151,8 +207,26 @@ Sound::Sound(const std::string& name) : void Sound::play() { - alSourceRewind(impl_->source_); + //alSourceRewind(impl_->source_); alSourcePlay(impl_->source_); + impl_->playing = true; +} + +void Sound::pause() +{ + alSourcePause(impl_->source_); + impl_->playing = false; +} + +void Sound::togglePlayPause() +{ + if (impl_->playing) pause(); + else play(); +} + +void Sound::setGain(Scalar gain) +{ + alSourcef(impl_->source_, AL_GAIN, gain); } diff --git a/src/Moof/Sound.hh b/src/Moof/Sound.hh index cca7dc7..23979db 100644 --- a/src/Moof/Sound.hh +++ b/src/Moof/Sound.hh @@ -51,6 +51,10 @@ public: Sound(const std::string& name); void play(); + void pause(); + void togglePlayPause(); + + void setGain(Scalar gain); static std::string getPath(const std::string& name); diff --git a/src/Moof/Texture.cc b/src/Moof/Texture.cc index e8f5d86..8aa66c4 100644 --- a/src/Moof/Texture.cc +++ b/src/Moof/Texture.cc @@ -78,7 +78,7 @@ class Texture::Impl : public Mippleton * to cache it if the client has plenty of RAM. */ - void contextRecreated(const Notification& note) + void contextRecreated(const Notification* note) { object_ = globalObject_ = 0; uploadToGL(); diff --git a/src/YoinkApp.cc b/src/YoinkApp.cc index a1c2dbb..bf6d71a 100644 --- a/src/YoinkApp.cc +++ b/src/YoinkApp.cc @@ -111,6 +111,8 @@ YoinkApp::YoinkApp(int argc, char* argv[]) : boost::bind(&YoinkApp::contextRecreated, this, _1), this); setupGL(); + Mf::Scalar fade[2] = {0.0, 1.0}; + musicFade.init(fade, 0.0); music.play(); state = 0.0; @@ -176,7 +178,7 @@ void YoinkApp::setupGL() //glLineWidth(10.0f); } -void YoinkApp::contextRecreated(const Mf::Notification& note) +void YoinkApp::contextRecreated(const Mf::Notification* note) { // Whenever the context and a new one created, it probably won't contain our // state so we need to set that up again. @@ -187,6 +189,10 @@ void YoinkApp::contextRecreated(const Mf::Notification& note) void YoinkApp::update(Mf::Scalar t, Mf::Scalar dt) { //dt *= 0.2; + + musicFade.update(dt); + music.update(t, dt); + music.setGain(musicFade.getValue()); fadeIn.update(dt); @@ -404,6 +410,10 @@ void YoinkApp::handleEvent(const Mf::Event& event) { testScene->refresh(); } + else if (event.key.keysym.sym == SDLK_p) + { + music.togglePlayPause(); + } else if (event.key.keysym.sym == SDLK_l) { getVideo().toggleCursorGrab(); @@ -415,7 +425,7 @@ void YoinkApp::handleEvent(const Mf::Event& event) case SDL_MOUSEMOTION: case SDL_MOUSEBUTTONDOWN: - camera.adjustFromInput(event); + camera.handleEvent(event); break; case SDL_QUIT: diff --git a/src/YoinkApp.hh b/src/YoinkApp.hh index 1613707..b70cb4d 100644 --- a/src/YoinkApp.hh +++ b/src/YoinkApp.hh @@ -67,8 +67,9 @@ private: * Set OpenGL to a state we can know and depend on. */ void setupGL(); - void contextRecreated(const Mf::Notification& note); + void contextRecreated(const Mf::Notification* note); + Mf::Lerps musicFade; Mf::SoundStream music; CharacterPtr heroine; -- 2.43.0