本文来自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);
}
//分配另一个 RCPtr
RCPtr &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->member
T &operator*() const {return *_ptr;} //*x, (*x).member
explicit 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_BEGIN
class 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_VECTOR
return data.size();
#else
return data->num;
#endif
}
/** Returns 这个 array 的容量
* @js NA
*/
int capacity() const
{
#if CC_USE_ARRAY_VECTOR
return data.capacity();
#else
return 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_VECTOR
return data[index].get();
#else
return data->arr[index];
#endif
}
CC_DEPRECATED_ATTRIBUTE Object* objectAtIndex(int index) { return getObjectAtIndex(index); }
/** Returns 这个 array 的最后一个元素
* @js NA
*/
Object* getLastObject()
{
#if CC_USE_ARRAY_VECTOR
return data.back().get();
#else
if(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_VECTOR
setObject(object, index);
#else
// no retain
data->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_VECTOR
std::swap(data[indexOne], data[indexTwo]);
#else
std::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_VECTOR
typedef 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__