From: Charles McGarvey Date: Tue, 29 Dec 2009 09:21:59 +0000 (-0700) Subject: stream-based logging classes X-Git-Url: https://git.dogcows.com/gitweb?a=commitdiff_plain;h=7f3984f3f9524f5b6813e01ceb2fe576dadff94e;p=chaz%2Fyoink stream-based logging classes --- diff --git a/TODO b/TODO index 5c432f5..a456650 100644 --- a/TODO +++ b/TODO @@ -1,7 +1,7 @@ -The man page (doc/yoink.6) might have a general list of broad, long-term goals. +The man page (doc/yoink.6) might have a broad list of long-term goals. Otherwise, the code itself is documented with stuff that needs doing: -FIXME marks a bug and/or broken, incomplete code. +FIXME marks a known bug and/or broken, incomplete code. TODO marks code that could use some refactoring or possible new features. diff --git a/src/Animation.cc b/src/Animation.cc index ab178df..593f44e 100644 --- a/src/Animation.cc +++ b/src/Animation.cc @@ -78,7 +78,7 @@ class Animation::Impl * frame map which is probably loaded within an animation file. */ - Frame(Mf::Script& script, Mf::Script::Value table) : + Frame(Mf::Script& script, Mf::Script::Slot table) : mIndex(0), mDuration(1.0) { @@ -114,7 +114,7 @@ class Animation::Impl * constructor which loads each individual frame. */ - Sequence(Mf::Script& script, Mf::Script::Value table) : + Sequence(Mf::Script& script, Mf::Script::Slot table) : mDelay(0.0), mLoop(true) { @@ -133,10 +133,10 @@ class Animation::Impl // TODO - sequence class/type not yet implemented table.pushField("frames"); - Mf::Script::Value frameTable = script.getTop(); + Mf::Script::Slot frameTable = script.getTop(); if (frameTable.isTable()) { - Mf::Script::Value top = script[-1]; + Mf::Script::Slot top = script[-1]; int index = 1; for (;;) @@ -174,14 +174,14 @@ class Animation::Impl { std::string str; script[-1].get(str); - Mf::logScript("%s", str.c_str()); + Mf::logWarning(str); } } int defineSequence(Mf::Script& script) { - Mf::Script::Value name = script[1].requireString(); - Mf::Script::Value table = script[2].requireTable(); + Mf::Script::Slot name = script[1].requireString(); + Mf::Script::Slot table = script[2].requireTable(); std::string nameStr; name.get(nameStr); diff --git a/src/GameLayer.cc b/src/GameLayer.cc index 1e60758..3f5a7a8 100644 --- a/src/GameLayer.cc +++ b/src/GameLayer.cc @@ -68,13 +68,12 @@ void GameLayer::loadSceneLoader() throw Mf::Exception(Mf::ErrorCode::RESOURCE_NOT_FOUND, "loader"); } - Mf::Script::Status status = mState.script.doFile(loaderPath); + Mf::Script::Result status = mState.script.doFile(loaderPath); if (status != Mf::Script::SUCCESS) { std::string str; mState.script[-1].get(str); - Mf::logScript("%s", str.c_str()); throw Mf::Exception(Mf::ErrorCode::SCRIPT_ERROR, str); } @@ -82,8 +81,8 @@ void GameLayer::loadSceneLoader() mState.script.getTop().get(mState.sceneList); if (mState.sceneList.size() == 0) { - Mf::logScript("no variable `scenes' within loader"); - throw Mf::Exception(Mf::ErrorCode::SCRIPT_ERROR, "no scenes to load"); + throw Mf::Exception(Mf::ErrorCode::SCRIPT_ERROR, + "no variable `scenes' within loader"); } } @@ -94,13 +93,12 @@ void GameLayer::advanceScene() mState.scene = Scene::alloc(mState.sceneList[0]); mState.sceneList.erase(mState.sceneList.begin()); - Mf::Script::Status status = mState.scene->load(mState.script); + Mf::Script::Result status = mState.scene->load(mState.script); if (status != Mf::Script::SUCCESS) { std::string str; mState.script[-1].get(str); - Mf::logScript("%s", str.c_str()); throw Mf::Exception(Mf::ErrorCode::SCRIPT_ERROR, str); } } @@ -118,6 +116,8 @@ GameLayer::GameLayer() : Mf::Settings::getInstance().get("nomusic", isMute); if (!isMute) mMusic.play(); + //mMusic.setPosition(Mf::Vector3(10.0, 5.0, 0.0)); + loadSceneLoader(); advanceScene(); // load the first scene @@ -136,16 +136,14 @@ void GameLayer::pushed(Mf::Engine& engine) engine.push(Hud::alloc(mState)); mRay.direction.set(1.0, 0.0); - mRay3.direction.set(1.0, 0.0, 0.0); mLine.a.set(20, 10); mLine.b.set(19, 14); - mPlane.normal.set(-1.0, 0.0, 0.0); - mPlane.d = 0.0; - mSphere.point.set(22, 5); mSphere.radius = 2; + + mRayTimer.init(boost::bind(&GameLayer::rayTimer, this), 1.0, Mf::Timer::REPEAT); } @@ -160,44 +158,37 @@ void GameLayer::update(Mf::Engine& engine, Mf::Scalar t, Mf::Scalar dt) -mState.heroine->getState().position[1], -9)); //mState.camera.lookAt(Mf::promote(mState.heroine->getState().position)); - //Mf::Vector3 heroinePosition = Mf::promote(mState.heroine->getState().position); - //Mf::Sound::setListenerPosition(heroinePosition); - mRay.point = mState.heroine->getState().position; - mRay3.point = Mf::promote(mRay.point); - mRay3.direction = Mf::promote(mRay.direction); +} + +void GameLayer::rayTimer() +{ Mf::Ray<2>::Intersection meh; - Mf::Ray<3>::Intersection meh3; + std::list::Intersection> hits; + Mf::Vector2 point; - Mf::Scalar d = mLine.intersectRay(mRay, meh); - if (d > 0.0) + bool bam = mLine.intersectRay(mRay, meh); + if (bam) { - Mf::logDebug("line: d = %f", d); - Mf::logDebug(" P = <%f,%f>", meh.point[0], meh.point[1]); - Mf::logDebug(" n = <%f,%f>", meh.normal[0], meh.normal[1]); + meh.normal.normalize(); + hits.push_back(meh); } - //d = mPlane.intersectRay(mRay3, meh3); - //if (d > 0.0) - //{ - //Mf::logDebug("plane: d = %f", d); - //Mf::logDebug(" P = <%f,%f>", meh3.point[0], meh3.point[1]); - //Mf::logDebug(" n = <%f,%f>", meh3.normal[0], meh3.normal[1]); - //} - d = mSphere.intersectRay(mRay, meh); - if (d > 0.0) + + bam = mSphere.intersectRay(mRay, meh); + if (bam) { - Mf::logDebug("sphere: d = %f", d); - Mf::logDebug(" P = <%f,%f>", meh.point[0], meh.point[1]); - Mf::logDebug(" n = <%f,%f>", meh.normal[0], meh.normal[1]); + meh.normal.normalize(); + hits.push_back(meh); } - std::list::Intersection> hits; if (mState.scene->castRay(mRay, hits)) { - Mf::logDebug("scene: d = %f", d); - Mf::logDebug(" P = <%f,%f>", hits.front().point[0], hits.front().point[1]); - Mf::logDebug(" n = <%f,%f>", hits.front().normal[0], hits.front().normal[1]); + hits.front().normal.normalize(); + mRay.solve(point, hits.front().distance); + Mf::logDebug << "scene: d = " << hits.front().distance << std::endl; + Mf::logDebug << " P = " << point << std::endl; + Mf::logDebug << " n = " << hits.front().normal << std::endl; } } @@ -241,12 +232,14 @@ bool GameLayer::handleEvent(Mf::Engine& engine, const Mf::Event& event) } else if (event.key.keysym.sym == SDLK_PAGEUP) { - mRay.direction = cml::rotate_vector_2D(mRay.direction, cml::rad(10.0)); + mRay.direction = cml::rotate_vector_2D(mRay.direction, + cml::rad(10.0)); return true; } else if (event.key.keysym.sym == SDLK_PAGEDOWN) { - mRay.direction = cml::rotate_vector_2D(mRay.direction, cml::rad(-10.0)); + mRay.direction = cml::rotate_vector_2D(mRay.direction, + cml::rad(-10.0)); return true; } return mState.heroine->handleEvent(event); diff --git a/src/GameLayer.hh b/src/GameLayer.hh index 4692611..4e0a84f 100644 --- a/src/GameLayer.hh +++ b/src/GameLayer.hh @@ -51,6 +51,7 @@ #include #include #include +#include #include "Character.hh" #include "Heroine.hh" @@ -107,10 +108,11 @@ private: Mf::Sound mPunchSound; Mf::Ray<2> mRay; - Mf::Ray<3> mRay3; Mf::Line<2> mLine; - Mf::Plane mPlane; Mf::Sphere<2> mSphere; + + Mf::Timer mRayTimer; + void rayTimer(); }; diff --git a/src/Heroine.cc b/src/Heroine.cc index e2b69b2..a70b798 100644 --- a/src/Heroine.cc +++ b/src/Heroine.cc @@ -26,6 +26,8 @@ *******************************************************************************/ +#include + #include "Heroine.hh" #include "Log.hh" @@ -34,6 +36,22 @@ Heroine::Heroine() : Character("Heroine") {} +void Heroine::update(Mf::Scalar t, Mf::Scalar dt) +{ + Character::update(t, dt); + + Mf::Vector3 at(0.0, 0.0, 0.0); + const Mf::Vector3 up(0.0, 1.0, 0.0); + + if (mState.velocity[0] < 0.0) at[0] = -1.0; + else at[0] = 1.0; + + Mf::Sound::setListenerPosition(Mf::promote(mState.position)); + Mf::Sound::setListenerVelocity(Mf::promote(mState.velocity)); + Mf::Sound::setListenerOrientation(at, up); +} + + bool Heroine::handleEvent(const Mf::Event& event) { Mf::Scalar force = 40.0; diff --git a/src/Heroine.hh b/src/Heroine.hh index 151362e..ad8cd9a 100644 --- a/src/Heroine.hh +++ b/src/Heroine.hh @@ -55,6 +55,7 @@ public: return HeroineP(new Heroine); } + void update(Mf::Scalar t, Mf::Scalar dt); bool handleEvent(const Mf::Event& event); }; diff --git a/src/MainLayer.cc b/src/MainLayer.cc index faa4622..0b2ef36 100644 --- a/src/MainLayer.cc +++ b/src/MainLayer.cc @@ -271,15 +271,15 @@ int main(int argc, char* argv[]) #if YOINK_LOGLEVEL >= 4 - Mf::setLogLevel(Mf::LOG_DEBUG); + Mf::Log::setLevel(Mf::Log::DEBUGG); #elif YOINK_LOGLEVEL >= 3 - Mf::setLogLevel(Mf::LOG_INFO); + Mf::Log::setLevel(Mf::Log::INFO); #elif YOINK_LOGLEVEL >= 2 - Mf::setLogLevel(Mf::LOG_SCRIPT); + Mf::Log::setLevel(Mf::Log::SCRIPT); #elif YOINK_LOGLEVEL >= 1 - Mf::setLogLevel(Mf::LOG_ERROR); + Mf::Log::setLevel(Mf::Log::ERROR); #elif YOINK_LOGLEVEL - Mf::setLogLevel(Mf::LOG_NONE); + Mf::Log::setLevel(Mf::Log::NONE); #endif diff --git a/src/Moof/Engine.cc b/src/Moof/Engine.cc index fca5e15..ccfaf81 100644 --- a/src/Moof/Engine.cc +++ b/src/Moof/Engine.cc @@ -73,7 +73,8 @@ public: { char vdName[128]; SDL_VideoDriverName(vdName, sizeof(vdName)); - logDebug("initialized SDL; using video driver `%s'", vdName); + logDebug << "initialized SDL; using video driver `" + << vdName << "'" << std::endl; } if (FE_Init() != 0) @@ -87,13 +88,15 @@ public: if (!mAlDevice || !mAlContext) { const char* error = alcGetString(mAlDevice,alcGetError(mAlDevice)); - logError("error while creating audio context: %s", error); + logError << "error while creating audio context: " + << error << std::endl; } else { alcMakeContextCurrent(mAlContext); - logDebug("opened sound device `%s'", - alcGetString(mAlDevice, ALC_DEFAULT_DEVICE_SPECIFIER)); + logDebug << "opened sound device `" + << alcGetString(mAlDevice, ALC_DEFAULT_DEVICE_SPECIFIER) + << "'" << std::endl; } // now load the settings the engine needs @@ -196,7 +199,7 @@ public: if (mPrintFps) { - logInfo("%d fps", mFps); + logInfo << mFps << " fps" << std::endl; } } @@ -279,7 +282,8 @@ public: { ASSERT(layer && "cannot push null layer"); mStack.push_front(layer); - logDebug("stack: %d [pushed %X]", mStack.size(), layer.get()); + logDebug << "stack: " << mStack.size() + << " [pushed " << layer.get() << "]" << std::endl; layer->pushed(mInterface); } @@ -290,7 +294,8 @@ public: LayerP layer = mStack.front(); mStack.pop_front(); - logDebug("stack: %d [popped %X]", mStack.size(), layer.get()); + logDebug << "stack: " << mStack.size() + << " [popped " << layer.get() << "]" << std::endl; layer->popped(mInterface); if (fixIt) mStackIt = --mStack.begin(); @@ -319,7 +324,8 @@ public: for (it = layers.begin(); it != layers.end(); ++it) { (*it)->popped(mInterface); - logDebug("stack: %d [popped %X]", mStack.size(), (*it).get()); + logDebug << "stack: " << mStack.size() + << " [popped " << (*it).get() << "]" << std::endl; } if (fixIt) mStackIt = --mStack.begin(); @@ -343,7 +349,8 @@ public: { if (mMaxFps < mTimestep) { - logWarning("capping maximum fps to timestep (%f)", mTimestep); + logWarning << "capping maximum fps to timestep (" + << mTimestep << ")" << std::endl; mMaxFps = mTimestep; } } diff --git a/src/Moof/Interpolator.hh b/src/Moof/Interpolator.hh index 7ad38fe..5c9f097 100644 --- a/src/Moof/Interpolator.hh +++ b/src/Moof/Interpolator.hh @@ -80,6 +80,8 @@ class Interpolator public: + virtual ~Interpolator() {} + typedef enum { STOP = 0, @@ -132,6 +134,8 @@ class InterpolatorBase : public Interpolator { public: + virtual ~InterpolatorBase() {} + void init(Scalar seconds = 1.0, Mode mode = STOP) { Interpolator::init(seconds, mode); diff --git a/src/Moof/Line.hh b/src/Moof/Line.hh index 33eecb9..a88405e 100644 --- a/src/Moof/Line.hh +++ b/src/Moof/Line.hh @@ -56,8 +56,7 @@ struct Line : public Drawable, public Shape a(point1), b(point2) {} - Scalar intersectRay(const Ray<2>& ray, - Ray<2>::Intersection& intersection) const + bool intersectRay(const Ray<2>& ray, Ray<2>::Intersection& hit) const { // solve: Cx + r*Dx = Ax + s(Bx - Ax) // Cy + r*Dy = Ay + s(By - Ay) @@ -71,7 +70,8 @@ struct Line : public Drawable, public Shape ray.direction[1] * (a[0] - b[0]); // check if the ray and line are parallel - if (isEqual(denom, SCALAR(0.0))) + //if (isEqual(denom, SCALAR(0.0))) + if (denom == SCALAR(0.0)) { Scalar numer = a[0] * (ray.point[1] - b[1]) + b[0] * (a[1] - ray.point[1]) + @@ -80,35 +80,29 @@ struct Line : public Drawable, public Shape // check if they are collinear if (isEqual(numer, SCALAR(0.0))) { - intersection.point = ray.point; - intersection.normal.set(0.0, 0.0); - return SCALAR(0.0); + hit.distance = SCALAR(0.0); + hit.normal.set(0.0, 0.0); + return true; } - return SCALAR(-1.0); + return false; } Scalar s = (ray.direction[0] * (ray.point[1] - a[1]) + ray.direction[1] * (a[0] - ray.point[0])) / denom; // check if the ray hits the segment - if (s < SCALAR(0.0) || s > SCALAR(1.0)) return SCALAR(-1.0); + if (s < SCALAR(0.0) || s > SCALAR(1.0)) return false; - Scalar r = -(a[0] * (ray.point[1] - b[1]) + - b[0] * (a[1] - ray.point[1]) + - ray.point[0] * (b[1] - a[1])) / denom; + hit.distance = -(a[0] * (ray.point[1] - b[1]) + + b[0] * (a[1] - ray.point[1]) + + ray.point[0] * (b[1] - a[1])) / denom; + if (hit.distance < SCALAR(0.0)) return false; - // make sure we're dealing with the right side of the ray - if (r < SCALAR(0.0)) return SCALAR(-1.0); - - intersection.point = ray.point + r * ray.direction; - - // gotta use the correct normal - Vector n = cml::perp(a - b); - if (cml::dot(a - ray.point, n) < 0) intersection.normal = n; - else intersection.normal = -n; - - return r; + Vector normal = cml::perp(a - b); + if (cml::dot(a - ray.point, normal) < 0) hit.normal = normal; + else hit.normal = -normal; + return true; } void draw(Scalar alpha = 0.0) const diff --git a/src/Moof/Log.cc b/src/Moof/Log.cc index a7cdae4..2ea6c57 100644 --- a/src/Moof/Log.cc +++ b/src/Moof/Log.cc @@ -26,9 +26,7 @@ *******************************************************************************/ -#include -#include // snprintf -#include // strcpy +#include #include "Log.hh" #include "Script.hh" @@ -37,124 +35,41 @@ namespace Mf { -static LogLevel logLevel_ = LOG_WARNING; - -inline void printLog_(int logLevel, const char* fmt, va_list args) -{ - if (logLevel_ < logLevel) return; - - switch (logLevel) - { - case LOG_ERROR: - fprintf(stderr, " error: "); - break; - case LOG_WARNING: - fprintf(stderr, "warning: "); - break; - case LOG_SCRIPT: - fprintf(stderr, " script: "); - break; - case LOG_INFO: - fprintf(stderr, " info: "); - break; - case LOG_DEBUG: - fprintf(stderr, " debug: "); - break; - } - - vfprintf(stderr, fmt, args); - fprintf(stderr, "\n"); -} +Log::Level Log::gLevel = Log::WARNING; -LogLevel setLogLevel(LogLevel level) +void Log::setLevel(Level level) { - if (level != 0) - logLevel_ = level; - - return logLevel_; + if (level != 0) gLevel = level; } - -void logError(const char* fmt, ...) +Log::Level Log::getLevel() { - va_list args; - va_start(args, fmt); - - printLog_(LOG_ERROR, fmt, args); - - va_end(args); + return gLevel; } -void logWarning(const char* fmt, ...) -{ - va_list args; - va_start(args, fmt); - printLog_(LOG_WARNING, fmt, args); +static std::ofstream nullLog_; - va_end(args); -} +std::ostream& log(std::clog); +std::ostream& nullLog(nullLog_); -void logInfo(const char* fmt, ...) -{ - va_list args; - va_start(args, fmt); - - printLog_(LOG_INFO, fmt, args); - - va_end(args); -} - -void logDebug(const char* fmt, ...) -{ - va_list args; - va_start(args, fmt); +Log logError(Log::ERRORR, " error: "); +Log logWarning(Log::WARNING, "warning: "); +Log logInfo(Log::INFO, " info: "); +Log logDebug(Log::DEBUGG, " debug: "); - printLog_(LOG_DEBUG, fmt, args); - va_end(args); -} - -void logScript(const char* fmt, ...) +static int logScript_(Script& script) { - va_list args; - va_start(args, fmt); - - printLog_(LOG_SCRIPT, fmt, args); + static Log logScript(Log::SCRIPT, " script: "); - va_end(args); -} - -int logScript(Script& script) -{ - Script::Value param = script[1]; + Script::Slot param = script[1]; while (!param.isNone()) { - if (param.isString()) - { - std::string str; - param.get(str); - logScript("%s", str.c_str()); - } - else if (param.isBoolean()) - { - if (param) logScript("true"); - else logScript("false"); - - } - else if (param.isNil()) - { - logScript("nil"); - } - else - { - logScript("%s (%X)", param.getTypeName().c_str(), - param.getIdentifier()); - } - - param.index++; + logScript(param); + ++param.index; } return 0; @@ -163,7 +78,7 @@ int logScript(Script& script) void importLogPrintFunction(Script& script) { - script.importFunction("print", (int (*)(Script&))logScript); + script.importFunction("print", logScript_); } diff --git a/src/Moof/Log.hh b/src/Moof/Log.hh index d3aa555..c7ee507 100644 --- a/src/Moof/Log.hh +++ b/src/Moof/Log.hh @@ -37,6 +37,7 @@ */ #include // exit +#include /** @@ -49,76 +50,72 @@ #if NDEBUG #define ASSERT(X) #else -#define ASSERT(X) if (!(X)) Mf::logError("false assertion at %s:%d, " #X, \ - __FILE__, __LINE__), exit(1) +#define ASSERT(X) if (!(X)) Mf::logError << \ + "false assertion at " << __FILE__ << ":" << __LINE__ << ", " << #X, exit(1) #endif namespace Mf { -/** - * Possible values used for setting the log level using LogLevel(). Log - * messages of lesser importance than the level specified are ignored. - * @see LogLevel() - */ - -enum LogLevel +class Log { - LOG_NONE = -1, ///< Disable all logging. - LOG_ERROR = 1, ///< Log only errors. - LOG_WARNING = 2, ///< Log warnings and errors. - LOG_SCRIPT = 3, ///< Log messages from Lua, too. - LOG_INFO = 4, ///< Log info, warnings, errors. - LOG_DEBUG = 5, ///< Log all messages. -}; +public: + enum Level + { + NONE = -1, ///< Disable all logging. + ERRORR = 1, ///< Log only errors. + WARNING = 2, ///< Log warnings and errors. + SCRIPT = 3, ///< Log messages from Lua, too. + INFO = 4, ///< Log info, warnings, errors. + DEBUGG = 5, ///< Log all messages. + }; -/** - * Set and/or get the level of logs which will be logged. If not called, - * defaults to WARNING - * @param level LOG_LEVEL_* constant or 0 for no change. - * @return The currently set log level. - */ + static void setLevel(Level level); + static Level getLevel(); -LogLevel setLogLevel(LogLevel level); + Log(Level level, const char* type) : + mLevel(level), + mType(type) /* only pass literal strings */ {} -/** - * Log an error. - * @param fmt Log format string. - * @param ... Extra format arguments. - */ -void logError(const char* fmt, ...); + template + void operator () (const T& item) + { + *this << item << std::endl; + } -/** - * Log a warning. - * @param fmt Log format string. - * @param ... Extra format arguments. - */ +private: -void logWarning(const char* fmt, ...); + template friend std::ostream& operator << (Log&, const T&); -/** - * Log a message. - * @param fmt Log format string. - * @param ... Extra format arguments. - */ + static Level gLevel; -void logInfo(const char* fmt, ...); + Level mLevel; + const char* mType; +}; -/** - * Log a debug message. - * @param fmt Log format string. - * @param ... Extra format arguments. - */ -void logDebug(const char* fmt, ...); +extern std::ostream& log; +extern std::ostream& nullLog; + +extern Log logError; +extern Log logWarning; +extern Log logInfo; +extern Log logDebug; + + +template +inline std::ostream& operator << (Log& logObj, const T& item) +{ + if (Log::gLevel < logObj.mLevel) return nullLog; + return log << logObj.mType << item; +} + -void logScript(const char* fmt, ...); class Script; -int logScript(Script& script); void importLogPrintFunction(Script& script); diff --git a/src/Moof/ModalDialog.hh b/src/Moof/ModalDialog.hh index 68a6d28..9b3820a 100644 --- a/src/Moof/ModalDialog.hh +++ b/src/Moof/ModalDialog.hh @@ -79,16 +79,16 @@ struct ModalDialog switch (type) { case WARNING: - logWarning("%s", text1.c_str()); - logWarning("%s", text2.c_str()); + logWarning(text1); + logWarning(text2); break; case CRITICAL: - logError("%s", text1.c_str()); - logError("%s", text2.c_str()); + logError(text1); + logError(text2); break; default: - logInfo("%s", text1.c_str()); - logInfo("%s", text2.c_str()); + logInfo(text1); + logInfo(text2); break; } diff --git a/src/Moof/Octree.hh b/src/Moof/Octree.hh index 13ece5b..4657aec 100644 --- a/src/Moof/Octree.hh +++ b/src/Moof/Octree.hh @@ -79,7 +79,7 @@ class Octree : public Entity void printSize() { - logDebug("size of node %d", objects.size()); + logDebug << "size of node " << objects.size() << std::endl; } void getAll(std::list& insertables) const @@ -272,8 +272,8 @@ public: void print(NodeP node) { logInfo("-----"); - logInfo("depth to node: %d", mTree.depth(node)); - logInfo("size of node: %d", mTree.size(node)); + logInfo << "depth to node: " << mTree.depth(node) << std::endl; + logInfo << "size of node: " << mTree.size(node) << std::endl; } static Ptr alloc(const Node& rootNode) diff --git a/src/Moof/Plane.hh b/src/Moof/Plane.hh index 11cd63e..b398917 100644 --- a/src/Moof/Plane.hh +++ b/src/Moof/Plane.hh @@ -66,39 +66,34 @@ struct Plane : public Shape<3> d(scalar) {} - Scalar intersectRay(const Ray<3>& ray, Ray<3>::Intersection& intersection) + bool intersectRay(const Ray<3>& ray, Ray<3>::Intersection& hit) { // solve: [(ray.point + t*ray.direction) dot normal] + d = 0 - Scalar denominator = cml::dot(ray.direction, normal); + Scalar denom = cml::dot(ray.direction, normal); // check for parallel condition - if (denominator == SCALAR(0.0)) + if (denom == SCALAR(0.0)) { if (isEqual(cml::dot(ray.point, normal), -d)) { // the ray lies on the plane - intersection.point = ray.point; - intersection.normal.set(0.0, 0.0, 0.0); - //intersection.normal = normal; - return SCALAR(0.0); + hit.distance = SCALAR(0.0); + hit.normal.set(0.0, 0.0, 0.0); + return true; } // no solution - return SCALAR(-1.0); + return false; } - Scalar distance = cml::dot(ray.point, normal) + d; - Scalar t = -distance / denominator; - if (t > SCALAR(0.0)) - { - ray.solve(intersection.point, t); - - if (distance >= 0.0) intersection.normal = normal; - else intersection.normal = -normal; - } + Scalar numer = cml::dot(ray.point, normal) + d; + hit.distance = -numer / denom; + if (hit.distance < SCALAR(0.0)) return false; - return t; + if (numer >= 0.0) hit.normal = normal; + else hit.normal = -normal; + return true; } diff --git a/src/Moof/Ray.hh b/src/Moof/Ray.hh index 15e1d9d..23ebd76 100644 --- a/src/Moof/Ray.hh +++ b/src/Moof/Ray.hh @@ -53,8 +53,13 @@ struct Ray : public Drawable struct Intersection { - Vector point; // nearest point of intersection + Scalar distance; // distance from the origin to the nearest point Vector normal; // surface normal at intersection point + + bool operator < (const Intersection& rhs) + { + return distance < rhs.distance; + } }; void solve(Vector& p, Scalar t) const @@ -77,7 +82,6 @@ struct Ray : public Drawable { direction.normalize(); } - }; diff --git a/src/Moof/Resource.cc b/src/Moof/Resource.cc index 6f09601..ff4213e 100644 --- a/src/Moof/Resource.cc +++ b/src/Moof/Resource.cc @@ -78,7 +78,7 @@ std::string Resource::getPath(const std::string& name) if (access(fullPath.c_str(), R_OK) == 0) return fullPath; } - logWarning("cannot find resource %s", name.c_str()); + logWarning << "cannot find resource " << name << std::endl; // empty string return std::string(); diff --git a/src/Moof/Script.hh b/src/Moof/Script.hh index f67c62c..05b9da9 100644 --- a/src/Moof/Script.hh +++ b/src/Moof/Script.hh @@ -38,6 +38,7 @@ * more consistent API. */ +#include #include #include #include @@ -79,7 +80,7 @@ public: THREAD = LUA_TTHREAD }; - enum Status + enum Result { SUCCESS = 0, YIELD = LUA_YIELD, @@ -99,14 +100,14 @@ public: /** * This is the most prominent abstraction on top of the standard Lua API. - * A Value object represents a value on the stack. More specifically, it + * A Slot object represents a value on the stack. More specifically, it * represents a position on the stack. The distinction is only important - * when values are moved around on the stack or if the Value represents a + * when objects are moved around on the stack or if the Slot represents a * negative index on the stack (the value of which will change as things are * pushed onto and popped from the stack). */ - struct Value + struct Slot { /** * You have direct access to the index of the value on the stack being @@ -117,13 +118,13 @@ public: /** - * A default-constructed Value is invalid until a valid Value is - * assigned to it. The only method that should be called on such a - * Value is isValid(), otherwise chaos may ensue. In this case, the - * Value will be invalid even if index is manually changed to a valid - * index. You have to index the script itself to get a valid Value. + * A default-constructed Slot is invalid until a valid Slot is assigned + * to it. The only method that should be called on such a Slot is + * isValid(), otherwise chaos may ensue. In this case, the Slot will be + * invalid even if index is manually changed to a valid index. You have + * to index the script itself to get a valid Slot. */ - Value(lua_State* s = 0, int i = 0) : + Slot(lua_State* s = 0, int i = 0) : index(i), mState(s) {} @@ -134,7 +135,7 @@ public: * copied into the new value object. */ - Value(const Value& copy) : + Slot(const Slot& copy) : index(copy.getRealIndex()), mState(copy.mState) {} @@ -180,42 +181,42 @@ public: } - Value& requireBoolean() + Slot& requireBoolean() { if (!isBoolean()) luaL_typerror(mState, index, "boolean"); return *this; } - Value& requireNumber() + Slot& requireNumber() { if (!isNumber()) luaL_typerror(mState, index, "number"); return *this; } - Value& requireString() + Slot& requireString() { if (!isString()) luaL_typerror(mState, index, "string"); return *this; } - Value& requireTable() + Slot& requireTable() { if (!isTable()) luaL_typerror(mState, index, "table"); return *this; } - Value& requireFunction() + Slot& requireFunction() { if (!isFunction()) luaL_typerror(mState, index, "function"); return *this; } - Value& requireData() + Slot& requireData() { if (!isData()) luaL_typerror(mState, index, "data"); return *this; } - Value& requireNil() + Slot& requireNil() { if (!isNil()) luaL_typerror(mState, index, "nil"); return *this; } - Value& requireThread() + Slot& requireThread() { if (!isThread()) luaL_typerror(mState, index, "thread"); return *this; @@ -267,27 +268,27 @@ public: } - bool operator == (const Value& rhs) const + bool operator == (const Slot& rhs) const { return (bool)lua_equal(mState, index, rhs.index); } - bool operator != (const Value& rhs) const + bool operator != (const Slot& rhs) const { return !(*this == rhs); } - bool operator < (const Value& rhs) const + bool operator < (const Slot& rhs) const { return (bool)lua_lessthan(mState, index, rhs.index); } - bool operator <= (const Value& rhs) const + bool operator <= (const Slot& rhs) const { return *this < rhs || *this == rhs; } - bool operator > (const Value& rhs) const + bool operator > (const Slot& rhs) const { return !(*this <= rhs); } - bool operator >= (const Value& rhs) const + bool operator >= (const Slot& rhs) const { return !(*this < rhs); } @@ -296,7 +297,7 @@ public: return (bool)lua_toboolean(mState, index); } - Value& operator = (const Value& rhs) + Slot& operator = (const Slot& rhs) { rhs.pushCopy(); replaceWithTop(); @@ -367,7 +368,7 @@ public: array.clear(); - Value value(mState, -1); + Slot value(mState, -1); int realIndex = getRealIndex(); bool done = false; @@ -392,8 +393,8 @@ public: dictionary.clear(); - Value key(mState, -2); - Value value(mState, -1); + Slot key(mState, -2); + Slot value(mState, -1); int realIndex = getRealIndex(); lua_pushnil(mState); @@ -413,7 +414,6 @@ public: } - /** * Copy the value and push the copy to the stack. */ @@ -498,7 +498,7 @@ public: if (mState) destroy(); mState = luaL_newstate(); lua_pushlightuserdata(mState, this); - lua_setfield(mState, LUA_REGISTRYINDEX, "_script_obj"); + lua_setfield(mState, LUA_REGISTRYINDEX, "Script_hh_Object"); } @@ -571,14 +571,14 @@ public: } - Status doString(const std::string& commands) + Result doString(const std::string& commands) { - return (Status)luaL_dostring(mState, commands.c_str()); + return (Result)luaL_dostring(mState, commands.c_str()); } - Status doFile(const std::string& file) + Result doFile(const std::string& file) { - return (Status)luaL_dofile(mState, file.c_str()); + return (Result)luaL_dofile(mState, file.c_str()); } @@ -596,14 +596,14 @@ public: lua_pushthread(mState); } - Status resume(int nargs) + Result resume(int nargs) { - return (Status)lua_resume(mState, nargs); + return (Result)lua_resume(mState, nargs); } - Status getStatus() const + Result getStatus() const { - return (Status)lua_status(mState); + return (Result)lua_status(mState); } int yield(int results) @@ -637,24 +637,24 @@ public: * Get significant values. */ - Value getGlobalTable() const + Slot getGlobalTable() const { - return Value(mState, GLOBALS); + return Slot(mState, GLOBALS); } - Value getRegistryTable() const + Slot getRegistryTable() const { - return Value(mState, REGISTRY); + return Slot(mState, REGISTRY); } - Value getEnvironmentTable() const + Slot getEnvironmentTable() const { - return Value(mState, ENVIRONMENT); + return Slot(mState, ENVIRONMENT); } - Value getTop() const + Slot getTop() const { - return Value(mState, lua_gettop(mState)); + return Slot(mState, lua_gettop(mState)); } /** @@ -692,10 +692,10 @@ public: /** - * Concatenates the top-most n values on the stack. + * Concatenates the top-most n slots on the stack. */ - void concat(int n) + void concat(int n = 2) { lua_concat(mState, n); } @@ -761,14 +761,14 @@ public: lua_xmove(thread.mState, mState, n); } - Status pushCode(const std::string& filename) + Result pushCode(const std::string& filename) { - return (Status)luaL_loadfile(mState, filename.c_str()); + return (Result)luaL_loadfile(mState, filename.c_str()); } - Status pushCode(const std::string& name, const char* buffer, size_t size) + Result pushCode(const std::string& name, const char* buffer, size_t size) { - return (Status)luaL_loadbuffer(mState, buffer, size, name.c_str()); + return (Result)luaL_loadbuffer(mState, buffer, size, name.c_str()); } void* pushNewData(size_t size) @@ -789,9 +789,9 @@ public: * is any number of return values, depending on the callee). */ - Status call(int nargs, int nresults = LUA_MULTRET) + Result call(int nargs, int nresults = LUA_MULTRET) { - return (Status)lua_pcall(mState, nargs, nresults, 0); + return (Result)lua_pcall(mState, nargs, nresults, 0); } @@ -806,12 +806,12 @@ public: /** - * Index into the stack to get a Value. + * Index into the stack to get a Slot. */ - Value operator [] (int index) const + Slot operator [] (int index) const { - return Value(mState, index); + return Slot(mState, index); } @@ -819,7 +819,7 @@ public: * Getting and setting fields of a table. */ - void get(const std::string& field, int index = GLOBALS) const + void pushField(const std::string& field, int index = GLOBALS) const { lua_getfield(mState, index, field.c_str()); } @@ -878,7 +878,7 @@ private: const Function* function = (const Function*)lua_touserdata(state, lua_upvalueindex(1)); - lua_getfield(state, LUA_REGISTRYINDEX, "_script_obj"); + lua_getfield(state, LUA_REGISTRYINDEX, "Script_hh_Object"); Script* script = (Script*)lua_touserdata(state, -1); lua_pop(state, 1); @@ -896,6 +896,34 @@ private: }; +inline std::ostream& operator << (std::ostream& stream, + const Script::Slot& slot) +{ + if (slot.isString()) + { + std::string str; + slot.get(str); + stream << str; + } + else if (slot.isBoolean()) + { + if (slot) stream << "true"; + else stream << "false"; + } + else if (slot.isNil()) + { + stream << "nil"; + } + else + { + stream << slot.getTypeName() + << " (" << slot.getIdentifier() << ")" << std::endl; + } + + return stream; +} + + } // namespace Mf #endif // _MOOF_SCRIPT_HH_ diff --git a/src/Moof/Settings.cc b/src/Moof/Settings.cc index 81b5c50..c5c3734 100644 --- a/src/Moof/Settings.cc +++ b/src/Moof/Settings.cc @@ -35,6 +35,11 @@ namespace Mf { +Settings::~Settings() +{ + save(); +} + Settings& Settings::getInstance() { static Settings settings; @@ -72,13 +77,18 @@ void Settings::loadFromFiles(const std::vector& filePaths) if (home) { boost::replace_all(path, "$HOME", home); + + //Mf::logDebug("Copying global settings..."); + //mUserFile = path; + //mGlobals.pushCopy(); + //mScript.set("globals", Script::REGISTRY); } if (mScript.doFile(path) != Script::SUCCESS) { std::string str; mScript[-1].get(str); - logScript("%s", str.c_str()); + logInfo(str); mScript.clear(); } } @@ -91,6 +101,17 @@ void Settings::clear() } +void Settings::saveAs(const std::string& filePath) +{ + mUserFile = filePath; + save(); +} + +void Settings::save() const +{ +} + + } // namepsace Mf /** vim: set ts=4 sw=4 tw=80: *************************************************/ diff --git a/src/Moof/Settings.hh b/src/Moof/Settings.hh index 9b3e0cb..2a2a926 100644 --- a/src/Moof/Settings.hh +++ b/src/Moof/Settings.hh @@ -58,6 +58,8 @@ public: importLogPrintFunction(mScript); } + ~Settings(); + // get global instance static Settings& getInstance(); @@ -68,13 +70,18 @@ public: void clear(); // remove all settings + void saveAs(const std::string& filePath); + void save() const; + template bool get(const std::string& key, T& value); private: Script mScript; - Script::Value mGlobals, mTop; + Script::Slot mGlobals, mTop; + + std::string mUserFile; }; diff --git a/src/Moof/Shape.hh b/src/Moof/Shape.hh index c67a779..626ac3a 100644 --- a/src/Moof/Shape.hh +++ b/src/Moof/Shape.hh @@ -61,14 +61,15 @@ class Shape public: virtual ~Shape() {} + /** * Checks if this shape is intersected by a given ray. If so, returns the * distance from the start of the ray to the shape and information about the * intersection via the 2nd parameter. A negative value is returned if * there is no intersection. */ - virtual Scalar intersectRay(const Ray& ray, - typename Ray::Intersection& intersection) + virtual bool intersectRay(const Ray& ray, + typename Ray::Intersection& hit) { return SCALAR(-1.0); } diff --git a/src/Moof/Sound.cc b/src/Moof/Sound.cc index 3aec3f6..b91158a 100644 --- a/src/Moof/Sound.cc +++ b/src/Moof/Sound.cc @@ -97,8 +97,8 @@ public: if (result < 0) { - logWarning("error while loading sound %s", - getName().c_str()); + logWarning << "error while loading sound " + << getName() << std::endl; throw Exception(ErrorCode::UNKNOWN_AUDIO_FORMAT, getName()); } @@ -134,7 +134,8 @@ public: } if (size == 0) { - logWarning("decoded no bytes from %s", getName().c_str()); + logWarning << "decoded no bytes from " + << getName() << std::endl; return; } diff --git a/src/Moof/Sphere.hh b/src/Moof/Sphere.hh index f7b6a95..f184709 100644 --- a/src/Moof/Sphere.hh +++ b/src/Moof/Sphere.hh @@ -77,26 +77,27 @@ struct Sphere : public Cullable, public Drawable, public Shape // a ray inside the sphere will not intersect on its way out - Scalar intersectRay(const Ray& ray, - typename Ray::Intersection& intersection) + bool intersectRay(const Ray& ray, typename Ray::Intersection& hit) { Vector b = point - ray.point; Scalar z = cml::dot(b, ray.direction); // check if the ball is behind the ray - if (z < SCALAR(0.0)) return SCALAR(-1.0); + if (z < SCALAR(0.0)) return false; Scalar d2 = cml::dot(b, b) - z*z; Scalar r2 = radius * radius; // check for an intersection - if (d2 > r2) return SCALAR(-1.0); + if (d2 > r2) return false; - Scalar t = z - std::sqrt(r2 - d2); - ray.solve(intersection.point, t); - intersection.normal = intersection.point - point; + hit.distance = z - std::sqrt(r2 - d2); + if (hit.distance < SCALAR(0.0)) return false; - return t; + Vector surfacePoint; + ray.solve(surfacePoint, hit.distance); + hit.normal = surfacePoint - point; + return true; } diff --git a/src/Moof/Texture.cc b/src/Moof/Texture.cc index a701424..61cabd2 100644 --- a/src/Moof/Texture.cc +++ b/src/Moof/Texture.cc @@ -249,7 +249,7 @@ public: if (!surface) { - logWarning("texture not found: %s", getName().c_str()); + logWarning << "texture not found: " << getName() << std::endl; throw Exception(ErrorCode::FILE_NOT_FOUND, getName()); } diff --git a/src/Moof/Transition.hh b/src/Moof/Transition.hh index 310e8ea..07addc3 100644 --- a/src/Moof/Transition.hh +++ b/src/Moof/Transition.hh @@ -121,7 +121,7 @@ public: void draw(Engine& engine, Scalar alpha) const { Scalar a = mInterp.getState(alpha); - logDebug("transition state: %f", a); + logDebug << "transition state: " << a << std::endl; //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); diff --git a/src/Scene.cc b/src/Scene.cc index fce4517..a45b1fb 100644 --- a/src/Scene.cc +++ b/src/Scene.cc @@ -75,8 +75,8 @@ struct Scene::Impl : public Mf::Library if (!mTilemap.getTileCoords(tileIndex, mTexCoords)) { - Mf::logWarning("no index %d in texture %s", tileIndex, - texture.c_str()); + Mf::logWarning << "no index " << tileIndex << + " in texture " << texture << std::endl; mTexCoords[0] = mTexCoords[1] = mTexCoords[3] = mTexCoords[6] = 0.0; @@ -211,7 +211,7 @@ struct Scene::Impl : public Mf::Library } - Mf::Script::Status load(Mf::Script& script) + Mf::Script::Result load(Mf::Script& script) { std::string filePath = Scene::getPath(getName()); if (filePath == "") @@ -227,18 +227,15 @@ struct Scene::Impl : public Mf::Library static int loadBox(Mf::Script& script, Mf::Aabb<3>& aabb) { - Mf::Script::Value table[] = - { - script[1].requireTable(), - script[2].requireTable() - }; + script[1].requireTable(); + script[2].requireTable(); + script.setSize(2); - for (int i = 0; i <= 1; ++i) + for (int i = 1; i <= 2; ++i) { for (int j = 1; j <= 3; ++j) { - script.push(j); - table[i].pushField(); + script[i].pushField(j); } } @@ -267,14 +264,11 @@ struct Scene::Impl : public Mf::Library int translate(Mf::Script& script) { - Mf::Script::Value x = script[1].requireNumber(); - Mf::Script::Value y = script[2].requireNumber(); - Mf::Script::Value z = script[3].requireNumber(); - Mf::Vector3 vec; - x.get(vec[0]); - y.get(vec[1]); - z.get(vec[2]); + + script[1].requireNumber().get(vec[0]); + script[2].requireNumber().get(vec[1]); + script[3].requireNumber().get(vec[2]); Mf::Matrix4 translation; cml::matrix_translation(translation, vec); @@ -315,14 +309,11 @@ struct Scene::Impl : public Mf::Library int rotate(Mf::Script& script) { - Mf::Script::Value axis = script[1].requireNumber(); - Mf::Script::Value angle = script[2].requireNumber(); - size_t index = 0; - axis.get(index); + script[1].requireNumber().get(index); Mf::Scalar value; - angle.get(value); + script[2].requireNumber().get(value); cml::matrix_rotate_about_world_axis(mTransform, index, cml::rad(value)); @@ -337,8 +328,8 @@ struct Scene::Impl : public Mf::Library int drawTilemap(Mf::Script& script) { - Mf::Script::Value table = script[1].requireTable(); - Mf::Script::Value top = script[-1]; + Mf::Script::Slot table = script[1].requireTable(); + Mf::Script::Slot top = script[-1]; int width = 1; int height = 1; @@ -359,7 +350,7 @@ struct Scene::Impl : public Mf::Library // the indices are stored upside-down in the scene file so that they are // easier to edit as text, so we'll need to load them last row first - // do first row and first column of vertices + // do first row and first column of vertices for (int w = 0; w <= width; ++w) { @@ -420,25 +411,11 @@ struct Scene::Impl : public Mf::Library // scene is built, simply demoting the vector again should // project the points to the xy-plane - //Mf::Vector2 tr = Mf::demote(vertices[height+1][width+1]); - //Mf::Vector2 bl = Mf::demote(vertices[0][0]); - Mf::Vector2 bl = Mf::demote(vertices[0][0]); Mf::Vector2 tr = Mf::demote(vertices[height][width]); - //Mf::logInfo("pt1: %f, %f", bl[0], bl[1]); - //Mf::logInfo("pt2: %f, %f", tr[0], tr[1]); mLines.push_back(Mf::Line<2>(bl, tr)); - Mf::logInfo("new line"); - - //if (tl == tr) - //{ - //mLines.push_back(Mf::Line<2>(bl, tl)); - //} - //else - //{ - //mLines.push_back(Mf::Line<2>(bl, tl)); - //} + Mf::logDebug("new line"); } return 0; @@ -446,8 +423,8 @@ struct Scene::Impl : public Mf::Library int drawTile(Mf::Script& script) { - Mf::Script::Value param = script[1]; - Mf::Script::Value top = script[-1]; + Mf::Script::Slot param = script[1]; + Mf::Script::Slot top = script[-1]; Tilemap::Index index = 0; int width = 1; @@ -518,7 +495,7 @@ Scene::Scene(const std::string& name) : mImpl(Scene::Impl::getInstance(name)) {} -Mf::Script::Status Scene::load(Mf::Script& script) +Mf::Script::Result Scene::load(Mf::Script& script) { // pass through return mImpl->load(script); @@ -573,11 +550,13 @@ bool Scene::castRay(const Mf::Ray<2>& ray, if (d > 0.0) { hits.push_back(hit); - return true; + //return true; } } - return false; + hits.sort(); + return !hits.empty(); + //return false; } bool Scene::checkForCollision(Character& character) @@ -635,7 +614,7 @@ bool Scene::checkForCollision(Character& character) if (collisions > 0) { - Mf::logInfo("collisions: %d", collisions); + Mf::logInfo << "collisions: " << collisions << std::endl; } return false; diff --git a/src/Scene.hh b/src/Scene.hh index 316f25b..7558e3a 100644 --- a/src/Scene.hh +++ b/src/Scene.hh @@ -60,7 +60,7 @@ public: return SceneP(new Scene(name)); } - Mf::Script::Status load(Mf::Script& script); + Mf::Script::Result load(Mf::Script& script); void draw(Mf::Scalar alpha) const; void drawIfVisible(Mf::Scalar alpha, const Mf::Frustum& frustum) const; diff --git a/src/Tilemap.cc b/src/Tilemap.cc index 02184bc..c45d169 100644 --- a/src/Tilemap.cc +++ b/src/Tilemap.cc @@ -73,14 +73,14 @@ struct Tilemap::Impl : public Mf::Library { std::string str; script[-1].get(str); - Mf::logScript("%s", str.c_str()); + Mf::logWarning(str); return; // TODO needs a better exit strategy } - Mf::logInfo("loading tiles from tilemap %s", filePath.c_str()); + Mf::logInfo << "loading tiles from tilemap " << filePath << std::endl; - Mf::Script::Value globals = script.getGlobalTable(); - Mf::Script::Value top = script[-1]; + Mf::Script::Slot globals = script.getGlobalTable(); + Mf::Script::Slot top = script[-1]; globals.pushField("tiles_s"); top.get(mTilesS);