Refactor CCFileUtils-apple to remove code duplication (#15645)

* Refactor CCFileUtils-apple to remove code duplication of conversion from CCValue to NSObject and vise versa

* CCFileUtilsApple: rename helper functions
This commit is contained in:
Shulepov 2016-05-23 14:26:19 +04:00 committed by minggo
parent 16a1605927
commit 758425cfd5
1 changed files with 95 additions and 213 deletions

View File

@ -52,18 +52,75 @@ private:
NSBundle* bundle_;
};
static void addValueToDict(id nsKey, id nsValue, ValueMap& dict);
static void addObjectToNSDict(const std::string& key, const Value& value, NSMutableDictionary *dict);
static id convertCCValueToNSObject(const cocos2d::Value &value);
static cocos2d::Value convertNSObjectToCCValue(id object);
static void addItemToArray(id item, ValueVector& array)
static void addNSObjectToCCMap(id nsKey, id nsValue, ValueMap& dict);
static void addCCValueToNSDictionary(const std::string& key, const Value& value, NSMutableDictionary *dict);
static void addNSObjectToCCVector(id item, ValueVector& array);
static void addCCValueToNSArray(const Value& value, NSMutableArray *array);
static id convertCCValueToNSObject(const cocos2d::Value &value)
{
switch (value.getType())
{
case Value::Type::NONE:
return [NSNull null];
case Value::Type::STRING:
return [NSString stringWithCString:value.asString().c_str() encoding:NSUTF8StringEncoding];
case Value::Type::BYTE:
return [NSNumber numberWithInt:value.asByte()];
case Value::Type::INTEGER:
return [NSNumber numberWithInt:value.asInt()];
case Value::Type::UNSIGNED:
return [NSNumber numberWithUnsignedInt:value.asUnsignedInt()];
case Value::Type::FLOAT:
return [NSNumber numberWithFloat:value.asFloat()];
case Value::Type::DOUBLE:
return [NSNumber numberWithDouble:value.asDouble()];
case Value::Type::BOOLEAN:
return [NSNumber numberWithBool:value.asBool()];
case Value::Type::VECTOR: {
NSMutableArray *array = [NSMutableArray array];
const ValueVector &vector = value.asValueVector();
for (const auto &e : vector) {
addCCValueToNSArray(e, array);
}
return array;
}
case Value::Type::MAP: {
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
const ValueMap &map = value.asValueMap();
for (auto iter = map.begin(); iter != map.end(); ++iter) {
addCCValueToNSDictionary(iter->first, iter->second, dictionary);
}
return dictionary;
}
case Value::Type::INT_KEY_MAP:
break;
}
return [NSNull null];
}
static cocos2d::Value convertNSObjectToCCValue(id item)
{
// add string value into array
if ([item isKindOfClass:[NSString class]])
{
array.push_back(Value([item UTF8String]));
return;
return Value([item UTF8String]);
}
// add number value into array(such as int, float, bool and so on)
// the value is a number
if ([item isKindOfClass:[NSNumber class]])
@ -73,23 +130,23 @@ static void addItemToArray(id item, ValueVector& array)
if(num == (void*)kCFBooleanFalse || num == (void*)kCFBooleanTrue)
{
bool v = [num boolValue];
array.push_back(Value(v));
return Value(v);
}
else if(strcmp(numType, @encode(float)) == 0)
{
array.push_back(Value([num floatValue]));
return Value([num floatValue]);
}
else if(strcmp(numType, @encode(double)) == 0)
{
array.push_back(Value([num doubleValue]));
return Value([num doubleValue]);
}
else{
array.push_back(Value([num intValue]));
else
{
return Value([num intValue]);
}
return;
}
// add dictionary value into array
if ([item isKindOfClass:[NSDictionary class]])
{
@ -97,226 +154,51 @@ static void addItemToArray(id item, ValueVector& array)
for (id subKey in [item allKeys])
{
id subValue = [item objectForKey:subKey];
addValueToDict(subKey, subValue, dict);
addNSObjectToCCMap(subKey, subValue, dict);
}
array.push_back(Value(dict));
return;
return Value(dict);
}
// add array value into array
if ([item isKindOfClass:[NSArray class]])
{
ValueVector subArray;
for (id subItem in item)
{
addItemToArray(subItem, subArray);
addNSObjectToCCVector(subItem, subArray);
}
array.push_back(Value(subArray));
return;
return Value(subArray);
}
return Value::Null;
}
static void addObjectToNSArray(const Value& value, NSMutableArray *array)
static void addNSObjectToCCVector(id item, ValueVector& array)
{
// add string into array
if (value.getType() == Value::Type::STRING)
{
NSString *element = [NSString stringWithCString:value.asString().c_str() encoding:NSUTF8StringEncoding];
[array addObject:element];
return;
}
//add float into array
if (value.getType() == Value::Type::FLOAT) {
NSNumber *number = [NSNumber numberWithFloat:value.asFloat()];
[array addObject:number];
}
//add double into array
if (value.getType() == Value::Type::DOUBLE) {
NSNumber *number = [NSNumber numberWithDouble:value.asDouble()];
[array addObject:number];
}
//add boolean into array
if (value.getType() == Value::Type::BOOLEAN) {
NSNumber *element = [NSNumber numberWithBool:value.asBool()];
[array addObject:element];
}
if (value.getType() == Value::Type::INTEGER) {
NSNumber *element = [NSNumber numberWithInt:value.asInt()];
[array addObject:element];
}
//todo: add date and data support
// add array into array
if (value.getType() == Value::Type::VECTOR)
{
NSMutableArray *element = [NSMutableArray array];
ValueVector valueArray = value.asValueVector();
for (const auto &e : valueArray)
{
addObjectToNSArray(e, element);
}
[array addObject:element];
return;
}
// add dictionary value into array
if (value.getType() == Value::Type::MAP)
{
NSMutableDictionary *element = [NSMutableDictionary dictionary];
auto valueDict = value.asValueMap();
for (auto iter = valueDict.begin(); iter != valueDict.end(); ++iter)
{
addObjectToNSDict(iter->first, iter->second, element);
}
[array addObject:element];
}
array.push_back(convertNSObjectToCCValue(item));
}
static void addValueToDict(id nsKey, id nsValue, ValueMap& dict)
static void addCCValueToNSArray(const Value& value, NSMutableArray *array)
{
[array addObject:convertCCValueToNSObject(value)];
}
static void addNSObjectToCCMap(id nsKey, id nsValue, ValueMap& dict)
{
// the key must be a string
CCASSERT([nsKey isKindOfClass:[NSString class]], "The key should be a string!");
std::string key = [nsKey UTF8String];
// the value is a string
if ([nsValue isKindOfClass:[NSString class]])
{
dict[key] = Value([nsValue UTF8String]);
return;
}
// the value is a number
if ([nsValue isKindOfClass:[NSNumber class]])
{
NSNumber* num = nsValue;
const char* numType = [num objCType];
if(num == (void*)kCFBooleanFalse || num == (void*)kCFBooleanTrue)
{
bool v = [num boolValue];
dict[key] = Value(v);
}
else if(strcmp(numType, @encode(float)) == 0)
{
dict[key] = Value([num floatValue]);
}
else if(strcmp(numType, @encode(double)) == 0)
{
dict[key] = Value([num doubleValue]);
}
else{
dict[key] = Value([num intValue]);
}
return;
}
// the value is a new dictionary
if ([nsValue isKindOfClass:[NSDictionary class]])
{
ValueMap subDict;
for (id subKey in [nsValue allKeys])
{
id subValue = [nsValue objectForKey:subKey];
addValueToDict(subKey, subValue, subDict);
}
dict[key] = Value(subDict);
return;
}
// the value is a array
if ([nsValue isKindOfClass:[NSArray class]])
{
ValueVector valueArray;
for (id item in nsValue)
{
addItemToArray(item, valueArray);
}
dict[key] = Value(valueArray);
return;
}
dict[key] = convertNSObjectToCCValue(nsValue);
}
static void addObjectToNSDict(const std::string& key, const Value& value, NSMutableDictionary *dict)
static void addCCValueToNSDictionary(const std::string& key, const Value& value, NSMutableDictionary *dict)
{
NSString *NSkey = [NSString stringWithCString:key.c_str() encoding:NSUTF8StringEncoding];
// the object is a Dictionary
if (value.getType() == Value::Type::MAP)
{
NSMutableDictionary *dictElement = [NSMutableDictionary dictionary];
ValueMap subDict = value.asValueMap();
for (auto iter = subDict.begin(); iter != subDict.end(); ++iter)
{
addObjectToNSDict(iter->first, iter->second, dictElement);
}
[dict setObject:dictElement forKey:NSkey];
return;
}
//add float into dict
if (value.getType() == Value::Type::FLOAT) {
NSNumber *number = [NSNumber numberWithFloat:value.asFloat()];
[dict setObject:number forKey:NSkey];
}
//add double into dict
if (value.getType() == Value::Type::DOUBLE) {
NSNumber *number = [NSNumber numberWithDouble:value.asDouble()];
[dict setObject:number forKey:NSkey];
}
//add boolean into dict
if (value.getType() == Value::Type::BOOLEAN) {
NSNumber *element = [NSNumber numberWithBool:value.asBool()];
[dict setObject:element forKey:NSkey];
}
//add integer into dict
if (value.getType() == Value::Type::INTEGER) {
NSNumber *element = [NSNumber numberWithInt:value.asInt()];
[dict setObject:element forKey:NSkey];
}
// the object is a String
if (value.getType() == Value::Type::STRING)
{
NSString *strElement = [NSString stringWithCString:value.asString().c_str() encoding:NSUTF8StringEncoding];
[dict setObject:strElement forKey:NSkey];
return;
}
// the object is a Array
if (value.getType() == Value::Type::VECTOR)
{
NSMutableArray *arrElement = [NSMutableArray array];
ValueVector array = value.asValueVector();
for(const auto& v : array)
{
addObjectToNSArray(v, arrElement);
}
[dict setObject:arrElement forKey:NSkey];
return;
}
[dict setObject:convertCCValueToNSObject(value) forKey:NSkey];
}
FileUtilsApple::FileUtilsApple() : pimpl_(new IMPL([NSBundle mainBundle])) {
}
@ -472,7 +354,7 @@ ValueMap FileUtilsApple::getValueMapFromData(const char* filedata, int filesize)
for (id key in [dict allKeys])
{
id value = [dict objectForKey:key];
addValueToDict(key, value, ret);
addNSObjectToCCMap(key, value, ret);
}
}
return ret;
@ -491,7 +373,7 @@ bool FileUtils::writeValueMapToFile(const ValueMap& dict, const std::string& ful
for (auto iter = dict.begin(); iter != dict.end(); ++iter)
{
addObjectToNSDict(iter->first, iter->second, nsDict);
addCCValueToNSDictionary(iter->first, iter->second, nsDict);
}
NSString *file = [NSString stringWithUTF8String:fullPath.c_str()];
@ -508,7 +390,7 @@ bool FileUtils::writeValueVectorToFile(const ValueVector& vecData, const std::st
for (const auto &e : vecData)
{
addObjectToNSArray(e, array);
addCCValueToNSArray(e, array);
}
[array writeToFile:path atomically:YES];
@ -530,7 +412,7 @@ ValueVector FileUtilsApple::getValueVectorFromFile(const std::string& filename)
for (id value in array)
{
addItemToArray(value, ret);
addNSObjectToCCVector(value, ret);
}
return ret;