#ifndef __CCDATAVISITOR_H__
#define __CCDATAVISITOR_H__
#include "platform/CCPlatformMacros.h"
#include <string>
NS_CC_BEGIN
class CCObject;
class CCBool;
class CCInteger;
class CCFloat;
class CCDouble;
class CCString;
class CCArray;
class CCDictionary;
class CCSet;
/**
* Visitor(访问者) that helps to perform(执行) action that depends on(取决于,依赖于) polymorphic(多态的) object type
*
* Use cases://使用情况
* - data serialization(序列化;串行化;连载长篇),
* - pretty(漂亮的) printing(印刷) of \a CCObject * //打印一个object的指针
* - safe value reading from \a CCArray, \a CCDictionary, \a CCSet //从数组中安全的读取值
*
* Usage://用法
* 1. subclass(子集) CCDataVisitor
* 2. overload visit() methods for object that you need to handle(重载visit)
* 3. handle(操作) other objects in \a visitObject()() //在visitObject()中操作其它object
* 4. pass your visitor to \a CCObject::acceptVisitor() //把visitor传递给CCObject::acceptVisitor()
*/
class CC_DLL CCDataVisitor
{
public:
virtual ~CCDataVisitor() {}
/** default method, called from non-overloaded(非 超载的) methods and for unrecognized(未识别的) objects */
virtual void visitObject(const CCObject *p) = 0;
virtual void visit(const CCBool *p);
void CCDataVisitor::visit(const CCBool *value)
{
visitObject(value);
}
virtual void visit(const CCInteger *p);
virtual void visit(const CCFloat *p);
virtual void visit(const CCDouble *p);
virtual void visit(const CCString *p);
virtual void visit(const CCArray *p);
virtual void visit(const CCDictionary *p);
virtual void visit(const CCSet *p);
};
class CC_DLL CCPrettyPrinter : public CCDataVisitor
{
public:
CCPrettyPrinter(int indentLevel = 0);
CCPrettyPrinter::CCPrettyPrinter(int indentLevel/* = 0 */)
{
setIndentLevel(indentLevel);
}
virtual void clear();
void CCPrettyPrinter::clear()
{
_result.clear();
}
virtual std::string getResult();
std::string CCPrettyPrinter::getResult()
{
return _result;
}
virtual void visitObject(const CCObject *p);
void CCPrettyPrinter::visitObject(const CCObject *p)
{
char buf[50] = {0};
sprintf(buf, "%p", p);
_result += buf;
}
virtual void visit(const CCBool * p);
virtual void visit(const CCInteger *p);
virtual void visit(const CCFloat *p);
void CCPrettyPrinter::visit(const CCFloat *p)
{
char buf[50] = {0};
sprintf(buf, "%f", p->getValue());
_result += buf;
}
virtual void visit(const CCDouble *p);
void CCPrettyPrinter::visit(const CCDouble *p)
{
char buf[50] = {0};
sprintf(buf, "%lf", p->getValue());
_result += buf;
}
virtual void visit(const CCString *p);
void CCPrettyPrinter::visit(const CCString *p)
{
_result += p->getCString();
}
virtual void visit(const CCArray *p);
void CCPrettyPrinter::visit(const CCArray *p)
{
_result += "\n";
_result += _indentStr;
_result += "<array>\n";
setIndentLevel(_indentLevel+1);
CCObject* obj;
int i = 0;
char buf[50] = {0};
CCARRAY_FOREACH(p, obj)
{
if (i > 0) {
_result += "\n";
}
sprintf(buf, "%s%02d: ", _indentStr.c_str(), i);
_result += buf;
CCPrettyPrinter v(_indentLevel);
obj->acceptVisitor(v);
_result += v.getResult();
i++;
}
setIndentLevel(_indentLevel-1);
_result += "\n";
_result += _indentStr;
_result += "</array>";
}
virtual void visit(const CCDictionary *p);
virtual void visit(const CCSet *p);
private:
void setIndentLevel(int indentLevel);
void CCPrettyPrinter::setIndentLevel(int indentLevel)
{
_indentLevel = indentLevel;
_indentStr.clear();
for (int i = 0; i < _indentLevel; ++i) {
_indentStr += "\t";
}
}
int _indentLevel;
std::string _indentStr;
std::string _result;
};
NS_CC_END
#endif