/*==LICENSE==* CyanWorlds.com Engine - MMOG client, server and tools Copyright (C) 2011 Cyan Worlds, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . You can contact Cyan Worlds, Inc. by email legal@cyan.com or by snail mail at: Cyan Worlds, Inc. 14617 N Newport Hwy Mead, WA 99021 *==LICENSE==*/ #ifndef plTimedValue_inc #define plTimedValue_inc #include "hsTimer.h" class hsStream; // plTimedValue // To use, replace your member var of type T with plTimedValue. // You can then pretty much treat it as normal. To set it to interpolate // to a new value over secs seconds, use Set(newVal, secs). // For I/O, see plTimedSimple and plTimedCompound. template class plTimedValue { protected: T fGoal; T fInit; double fStart; hsScalar fInvSecs; public: plTimedValue() {} plTimedValue(const plTimedValue& o) { Set(o, 0.f); } plTimedValue(const T& v) { Set(v, 0.f); } plTimedValue& operator=(const plTimedValue& o) { return Set(o, 0.f); } plTimedValue& operator=(const T& v) { return Set(v, 0.f); } plTimedValue& Set(const T& v, hsScalar secs=0); operator T () const { return Value(); } T Value() const; }; // Read/Writable version of plTimedValue, for intrinsic types (e.g. int, float, bool). // Must be a type that hsStream has an overloaded ReadSwap/WriteSwap defined. template class plTimedSimple : public plTimedValue { public: plTimedSimple& operator=(const plTimedValue& o) { return Set(o, 0.f); } plTimedSimple& operator=(const T& v) { return Set(v, 0.f); } plTimedSimple& Set(const T& v, hsScalar secs=0) { plTimedValue::Set(v, secs); return *this; } void Read(hsStream* s); void Write(hsStream* s) const; }; // Read/Writable version of plTimedValue, for compound types (e.g. hsVector3, hsColorRGBA). // May be any type that has Read(hsStream*)/Write(hsStream*) defined. template class plTimedCompound : public plTimedValue { public: plTimedCompound& operator=(const plTimedValue& o) { return Set(o, 0.f); } plTimedCompound& operator=(const T& v) { return Set(v, 0.f); } plTimedCompound& Set(const T& v, hsScalar secs=0) { plTimedValue::Set(v, secs); return *this; } void Read(hsStream* s); void Write(hsStream* s) const; }; template plTimedValue& plTimedValue::Set(const T& v, hsScalar secs) { if( secs <= 0 ) { fGoal = fInit = v; fInvSecs = 0; } else { fInit = Value(); fStart = hsTimer::GetSysSeconds(); fInvSecs = 1.f / secs; fGoal = v; } return *this; } template T plTimedValue::Value() const { if( fInvSecs > 0 ) { hsScalar t = (hsScalar)((hsTimer::GetSysSeconds() - fStart) * fInvSecs); hsAssert(t >= 0, "Moving back in time"); if( t < 1.f ) return fGoal * t + fInit * (1.f - t); } return fGoal; } template void plTimedSimple::Read(hsStream* s) { T val; s->ReadSwap(&val); Set(val, 0.f); } template void plTimedSimple::Write(hsStream* s) const { T val = Value(); s->WriteSwap(val); } template void plTimedCompound::Read(hsStream* s) { T val; val.Read(s); Set(val, 0.f); } template void plTimedCompound::Write(hsStream* s) const { T val = Value(); val.Write(s); } #endif // plTimedValue_inc