本文来自http://blog.csdn.net/runaying ,引用必须注明出处!
cocos2d-x节点(CCArray.h)API
温馨提醒:为了大家能更好学习,强烈推荐大家看看本人的这篇博客 Cocos2d-X权威指南笔记
这个类非常常用,可以存储任何对象,它可以模拟 C的指针,
///\cocos2d-x-3.0alpha0\cocos2dx\cocoa
//这个类非常常用,可以存储任何对象,它可以模拟 C 的指针,#ifndef __CCARRAY_H__
#define __CCARRAY_H__#define CC_USE_ARRAY_VECTOR 0#if CC_USE_ARRAY_VECTOR
#include <vector>
#include <algorithm>
#include "cocoa/CCObject.h"
#include "ccMacros.h"
#else
#include "support/data_support/ccCArray.h"
#endif#if CC_USE_ARRAY_VECTOR
/*** 一个来自RCBase类的引用计数管理指针* 可以作为 C 指针使用* Original code: http://www.codeproject.com/Articles/64111/Building-a-Quick-and-Handy-Reference-Counting-Clas //源代码* License: http://www.codeproject.com/info/cpol10.aspx //许可*/
template < class T >
class RCPtr
{
public://使用 C 指针的构造函数//e.g. RCPtr< T > x = new T();RCPtr(T* ptr = nullptr): _ptr(ptr){if(ptr != nullptr) {ptr->retain();}}//Copy 构造函数RCPtr(const RCPtr &ptr): _ptr(ptr._ptr){// printf("Array: copy constructor: %p\n", this);if(_ptr != NULL) {_ptr->retain();}}//Move 构造函数RCPtr(RCPtr &&ptr): _ptr(ptr._ptr){// printf("Array: Move Constructor: %p\n", this);ptr._ptr = nullptr;}~RCPtr(){// printf("Array: Destructor: %p\n", this);if(_ptr != nullptr) {_ptr->release();}}//分配一个指针//e.g. x = new T();RCPtr &operator=(T* ptr){// printf("Array: operator= T*: %p\n", this);//以下获取和释放操作必须执行//按照这个顺序来处理 ptr == _ptr 的情况//参阅 David Garlisch 的评论)if(ptr != nullptr) {ptr->retain();}if(_ptr != nullptr) {_ptr->release();}_ptr = ptr;return (*this);}//分配另一个 RCPtrRCPtr &operator=(const RCPtr &ptr){// printf("Array: operator= const&: %p\n", this);return (*this) = ptr._ptr;}//Retrieve(检索)真实的指针T* get() const{return _ptr;}//一些重载 operators 可以方便使用一个 RCPtr//作为一个传统的 C 指针.//如果没有这些 operators, 仍然可以使用但是透明度较低//get() 方法来访问指针.T* operator->() const {return _ptr;} //x->memberT &operator*() const {return *_ptr;} //*x, (*x).memberexplicit operator T*() const {return _ptr;} //T* y = x;explicit operator bool() const {return _ptr != nullptr;} //if(x) {/*x is not NULL*/}bool operator==(const RCPtr &ptr) {return _ptr == ptr._ptr;}bool operator==(const T *ptr) {return _ptr == ptr;}private:T *_ptr; //Actual pointer(真实的指针)
};
#endif // CC_USE_ARRAY_VECTOR/*** @addtogroup data_structures* @{*//** @def CCARRAY_FOREACH一个用来遍历 Array 的宏. 他比 "fast enumeration" 接口还要快.@since v0.99.4*//*In cocos2d-iphone 1.0.0, 这个 macro(宏) 已经更新;像这个:#define CCARRAY_FOREACH(__array__, __object__) \if (__array__ && __array__->data->num > 0) \for(id *__arr__ = __array__->data->arr, *end = __array__->data->arr + __array__->data->num-1; \__arr__ <= end && ((__object__ = *__arr__) != nil || true); \__arr__++)我发现他不能在 C++ 里面工作.所以他看起来和 1.0.0-rc3 版本一样. ---By Bin*/#if CC_USE_ARRAY_VECTOR
#define CCARRAY_FOREACH(__array__, __object__) \
if (__array__) \
for( auto __it__ = (__array__)->data.begin(); \
__it__ != (__array__)->data.end() && ((__object__) = __it__->get()) != nullptr; \
++__it__)#define CCARRAY_FOREACH_REVERSE(__array__, __object__) \
if (__array__) \
for( auto __it__ = (__array__)->data.rbegin(); \
__it__ != (__array__)->data.rend() && ((__object__) = __it__->get()) != nullptr; \
++__it__ )#define CCARRAY_VERIFY_TYPE(__array__, __type__) void(0)#else // ! CC_USE_ARRAY_VECTOR --------------------------#define CCARRAY_FOREACH(__array__, __object__) \
if ((__array__) && (__array__)->data->num > 0) \
for(Object** __arr__ = (__array__)->data->arr, **__end__ = (__array__)->data->arr + (__array__)->data->num-1; \
__arr__ <= __end__ && (((__object__) = *__arr__) != NULL/* || true*/); \
__arr__++)#define CCARRAY_FOREACH_REVERSE(__array__, __object__) \
if ((__array__) && (__array__)->data->num > 0) \
for(Object** __arr__ = (__array__)->data->arr + (__array__)->data->num-1, **__end__ = (__array__)->data->arr; \
__arr__ >= __end__ && (((__object__) = *__arr__) != NULL/* || true*/); \
__arr__--)#if defined(COCOS2D_DEBUG) && (COCOS2D_DEBUG > 0)
#define CCARRAY_VERIFY_TYPE(__array__, __type__) \
do { \
if ((__array__) && (__array__)->data->num > 0) \
for(Object** __arr__ = (__array__)->data->arr, \
**__end__ = (__array__)->data->arr + (__array__)->data->num-1; __arr__ <= __end__; __arr__++) \
CCASSERT(dynamic_cast<__type__>(*__arr__), "element type is wrong!"); \
} while(false)
#else
#define CCARRAY_VERIFY_TYPE(__array__, __type__) void(0)
#endif#endif // ! CC_USE_ARRAY_VECTOR// Common defines ----------------------------------------------------------------------------------------------- //常见的定义#define arrayMakeObjectsPerformSelector(pArray, func, elementType) \
do { \
if(pArray && pArray->count() > 0) \
{ \
Object* child; \
CCARRAY_FOREACH(pArray, child) \
{ \
elementType pNode = static_cast<elementType>(child); \
if(pNode) \
{ \
pNode->func(); \
} \
} \
} \
} \
while(false)#define arrayMakeObjectsPerformSelectorWithObject(pArray, func, object, elementType) \
do { \
if(pArray && pArray->count() > 0) \
{ \
Object* child; \
CCARRAY_FOREACH(pArray, child) \
{ \
elementType pNode = static_cast<elementType>(child); \
if(pNode) \
{ \
pNode->func(object); \
} \
} \
} \
} \
while(false)NS_CC_BEGINclass CC_DLL Array : public Object, public Clonable
{
public:/** 创建一个空的 array.默认容量是10* @js NA* @lua NA*/static Array* create();/** 使用 objects 创建一个 array* @js NA*/static Array* create(Object* object, ...) CC_REQUIRES_NULL_TERMINATION;/** 使用 object 创建一个 array* @js NA*/static Array* createWithObject(Object* object);/** 使用指定容量创建一个 array* @js NA*/static Array* createWithCapacity(int capacity);/** 使用一个已经存在的 array 创建一个 array* @js NA*/static Array* createWithArray(Array* otherArray);/**@brief 从 file 生成一个 array 指针@param pFileName *.plist 文件的文件名@return 从 file 生成的 array 指针* @js NA*/static Array* createWithContentsOfFile(const char* pFileName);/*@brief 他和 arrayWithContentsOfFile() 的含义相同,但它不能自动释放,所以调用者应该手动调用调用release()。* @js NA* @lua NA*/static Array* createWithContentsOfFileThreadSafe(const char* pFileName);/*** @js NA* @lua NA*/~Array();/** 初始化 array* @js NA* @lua NA*/bool init();/** 使用 object 初始化一个 array* @js NA* @lua NA*/bool initWithObject(Object* object);/** 使用 objects 初始化一个 array* @js NA* @lua NA*/bool initWithObjects(Object* object, ...) CC_REQUIRES_NULL_TERMINATION;/** 使用指定容量初始化一个 array* @js NA* @lua NA*/bool initWithCapacity(int capacity);/** 使用一个已经存在的 array 创建一个 array* @js NA* @lua NA*/bool initWithArray(Array* otherArray);// 查询 Array/** Returns 这个 array 中元素的数量* @js NA*/int count() const{
#if CC_USE_ARRAY_VECTORreturn data.size();
#elsereturn data->num;
#endif}/** Returns 这个 array 的容量* @js NA*/int capacity() const{
#if CC_USE_ARRAY_VECTORreturn data.capacity();
#elsereturn data->max;
#endif}/** Returns 一个 certain(确定)对象的索引, return UINT_MAX 如果不包含这个对象返回* @js NA* @lua NA*/int getIndexOfObject(Object* object) const;/*** @js NA*/CC_DEPRECATED_ATTRIBUTE int indexOfObject(Object* object) const { return getIndexOfObject(object); }/** Returns 返回 certain 索引对应的元素* @js NA* @lua NA*/Object* getObjectAtIndex(int index){CCASSERT(index>=0 && index < count(), "index out of range in getObjectAtIndex()");
#if CC_USE_ARRAY_VECTORreturn data[index].get();
#elsereturn data->arr[index];
#endif}CC_DEPRECATED_ATTRIBUTE Object* objectAtIndex(int index) { return getObjectAtIndex(index); }/** Returns 这个 array 的最后一个元素* @js NA*/Object* getLastObject(){
#if CC_USE_ARRAY_VECTORreturn data.back().get();
#elseif(data->num > 0)return data->arr[data->num-1];return nullptr;
#endif}/*** @js NA*/CC_DEPRECATED_ATTRIBUTE Object* lastObject() { return getLastObject(); }/** Returns 一个随机的 element* @js NA* @lua NA*/Object* getRandomObject();/*** @js NA*/CC_DEPRECATED_ATTRIBUTE Object* randomObject() { return getRandomObject(); }/** Returns object 是否存在于 array 的标记.* @js NA*/bool containsObject(Object* object) const;/** @since 1.1* @js NA*/bool isEqualToArray(Array* otherArray);// Adding Objects/** Add 一个确定的 object* @js NA*/void addObject(Object* object);/*** @js NA*//** Add 添加一个已经存在 array 里面的所有的元素* @js NA*/void addObjectsFromArray(Array* otherArray);/** Insert a certain object at a certain index* @js NA*/void insertObject(Object* object, int index);/** sets 添加一个已经存在 object 到指定索引* @js NA* @lua NA*/void setObject(Object* object, int index);/** sets 一个已经存在 object 到指定索引, without retaining(不保存) . 所以请谨慎使用* @js NA* @lua NA*/void fastSetObject(Object* object, int index){
#if CC_USE_ARRAY_VECTORsetObject(object, index);
#else// no retaindata->arr[index] = object;
#endif}/*** @js NA* @lua NA*/void swap( int indexOne, int indexTwo ){CCASSERT(indexOne >=0 && indexOne < count() && indexTwo >= 0 && indexTwo < count(), "Invalid indices");
#if CC_USE_ARRAY_VECTORstd::swap(data[indexOne], data[indexTwo]);
#elsestd::swap(data->arr[indexOne], data->arr[indexTwo]);
#endif}// Removing Objects/** Remove 最后一个 object* @js NA*/void removeLastObject(bool releaseObj = true);/** Remove 一个已经存在 object* @js NA*/void removeObject(Object* object, bool releaseObj = true);/** Remove 一个 certain 索引对应的对象* @js NA*/void removeObjectAtIndex(int index, bool releaseObj = true);/** Remove all elements* @js NA*/void removeObjectsInArray(Array* otherArray);/** Remove all objects* @js NA*/void removeAllObjects();/** 快速移除 一个已经存在的对象* @js NA*/void fastRemoveObject(Object* object);/** 快速移除 一个 certain 索引所对应的对象* @js NA*/void fastRemoveObjectAtIndex(int index);// Rearranging Content 重新排序内容/** 交换两个元素* @js NA*/void exchangeObject(Object* object1, Object* object2);/** 交换 3 个 certain 索引所对应的对象* @js NA*/void exchangeObjectAtIndex(int index1, int index2);/** 替换指定索引对应的对象* @js NA*/void replaceObjectAtIndex(int index, Object* object, bool releaseObject = true);/** Revers(反向) the array* @js NA*/void reverseObjects();/* 收缩 array 这样的内存占用量,对应的 items 数* @js NA*/void reduceMemoryFootprint();/* override functions* @js NA*/virtual void acceptVisitor(DataVisitor &visitor);/*** @js NA* @lua NA*/virtual Array* clone() const;// ------------------------------------------// Iterators// ------------------------------------------
#if CC_USE_ARRAY_VECTORtypedef std::vector<RCPtr<Object>>::iterator iterator;typedef std::vector<RCPtr<Object>>::const_iterator const_iterator;/*** @js NA* @lua NA*/iterator begin() { return data.begin(); }/*** @js NA* @lua NA*/iterator end() { return data.end(); }const_iterator cbegin() { return data.cbegin(); }/*** @js NA* @lua NA*/const_iterator cend() { return data.cend(); }std::vector<RCPtr<Object>> data;#else/*** @js NA* @lua NA*/Object** begin() { return &data->arr[0]; }/*** @js NA* @lua NA*/Object** end() { return &data->arr[data->num]; }ccArray* data;#endif//protected:/*** @js NA* @lua NA*/Array();
};// end of data_structure group
/// @}NS_CC_END#endif // __CCARRAY_H__