cocos2d::Value
の中身を良い感じに出力する
PHPのvar_dump()
みたいな感じ。
void ValueHelper::dumpValue(const cocos2d::Value &value)
{
CCLOG("%s", ValueHelper::getDumpString(value).c_str());
}
std::string ValueHelper::getDumpString(const cocos2d::Value &value,
unsigned int level /* = 1 */)
{
std::string ret;
switch (value.getType()) {
case Value::Type::NONE: ret = "NONE,\n"; break;
case Value::Type::BYTE: ret = StringUtils::format("BYTE(%c),\n", value.asByte()); break;
case Value::Type::INTEGER: ret = StringUtils::format("INTEGER(%d),\n", value.asInt()); break;
case Value::Type::FLOAT: ret = StringUtils::format("FLOAT(%f),\n", value.asFloat()); break;
case Value::Type::DOUBLE: ret = StringUtils::format("DOUBLE(%f),\n", value.asDouble()); break;
case Value::Type::BOOLEAN: ret = StringUtils::format("BOOLEAN(%s),\n", value.asBool() ? "true" : "false"); break;
case Value::Type::STRING: ret = StringUtils::format("STRING(%s),\n", value.asString().c_str()); break;
case Value::Type::VECTOR:
ret += "VECTOR(" + StrUtils::intToString((int)value.asValueVector().size()) + ")(\n";
for (Value child : value.asValueVector()) {
// 階層によるインデント
for (int i=0; i<level; i++) ret += " ";
ret += ValueHelper::getDumpString(child, level+1);
}
// 階層によるインデント
for (int i=0; i<level-1; i++) ret += " ";
ret += "),\n";
break;
case Value::Type::MAP:
ret += "MAP(" + StrUtils::intToString((int)value.asValueMap().size()) + "){\n";
for (ValueMap::const_iterator itr = value.asValueMap().begin(); itr != value.asValueMap().end(); itr++) {
// 階層によるインデント
for (int i=0; i<level; i++) ret += " ";
ret += StringUtils::format("\"%s\": ", (*itr).first.c_str()) + ValueHelper::getDumpString((*itr).second, level+1);
}
// 階層によるインデント
for (int i=0; i<level-1; i++) ret += " ";
ret += "},\n";
break;
case Value::Type::INT_KEY_MAP:
ret += "INT_KEY_MAP(" + StrUtils::intToString((int)value.asIntKeyMap().size()) + "){\n";
for (ValueMap::const_iterator itr = value.asValueMap().begin(); itr != value.asValueMap().end(); itr++) {
// 階層によるインデント
for (int i=0; i<level; i++) ret += " ";
ret += StringUtils::format("\"%s\": ", (*itr).first.c_str()) + ValueHelper::getDumpString((*itr).second, level+1);
}
// 階層によるインデント
for (int i=0; i<level-1; i++) ret += " ";
ret += "},\n";
break;
default:
NERROR("引数 value の getType() の値が不正です。: %d", value.getType());
break;
}
return ret;
}
cocos2d::Value
の中身を細かく比較する
bool ValueHelper::isEqual(const cocos2d::Value &value1,
const cocos2d::Value &value2)
{
// 型が違えばもう違う
if (value1.getType() != value2.getType()) return false;
/***** 以下、value1とvalue2の型が等しいことは保証される *****/
switch (value1.getType()) {
case Value::Type::NONE: return true; // 中身が無いので比較する必要無し
case Value::Type::BYTE: return (value1.asByte() == value2.asByte());
case Value::Type::INTEGER: return (value1.asInt() == value2.asInt());
case Value::Type::FLOAT: return (value1.asFloat() == value2.asFloat());
case Value::Type::DOUBLE: return (value1.asDouble() == value2.asDouble());
case Value::Type::BOOLEAN: return (value1.asBool() == value2.asBool());
case Value::Type::STRING: return (value1.asString() == value2.asString());
case Value::Type::VECTOR: return ValueHelper::isEqualVector(value1.asValueVector(), value2.asValueVector());
case Value::Type::MAP: return ValueHelper::isEqualMap(value1.asValueMap(), value2.asValueMap());
case Value::Type::INT_KEY_MAP: return ValueHelper::isEqualIntKeyMap(value1.asIntKeyMap(), value2.asIntKeyMap());
}
return false;
}
bool ValueHelper::isEqualVector(const cocos2d::ValueVector vector1,
const cocos2d::ValueVector vector2,
const bool considerOrder /* = false */)
{
// 要素数が違えばもう違う
if (vector1.size() != vector2.size()) return false;
/***** 以下、vector1とvector2の要素数が等しいことは保証される *****/
if (considerOrder) {
// 順序を考慮する場合
// vector1, vector2の同じ要素番号に格納されている値が、全て同じなら同じ。
for (unsigned int i=0; i<vector1.size(); i++)
// 一つでも違えば違う。
if (!ValueHelper::isEqual(vector1.at(i), vector2.at(i))) return false;
}
else {
// 順序を考慮しない場合
// 要素数が等しいことは保証されているので、value1の要素が全てvalue2に入っていれば同じ。
for (Value childValue1 : vector1)
// 一つでも違えば違う。
if (!ValueHelper::isContainsValue(vector2, childValue1)) return false;
}
return true;
}
bool ValueHelper::isEqualMap(const cocos2d::ValueMap &map1,
const cocos2d::ValueMap &map2)
{
// 要素数が違えばもう違う
if (map1.size() != map2.size()) return false;
/**** 以下、map1とmap2の要素数が等しいことは保証される *****/
// 要素数が等しいことは保証されているので、value1の全ての要素について
// - 同じキーが有る
// - そのキーに対する値が等しい
// なら同じ。
for (std::pair<std::string, Value> pair : map1) {
const std::string key = pair.first;
const Value childValue = pair.second;
// 一つでも違えば違う。
if (!ValueHelper::isExistsKey(map2, key)
||
!ValueHelper::isEqual(childValue, map2.at(key))) return false;
}
return true;
}
bool ValueHelper::isEqualIntKeyMap(const cocos2d::ValueMapIntKey &map1,
const cocos2d::ValueMapIntKey &map2)
{
// 要素数が違えばもう違う
if (map1.size() != map2.size()) return false;
/**** 以下、map1とmap2の要素数が等しいことは保証される *****/
// 要素数が等しいことは保証されているので、value1の全ての要素について
// - 同じキーが有る
// - そのキーに対する値が等しい
// なら同じ。
for (std::pair<int, Value> pair : map1) {
const int key = pair.first;
const Value childValue = pair.second;
// 一つでも違えば違う。
if (!ValueHelper::isExistsKey(map2, key)
||
!ValueHelper::isEqual(childValue, map2.at(key))) return false;
}
return true;
}
cocos2d::ValueMap
cocos2d::ValueMapIntKey
の中に該当するキーが存在するか調べる
bool ValueHelper::isExistsKey(const cocos2d::ValueMap &map,
const std::string &key)
{
return (map.find(key) != map.end());
}
bool ValueHelper::isExistsKey(const cocos2d::ValueMapIntKey &map,
const int key)
{
return (map.find(key) != map.end());
}
cocos2d::ValueVector
の中に該当する値があるか調べる
bool ValueHelper::isContainsValue(const cocos2d::ValueVector &vector,
const cocos2d::Value &value)
{
for (Value comparison : vector)
// 同値が見つかった時点でtrueを返却
if (ValueHelper::isEqual(value, comparison)) return true;
return false;
}