-/*******************************************************************************
-
- 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 <stdexcept>
#include <vector>
-#include <Moof/Library.hh>
-#include <Moof/Log.hh>
-#include <Moof/Script.hh>
+#include <moof/manager.hh>
+#include <moof/log.hh>
+#include <moof/script.hh>
#include "Animation.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
+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 moof::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.
+ moof::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::Value table) :
+ Frame(const moof::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.
+ moof::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::Value table) :
+ Sequence(const moof::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::Value frameTable = script.getTop();
- if (frameTable.isTable())
+ moof::script::slot frameTable = table.push_field("frames");
+ if (frameTable.is_table())
{
- Mf::Script::Value 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;
+ moof::script::slot top = frameTable.push_field(index);
+
+ if (top.is_table())
+ {
+ mFrames.push_back(Frame(top));
+ }
+ else
+ {
+ moof::log_warning << "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());
+ moof::script script;
+ std::string path(name);
+
+ if (!resource::find(path))
+ {
+ throw std::runtime_error("cannot find resource " + name);
+ }
- script.importBaseLibrary();
- importLogPrintFunction(script);
+ script.import_base_library();
+ moof::log::import(script);
importAnimationBindings(script);
- if (script.doFile(filePath) != Mf::Script::SUCCESS)
+ if (script.do_file(path) != moof::script::success)
{
std::string str;
script[-1].get(str);
- Mf::logScript("%s", str.c_str());
+ moof::log_warning(str);
}
}
- int defineSequence(Mf::Script& script)
+ int defineSequence(moof::script& script)
{
- Mf::Script::Value name = script[1].requireString();
- Mf::Script::Value table = script[2].requireTable();
+ moof::script::slot name = script[1].require_string();
+ moof::script::slot table = script[2].require_table();
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;
}
- void importAnimationBindings(Mf::Script& script)
+ void importAnimationBindings(moof::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");
+ script.import_function("DefineSequence",
+ boost::bind(&Data::defineSequence,
+ this, _1));
+
+ script.globals().set_field("ATTACK", 1);
+ script.globals().set_field("CHARGE", 2);
+ script.globals().set_field("FLY", 3);
+ script.globals().set_field("HIT", 4);
+ script.globals().set_field("JUMP", 5);
+ script.globals().set_field("RUN", 6);
+ script.globals().set_field("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.
};
* Construction is intialization.
*/
- Impl(const std::string& name) :
- mData(Data::getInstance(name)),
+ impl(const std::string& name) :
+ mData(Data::instance(name)),
mCurrentSequence(0),
mFrameCounter(0),
mFrameIndex(0),
/**
- * 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;
}
}
* 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)
+ void update(moof::scalar t, moof::scalar dt)
{
- if (mCurrentSequence)
- {
- mTimeAccum += dt;
+ if (!mCurrentSequence) return;
- if (mTimeAccum >= mFrameDuration)
+ mTimeAccum += dt;
+
+ 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;
}
}
Data::Sequence* mCurrentSequence; ///< Active sequence.
unsigned mFrameCounter; ///< Current frame.
unsigned mFrameIndex; ///< Index of current frame.
- Mf::Scalar mTimeAccum; ///< Time accumulation.
- Mf::Scalar mFrameDuration; ///< Scaled frame duration.
+ moof::scalar mTimeAccum; ///< Time accumulation.
+ moof::scalar mFrameDuration; ///< Scaled frame duration.
};
Animation::Animation(const std::string& name) :
// pass through
- mImpl(new Animation::Impl(name)) {}
+ impl_(new Animation::impl(name)) {}
void Animation::startSequence(const std::string& name)
{
// pass through
- mImpl->startSequence(name);
+ impl_->startSequence(name);
}
-void Animation::update(Mf::Scalar t, Mf::Scalar dt)
+void Animation::update(moof::scalar t, moof::scalar dt)
{
// pass through
- mImpl->update(t, dt);
+ impl_->update(t, dt);
}
unsigned Animation::getFrame() const
{
- return mImpl->mFrameIndex;
+ return impl_->mFrameIndex;
}
-
-/**
- * Specialized search location for animation files. They can be found in the
- * "animations" subdirectory of any of the searched directories.
- */
-
-std::string Animation::getPath(const std::string& name)
-{
- return Mf::Resource::getPath("animations/" + name + ".lua");
-}
-
-
-/** vim: set ts=4 sw=4 tw=80: *************************************************/
-