cleaned up dispatcher
authorCharles McGarvey <chazmcgarvey@brokenzipper.com>
Mon, 31 Aug 2009 21:39:39 +0000 (15:39 -0600)
committerCharles McGarvey <chazmcgarvey@brokenzipper.com>
Mon, 31 Aug 2009 21:39:39 +0000 (15:39 -0600)
extra/yoink.ebuild
src/Moof/Camera.cc
src/Moof/Camera.hh
src/Moof/Dispatcher.cc
src/Moof/Dispatcher.hh
src/Moof/Sound.cc
src/Moof/Sound.hh
src/Moof/Texture.cc
src/YoinkApp.cc
src/YoinkApp.hh

index 52e26c7890864305409f4de5b5635cb0392d6ed9..932251e561893ffbe8bfb6e2bad401d350f18a6b 100644 (file)
@@ -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"
index b38dd143cf04a51bc4dc30068a322ea77e073a42..376e2c5a4ff5398ea9f1c388f23ce4cc0bbd5000 100644 (file)
@@ -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)
        {
index 63d00749555a13c2052027dc8b0bb069e4856ecc..24632a53af82f88038b7d03df22a5039574a48ba 100644 (file)
@@ -70,7 +70,7 @@ public:
                return frustum_;
        }
 
-       void adjustFromInput(const Event& event);
+       void handleEvent(const Event& event);
        void update(Scalar t, Scalar dt);
 
 private:
index e0d3d21bb839668593629818e281c7ff1f5ed9b3..9e652a37a8983614010cf974f92172c310caae88 100644 (file)
@@ -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<Dispatcher::Handler,std::string>          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<HandlerIter,HandlerIter> 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<std::string,Dispatcher::DispatcherImpl::Callback>
-               callbackPair(message, Dispatcher::DispatcherImpl::Callback(id, callback));
-
-       std::pair<Handler,std::string> 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<Dispatcher::DispatcherImpl::HandlerIter,Dispatcher::DispatcherImpl::HandlerIter>
-               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<Dispatcher::DispatcherImpl::CallbackIter,Dispatcher::DispatcherImpl::CallbackIter>
+       std::pair<Impl::CallbackIter,Impl::CallbackIter>
                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);
index ec143b46fdce105a7021f79cc4a2ecb1027144f4..5747f8581ddbc3622eed9be8ce5c3f0eebd03293 100644 (file)
@@ -59,7 +59,7 @@ class Dispatcher : public Singleton<Dispatcher>
 {
 public:
        typedef void* Handler;
-       typedef boost::function<void(const Notification&)> Function;
+       typedef boost::function<void(const Notification*)> 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<DispatcherImpl> impl_;
+       class Impl;
+       boost::shared_ptr<Impl> impl_;
 };
 
 
index 9a632ebf3ace404b31787b16f227c70fecba4d60..59acfaa9af269886ec0cc34a8286671751f75505 100644 (file)
@@ -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>
        {
                Buffer(const std::string& name) :
-                       Mippleton<Buffer>(name),
-                       object(0)
-               {}
+                       Mippleton<Buffer>(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>       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);
 }
 
 
index cca7dc7e637fd2b9cd61fe3ecac024db9d03a9e6..23979db4aa019423573fbb8e73a59f5a49a6cc89 100644 (file)
@@ -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);
 
index e8f5d86d1f2e65fd85d413c5b93b26bfcedc6ac3..8aa66c4f1ec7c64c95b3d35016f4ef1e9068593d 100644 (file)
@@ -78,7 +78,7 @@ class Texture::Impl : public Mippleton<Impl>
         * to cache it if the client has plenty of RAM.
         */
 
-       void contextRecreated(const Notification& note)
+       void contextRecreated(const Notification* note)
        {
                object_ = globalObject_ = 0;
                uploadToGL();
index a1c2dbbf8133f273e2aca98efdf2dc3f8db133ef..bf6d71ab8d462d81507ee6525be954287111a51e 100644 (file)
@@ -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:
index 1613707730ea0d6a3efc7d499556d73d162e65a5..b70cb4d3a289817729433a6cad940eb8b696efe1 100644 (file)
@@ -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;
This page took 0.034832 seconds and 4 git commands to generate.