2010-12-31 14:56:24 +08:00
/****************************************************************************
2012-09-24 21:22:20 +08:00
Copyright ( c ) 2010 - 2012 cocos2d - x . org
2011-03-19 14:45:51 +08:00
Copyright ( c ) 2010 Ricardo Quesada
2011-07-01 16:11:31 +08:00
Copyright ( c ) 2011 Zynga Inc .
2010-12-31 14:56:24 +08:00
http : //www.cocos2d-x.org
Permission is hereby granted , free of charge , to any person obtaining a copy
of this software and associated documentation files ( the " Software " ) , to deal
in the Software without restriction , including without limitation the rights
to use , copy , modify , merge , publish , distribute , sublicense , and / or sell
copies of the Software , and to permit persons to whom the Software is
furnished to do so , subject to the following conditions :
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software .
THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM , DAMAGES OR OTHER
LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE , ARISING FROM ,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include "CCAnimationCache.h"
# include "ccMacros.h"
# include "CCAnimation.h"
# include "CCSpriteFrame.h"
2012-03-16 13:42:53 +08:00
# include "CCSpriteFrameCache.h"
2012-06-19 16:20:46 +08:00
# include "cocoa/CCString.h"
# include "platform/CCFileUtils.h"
2010-12-31 14:56:24 +08:00
2012-03-16 13:42:53 +08:00
using namespace std ;
2010-12-31 14:56:24 +08:00
2012-03-16 13:42:53 +08:00
NS_CC_BEGIN
2010-12-31 14:56:24 +08:00
2013-06-20 14:13:12 +08:00
AnimationCache * AnimationCache : : s_pSharedAnimationCache = NULL ;
2010-12-31 14:56:24 +08:00
2013-07-12 06:24:23 +08:00
AnimationCache * AnimationCache : : getInstance ( )
2012-03-16 13:42:53 +08:00
{
if ( ! s_pSharedAnimationCache )
2012-04-19 14:35:52 +08:00
{
2013-06-20 14:13:12 +08:00
s_pSharedAnimationCache = new AnimationCache ( ) ;
2012-04-19 14:35:52 +08:00
s_pSharedAnimationCache - > init ( ) ;
}
2010-12-31 14:56:24 +08:00
2012-04-19 14:35:52 +08:00
return s_pSharedAnimationCache ;
2012-03-16 13:42:53 +08:00
}
2010-12-31 14:56:24 +08:00
2013-07-12 06:24:23 +08:00
void AnimationCache : : destroyInstance ( )
2012-03-16 13:42:53 +08:00
{
CC_SAFE_RELEASE_NULL ( s_pSharedAnimationCache ) ;
}
2010-12-31 14:56:24 +08:00
2013-06-20 14:13:12 +08:00
bool AnimationCache : : init ( )
2012-03-16 13:42:53 +08:00
{
2013-06-20 14:13:12 +08:00
_animations = new Dictionary ( ) ;
2012-04-19 14:35:52 +08:00
return true ;
2012-03-16 13:42:53 +08:00
}
2013-06-20 14:13:12 +08:00
AnimationCache : : AnimationCache ( )
2013-06-15 14:03:30 +08:00
: _animations ( NULL )
2012-03-16 13:42:53 +08:00
{
}
2013-06-20 14:13:12 +08:00
AnimationCache : : ~ AnimationCache ( )
2012-03-16 13:42:53 +08:00
{
2012-04-19 14:35:52 +08:00
CCLOGINFO ( " cocos2d: deallocing %p " , this ) ;
2013-06-15 14:03:30 +08:00
CC_SAFE_RELEASE ( _animations ) ;
2012-03-16 13:42:53 +08:00
}
2010-12-31 14:56:24 +08:00
2013-06-20 14:13:12 +08:00
void AnimationCache : : addAnimation ( Animation * animation , const char * name )
2012-03-16 13:42:53 +08:00
{
2013-06-15 14:03:30 +08:00
_animations - > setObject ( animation , name ) ;
2012-03-16 13:42:53 +08:00
}
2013-06-20 14:13:12 +08:00
void AnimationCache : : removeAnimationByName ( const char * name )
2012-03-16 13:42:53 +08:00
{
if ( ! name )
2012-04-19 14:35:52 +08:00
{
return ;
}
2010-12-31 14:56:24 +08:00
2013-06-15 14:03:30 +08:00
_animations - > removeObjectForKey ( name ) ;
2012-03-16 13:42:53 +08:00
}
2010-12-31 14:56:24 +08:00
2013-06-20 14:13:12 +08:00
Animation * AnimationCache : : animationByName ( const char * name )
2012-03-16 13:42:53 +08:00
{
2013-06-20 14:13:12 +08:00
return ( Animation * ) _animations - > objectForKey ( name ) ;
2012-03-16 13:42:53 +08:00
}
2010-12-31 14:56:24 +08:00
2013-06-20 14:13:12 +08:00
void AnimationCache : : parseVersion1 ( Dictionary * animations )
2012-04-19 14:35:52 +08:00
{
2013-07-12 06:24:23 +08:00
SpriteFrameCache * frameCache = SpriteFrameCache : : getInstance ( ) ;
2012-04-19 14:35:52 +08:00
2013-06-20 14:13:12 +08:00
DictElement * pElement = NULL ;
2012-04-19 14:35:52 +08:00
CCDICT_FOREACH ( animations , pElement )
{
2013-07-09 14:40:43 +08:00
Dictionary * animationDict = static_cast < Dictionary * > ( pElement - > getObject ( ) ) ;
Array * frameNames = static_cast < Array * > ( animationDict - > objectForKey ( " frames " ) ) ;
2012-04-19 14:35:52 +08:00
float delay = animationDict - > valueForKey ( " delay " ) - > floatValue ( ) ;
2013-06-20 14:13:12 +08:00
Animation * animation = NULL ;
2012-04-19 14:35:52 +08:00
if ( frameNames = = NULL )
{
2013-06-20 14:13:12 +08:00
CCLOG ( " cocos2d: AnimationCache: Animation '%s' found in dictionary without any frames - cannot add to animation cache. " , pElement - > getStrKey ( ) ) ;
2012-04-19 14:35:52 +08:00
continue ;
}
2013-06-20 14:13:12 +08:00
Array * frames = Array : : createWithCapacity ( frameNames - > count ( ) ) ;
2012-04-19 14:35:52 +08:00
frames - > retain ( ) ;
2013-06-20 14:13:12 +08:00
Object * pObj = NULL ;
2012-04-19 14:35:52 +08:00
CCARRAY_FOREACH ( frameNames , pObj )
{
2013-07-09 14:29:51 +08:00
const char * frameName = static_cast < String * > ( pObj ) - > getCString ( ) ;
2013-07-18 07:56:19 +08:00
SpriteFrame * spriteFrame = frameCache - > getSpriteFrameByName ( frameName ) ;
2012-04-19 14:35:52 +08:00
if ( ! spriteFrame ) {
2013-06-20 14:13:12 +08:00
CCLOG ( " cocos2d: AnimationCache: Animation '%s' refers to frame '%s' which is not currently in the SpriteFrameCache. This frame will not be added to the animation. " , pElement - > getStrKey ( ) , frameName ) ;
2012-04-19 14:35:52 +08:00
continue ;
}
2013-06-20 14:13:12 +08:00
AnimationFrame * animFrame = new AnimationFrame ( ) ;
2012-04-19 14:35:52 +08:00
animFrame - > initWithSpriteFrame ( spriteFrame , 1 , NULL ) ;
frames - > addObject ( animFrame ) ;
animFrame - > release ( ) ;
}
if ( frames - > count ( ) = = 0 ) {
2013-06-20 14:13:12 +08:00
CCLOG ( " cocos2d: AnimationCache: None of the frames for animation '%s' were found in the SpriteFrameCache. Animation is not being added to the Animation Cache. " , pElement - > getStrKey ( ) ) ;
2012-04-19 14:35:52 +08:00
continue ;
} else if ( frames - > count ( ) ! = frameNames - > count ( ) ) {
2013-06-20 14:13:12 +08:00
CCLOG ( " cocos2d: AnimationCache: An animation in your dictionary refers to a frame which is not in the SpriteFrameCache. Some or all of the frames for the animation '%s' may be missing. " , pElement - > getStrKey ( ) ) ;
2012-04-19 14:35:52 +08:00
}
2013-06-20 14:13:12 +08:00
animation = Animation : : create ( frames , delay , 1 ) ;
2012-04-19 14:35:52 +08:00
2013-07-12 06:24:23 +08:00
AnimationCache : : getInstance ( ) - > addAnimation ( animation , pElement - > getStrKey ( ) ) ;
2012-04-19 14:35:52 +08:00
frames - > release ( ) ;
}
}
2013-06-20 14:13:12 +08:00
void AnimationCache : : parseVersion2 ( Dictionary * animations )
2012-04-19 14:35:52 +08:00
{
2013-07-12 06:24:23 +08:00
SpriteFrameCache * frameCache = SpriteFrameCache : : getInstance ( ) ;
2012-04-19 14:35:52 +08:00
2013-06-20 14:13:12 +08:00
DictElement * pElement = NULL ;
2012-04-19 14:35:52 +08:00
CCDICT_FOREACH ( animations , pElement )
{
const char * name = pElement - > getStrKey ( ) ;
2013-07-09 14:40:43 +08:00
Dictionary * animationDict = static_cast < Dictionary * > ( pElement - > getObject ( ) ) ;
2012-04-19 14:35:52 +08:00
2013-06-20 14:13:12 +08:00
const String * loops = animationDict - > valueForKey ( " loops " ) ;
2012-04-19 14:35:52 +08:00
bool restoreOriginalFrame = animationDict - > valueForKey ( " restoreOriginalFrame " ) - > boolValue ( ) ;
2013-07-09 14:40:43 +08:00
Array * frameArray = static_cast < Array * > ( animationDict - > objectForKey ( " frames " ) ) ;
2012-04-19 14:35:52 +08:00
if ( frameArray = = NULL ) {
2013-06-20 14:13:12 +08:00
CCLOG ( " cocos2d: AnimationCache: Animation '%s' found in dictionary without any frames - cannot add to animation cache. " , name ) ;
2012-04-19 14:35:52 +08:00
continue ;
}
// Array of AnimationFrames
2013-06-20 14:13:12 +08:00
Array * array = Array : : createWithCapacity ( frameArray - > count ( ) ) ;
2012-04-19 14:35:52 +08:00
array - > retain ( ) ;
2013-06-20 14:13:12 +08:00
Object * pObj = NULL ;
2012-04-19 14:35:52 +08:00
CCARRAY_FOREACH ( frameArray , pObj )
{
2013-07-09 14:29:51 +08:00
Dictionary * entry = static_cast < Dictionary * > ( pObj ) ;
2012-04-19 14:35:52 +08:00
const char * spriteFrameName = entry - > valueForKey ( " spriteframe " ) - > getCString ( ) ;
2013-07-18 07:56:19 +08:00
SpriteFrame * spriteFrame = frameCache - > getSpriteFrameByName ( spriteFrameName ) ;
2012-04-19 14:35:52 +08:00
if ( ! spriteFrame ) {
2013-06-20 14:13:12 +08:00
CCLOG ( " cocos2d: AnimationCache: Animation '%s' refers to frame '%s' which is not currently in the SpriteFrameCache. This frame will not be added to the animation. " , name , spriteFrameName ) ;
2012-04-19 14:35:52 +08:00
continue ;
}
float delayUnits = entry - > valueForKey ( " delayUnits " ) - > floatValue ( ) ;
2013-06-20 14:13:12 +08:00
Dictionary * userInfo = ( Dictionary * ) entry - > objectForKey ( " notification " ) ;
2012-04-19 14:35:52 +08:00
2013-06-20 14:13:12 +08:00
AnimationFrame * animFrame = new AnimationFrame ( ) ;
2012-04-19 14:35:52 +08:00
animFrame - > initWithSpriteFrame ( spriteFrame , delayUnits , userInfo ) ;
array - > addObject ( animFrame ) ;
animFrame - > release ( ) ;
}
float delayPerUnit = animationDict - > valueForKey ( " delayPerUnit " ) - > floatValue ( ) ;
2013-06-20 14:13:12 +08:00
Animation * animation = new Animation ( ) ;
2013-01-05 18:54:08 +08:00
animation - > initWithAnimationFrames ( array , delayPerUnit , 0 ! = loops - > length ( ) ? loops - > intValue ( ) : 1 ) ;
2012-04-19 14:35:52 +08:00
array - > release ( ) ;
animation - > setRestoreOriginalFrame ( restoreOriginalFrame ) ;
2013-07-12 06:24:23 +08:00
AnimationCache : : getInstance ( ) - > addAnimation ( animation , name ) ;
2012-04-19 14:35:52 +08:00
animation - > release ( ) ;
}
}
2013-06-20 14:13:12 +08:00
void AnimationCache : : addAnimationsWithDictionary ( Dictionary * dictionary )
2012-04-19 14:35:52 +08:00
{
2013-06-20 14:13:12 +08:00
Dictionary * animations = ( Dictionary * ) dictionary - > objectForKey ( " animations " ) ;
2012-04-19 14:35:52 +08:00
if ( animations = = NULL ) {
2013-06-20 14:13:12 +08:00
CCLOG ( " cocos2d: AnimationCache: No animations were found in provided dictionary. " ) ;
2012-04-19 14:35:52 +08:00
return ;
}
unsigned int version = 1 ;
2013-06-20 14:13:12 +08:00
Dictionary * properties = ( Dictionary * ) dictionary - > objectForKey ( " properties " ) ;
2012-04-19 14:35:52 +08:00
if ( properties )
{
version = properties - > valueForKey ( " format " ) - > intValue ( ) ;
2013-06-20 14:13:12 +08:00
Array * spritesheets = ( Array * ) properties - > objectForKey ( " spritesheets " ) ;
2012-04-19 14:35:52 +08:00
2013-06-20 14:13:12 +08:00
Object * pObj = NULL ;
2012-04-19 14:35:52 +08:00
CCARRAY_FOREACH ( spritesheets , pObj )
{
2013-07-09 14:29:51 +08:00
String * name = static_cast < String * > ( pObj ) ;
2013-07-12 06:24:23 +08:00
SpriteFrameCache : : getInstance ( ) - > addSpriteFramesWithFile ( name - > getCString ( ) ) ;
2012-04-19 14:35:52 +08:00
}
}
switch ( version ) {
case 1 :
parseVersion1 ( animations ) ;
break ;
case 2 :
parseVersion2 ( animations ) ;
break ;
default :
CCAssert ( false , " Invalid animation format " ) ;
}
}
/** Read an NSDictionary from a plist file and parse it automatically for animations */
2013-06-20 14:13:12 +08:00
void AnimationCache : : addAnimationsWithFile ( const char * plist )
2012-04-19 14:35:52 +08:00
{
CCAssert ( plist , " Invalid texture file name " ) ;
2013-07-12 06:24:23 +08:00
std : : string path = FileUtils : : getInstance ( ) - > fullPathForFilename ( plist ) ;
2013-06-20 14:13:12 +08:00
Dictionary * dict = Dictionary : : createWithContentsOfFile ( path . c_str ( ) ) ;
2012-04-19 14:35:52 +08:00
CCAssert ( dict , " CCAnimationCache: File could not be found " ) ;
addAnimationsWithDictionary ( dict ) ;
2012-03-16 13:42:53 +08:00
}
NS_CC_END