]> Dogcows Code - chaz/yoink/blobdiff - src/Animation.cc
sockets documentation and cleanup
[chaz/yoink] / src / Animation.cc
index 598361bf97143c28cb1ca2d78d495692d50f6d31..bd31f9b5dc26a8248952d8d7b5d5028bc6e45a63 100644 (file)
@@ -1,35 +1,19 @@
 
-/*******************************************************************************
-
- Copyright (c) 2009, Charles McGarvey
- All rights reserved.
- Redistribution   and   use  in  source  and  binary  forms,  with  or  without
- modification, are permitted provided that the following conditions are met:
-   * Redistributions  of  source  code  must retain the above copyright notice,
-     this list of conditions and the following disclaimer.
-   * Redistributions  in binary form must reproduce the above copyright notice,
-     this  list of conditions and the following disclaimer in the documentation
-     and/or other materials provided with the distribution.
- THIS  SOFTWARE  IS  PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- AND  ANY  EXPRESS  OR  IMPLIED  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED.  IN  NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- FOR  ANY  DIRECT,  INDIRECT,  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES  (INCLUDING,  BUT  NOT  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- SERVICES;  LOSS  OF  USE,  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- CAUSED  AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- OR  TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-*******************************************************************************/
+/*]  Copyright (c) 2009-2010, Charles McGarvey  [**************************
+**]  All rights reserved.
+*
+* vi:ts=4 sw=4 tw=75
+*
+* Distributable under the terms and conditions of the 2-clause BSD license;
+* see the file COPYING for a complete text of the license.
+*
+**************************************************************************/
 
 #include <map>
 #include <vector>
 
-#include <Moof/Library.hh>
+#include <Moof/Error.hh>
+#include <Moof/Manager.hh>
 #include <Moof/Log.hh>
 #include <Moof/Script.hh>
 
 
 
 /**
- * The collection of nested animation classes.  The animation implementation
- * consists of an Impl class which is allocated and initialized with the
- * interface object.  This class contains the specific fields which are required
- * to run a single instance of an animation.  The sequence data is loaded in a
- * different class which can be shared amongst multiple animation implementation
- * instances.
+ * The collection of nested animation classes.  The animation
+ * implementation consists of an Impl class which is allocated and
+ * initialized with the interface object.  This class contains the specific
+ * fields which are required to run a single instance of an animation.  The
+ * sequence data is loaded in a different class which can be shared amongst
+ * multiple animation implementation instances.
  */
 
 class Animation::Impl
 {
-       friend class Animation;
+public:
 
        /**
-        * Contains "global" animation data for the various animations which get
-        * loaded.  This is a mippleton, so it will be shared amongst any animation
-        * which wants to use these loaded sequences.
+        * Contains "global" animation data for the various animations which
+        * get loaded.  This is a mippleton, so it will be shared amongst any
+        * animation which wants to use these loaded sequences.
         */
 
-       class Data : public Mf::Library<Data>
+       class Data : public Mf::Manager<Data>
        {
-               friend class Impl;
-               friend class Mf::Library<Data>;
+       public:
 
                /**
-                * A frame of an animation sequence.  A frame is merely an index which
-                * presumably represents a "slide" or tile which should be displayed,
-                * and the duration that is how long the slide will be shown.
+                * A frame of an animation sequence.  A frame is merely an index
+                * which presumably represents a "slide" or tile which should be
+                * displayed, and the duration that is how long the slide will be
+                * shown.
                 */
 
                class Frame
                {
-                       friend class Impl;
+               public:
 
                        unsigned        mIndex;                                 ///< Frame index.
                        Mf::Scalar      mDuration;                              ///< Frame duration.
 
                        /**
-                        * Construction is initialization.  The frame data is loaded from a
-                        * frame map which is probably loaded within an animation file.
+                        * Construction is initialization.  The frame data is loaded
+                        * from a frame map which is probably loaded within an
+                        * animation file.
                         */
                
-                       Frame(Mf::Script& script, Mf::Script::Slot table) :
+                       Frame(const Mf::Script::Slot& table) :
                                mIndex(0),
                                mDuration(1.0)
                        {
-                               table.pushField("index");
-                               script[-1].get(mIndex);
-                               script.pop();
-
-                               table.pushField("duration");
-                               script[-1].get(mDuration);
-                               script.pop();
+                               table.get(mIndex,    "index");
+                               table.get(mDuration, "duration");
                        }
                };
 
 
                /**
-                * A sequence is just a few attributes and a list of frames in the order
-                * that they should be played.
+                * A sequence is just a few attributes and a list of frames in the
+                * order that they should be played.
                 */
 
-               struct Sequence
+               class Sequence
                {
-                       friend class Impl;
+               public:
 
-                       std::vector<Frame>      mFrames;                ///< List of frames.
-                       Mf::Scalar                      mDelay;                 ///< Scale frame durations.
-                       bool                            mLoop;                  ///< Does the sequence repeat?
-                       std::string                     mNext;                  ///< Next sequence name.
+                       std::vector<Frame>      mFrames;        ///< List of frames.
+                       Mf::Scalar                      mDelay;         ///< Scale frame durations.
+                       bool                            mLoop;          ///< Does the sequence repeat?
+                       std::string                     mNext;          ///< Next sequence name.
 
                        /**
-                        * Construction is initialization.  The constructor loads sequence
-                        * data from the sequence map, presumably loaded from an animation
-                        * file.  The rest of the loading takes place in the frame's
-                        * constructor which loads each individual frame.
+                        * Construction is initialization.  The constructor loads
+                        * sequence data from the sequence map, presumably loaded from
+                        * an animation file.  The rest of the loading takes place in
+                        * the frame's constructor which loads each individual frame.
                         */
 
-                       Sequence(Mf::Script& script, Mf::Script::Slot table) :
+                       Sequence(const Mf::Script::Slot& table) :
                                mDelay(0.0),
                                mLoop(true)
                        {
-                               table.pushField("delay");
-                               script[-1].get(mDelay);
-                               script.pop();
-
-                               table.pushField("loop");
-                               script[-1].get(mLoop);
-                               script.pop();
-
-                               table.pushField("next");
-                               script[-1].get(mNext);
-                               script.pop();
+                               table.get(mDelay, "delay");
+                               table.get(mLoop,  "loop");
+                               table.get(mNext,  "next");
 
                                // TODO - sequence class/type not yet implemented
 
-                               table.pushField("frames");
-                               Mf::Script::Slot frameTable = script.getTop();
+                               Mf::Script::Slot frameTable = table.pushField("frames");
                                if (frameTable.isTable())
                                {
-                                       Mf::Script::Slot top = script[-1];
-                                       int index = 1;
-
-                                       for (;;)
+                                       int max = frameTable.length();
+                                       for (int index = 1; index <= max; ++index)
                                        {
-                                               script.push(index);
-                                               frameTable.pushField();
-
-                                               if (top.isTable()) mFrames.push_back(Frame(script, top));
-                                               else               break;
-
-                                               ++index;
+                                               Mf::Script::Slot top = frameTable.pushField(index);
+
+                                               if (top.isTable())
+                                               {
+                                                       mFrames.push_back(Frame(top));
+                                               }
+                                               else
+                                               {
+                                                       Mf::logWarning << "invalid frame at index "
+                                                                                  << index << std::endl;
+                                               }
                                        }
                                }
-                               script.pop();
+                               frameTable.remove();
                        }
                };
 
 
                /**
-                * Starts loading a file with animation data.  Such a file is formatted
-                * as a map of named sequences.   The sequence constructor loads each
-                * individual sequence.
+                * Starts loading a file with animation data.  Such a file is
+                * formatted as a map of named sequences.   The sequence
+                * constructor loads each individual sequence.
                 */
 
-               void loadFromFile()
+               void init(const std::string& name)
                {
                        Mf::Script script;
-                       std::string filePath = Animation::getPath(getName());
+                       std::string path(name);
+                       
+                       if (!Animation::getPath(path))
+                       {
+                               Mf::Error(Mf::Error::RESOURCE_NOT_FOUND).raise();
+                       }
 
                        script.importBaseLibrary();
                        importLogFunctions(script);
                        importAnimationBindings(script);
 
-                       if (script.doFile(filePath) != Mf::Script::SUCCESS)
+                       if (script.doFile(path) != Mf::Script::SUCCESS)
                        {
                                std::string str;
                                script[-1].get(str);
@@ -186,8 +164,7 @@ class Animation::Impl
                        std::string nameStr;
                        name.get(nameStr);
 
-                       sequences.insert(std::pair<std::string,Sequence>(nameStr,
-                                               Sequence(script, table)));
+                       mSequences.insert(std::make_pair(nameStr, Sequence(table)));
 
                        return 0;
                }
@@ -196,30 +173,20 @@ class Animation::Impl
                void importAnimationBindings(Mf::Script& script)
                {
                        script.importFunction("DefineSequence",
-                                       boost::bind(&Data::defineSequence, this, _1));
-
-                       script.push(1); script.set("ATTACK");
-                       script.push(2); script.set("CHARGE");
-                       script.push(3); script.set("FLY");
-                       script.push(4); script.set("HIT");
-                       script.push(5); script.set("JUMP");
-                       script.push(6); script.set("RUN");
-                       script.push(7); script.set("STAND");
+                                                                 boost::bind(&Data::defineSequence,
+                                                                                         this, _1));
+
+                       script.globals().setField("ATTACK",     1);
+                       script.globals().setField("CHARGE",     2);
+                       script.globals().setField("FLY",        3);
+                       script.globals().setField("HIT",        4);
+                       script.globals().setField("JUMP",       5);
+                       script.globals().setField("RUN",        6);
+                       script.globals().setField("STAND",      7);
                }
 
 
-               /**
-                * Construction is initialization.  The animation class data container
-                * registers itself as a mippleton and then loads the animation data.
-                */
-
-               explicit Data(const std::string& name) :
-                       Mf::Library<Data>(name)
-               {
-                       loadFromFile();
-               }
-
-               std::map<std::string,Sequence> sequences;               ///< List of sequences.
+               std::map<std::string,Sequence> mSequences;      ///< List of sequences.
        };
 
 
@@ -237,25 +204,25 @@ class Animation::Impl
 
 
        /**
-        * Sets up the animation classes to "play" a named sequence.  If another
-        * sequence was active, it will be replaced.  Future updates will progress
-        * the new sequence.
+        * Sets up the animation classes to "play" a named sequence.  If
+        * another sequence was active, it will be replaced.  Future updates
+        * will progress the new sequence.
         */
 
        void startSequence(const std::string& name)
        {
                std::map<std::string,Data::Sequence>::iterator it;
 
-               it = mData->sequences.find(name);
+               it = mData->mSequences.find(name);
 
-               if (it != mData->sequences.end())
+               if (it != mData->mSequences.end())
                {
                        mCurrentSequence = &(*it).second;
                        mFrameCounter = 0;
                        mFrameIndex = mCurrentSequence->mFrames[0].mIndex;
                        mTimeAccum = 0.0;
                        mFrameDuration = mCurrentSequence->mDelay *
-                               mCurrentSequence->mFrames[0].mDuration;
+                                                        mCurrentSequence->mFrames[0].mDuration;
                }
        }
 
@@ -263,42 +230,41 @@ class Animation::Impl
         * Updates or progresses the animation sequence.  If the time interval
         * surpasses the duration of the current frame, a new frame becomes the
         * current frame.  If the last frame of a sequence expires, the active
-        * sequence will switch automatically to the designated "next" sequence, or
-        * if none is specified but the sequence is set to loop, the first frame of
-        * the sequence will become the current frame, and the animation essentially
-        * starts over again.
+        * sequence will switch automatically to the designated "next"
+        * sequence, or if none is specified but the sequence is set to loop,
+        * the first frame of the sequence will become the current frame, and
+        * the animation essentially starts over again.
         */
 
        void update(Mf::Scalar t, Mf::Scalar dt)
        {
-               if (mCurrentSequence)
-               {
-                       mTimeAccum += dt;
+               if (!mCurrentSequence) return;
+
+               mTimeAccum += dt;
 
-                       if (mTimeAccum >= mFrameDuration)
+               if (mTimeAccum >= mFrameDuration)
+               {
+                       if (++mFrameCounter >= mCurrentSequence->mFrames.size())
                        {
-                               if (++mFrameCounter >= mCurrentSequence->mFrames.size())
+                               if (!mCurrentSequence->mNext.empty())
                                {
-                                       if (!mCurrentSequence->mNext.empty())
-                                       {
-                                               startSequence(mCurrentSequence->mNext);
-                                       }
-                                       else if (mCurrentSequence->mLoop)
-                                       {
-                                               mFrameCounter = 0;
-                                       }
-                                       else
-                                       {
-                                               mFrameCounter--;
-                                               mCurrentSequence = 0;
-                                       }
+                                       startSequence(mCurrentSequence->mNext);
+                               }
+                               else if (mCurrentSequence->mLoop)
+                               {
+                                       mFrameCounter = 0;
+                               }
+                               else
+                               {
+                                       mFrameCounter--;
+                                       mCurrentSequence = 0;
                                }
-
-                               mFrameIndex = mCurrentSequence->mFrames[mFrameCounter].mIndex;
-                               mTimeAccum = mFrameDuration - mTimeAccum;
-                               mFrameDuration = mCurrentSequence->mDelay *
-                                       mCurrentSequence->mFrames[mFrameCounter].mDuration;
                        }
+
+                       mFrameIndex = mCurrentSequence->mFrames[mFrameCounter].mIndex;
+                       mTimeAccum = mFrameDuration - mTimeAccum;
+                       mFrameDuration = mCurrentSequence->mDelay *
+                               mCurrentSequence->mFrames[mFrameCounter].mDuration;
                }
        }
 
@@ -342,15 +308,12 @@ unsigned Animation::getFrame() const
 
 
 /**
- * Specialized search location for animation files.  They can be found in the
- * "animations" subdirectory of any of the searched directories.
+ * Specialized search location for animation files.  They can be found in
+ * the "animations" subdirectory of any of the search directories.
  */
 
-std::string Animation::getPath(const std::string& name)
+bool Animation::getPath(std::string& name)
 {
-       return Mf::Resource::getPath("animations/" + name + ".lua");
+       return Mf::Resource::getPath(name, "animations/", "lua");
 }
 
-
-/** vim: set ts=4 sw=4 tw=80: *************************************************/
-
This page took 0.031163 seconds and 4 git commands to generate.