0%

用c++ 实现一个IOS 端的闭包调用框架

用C++实现一个闭包调用框架

一、框架实现

1、设计

计划将调用请求从调用线程转到消息处理线程,消息处理完毕后再将消息转到回调线程抛出

2、接口设计

设计两类接口:一种是请求式的;一种是任务式的;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class MediaInterface {
public:
MediaInterface() {}
virtual ~MediaInterface() {}

public:
virtual void AddNotifyCallbacker(uint32_t task_id, INotifyCallbacker* callbacker) = 0;
virtual void DelNotifyCallbacker(uint32_t task_id) = 0;

virtual void Test(const std::string& json, IResponseCallbacker* callbacker) = 0;

virtual void PlayerCreate(const std::string& json, IResponseCallbacker* callbacker) = 0;
virtual void PlayerStart(const std::string& json, IResponseCallbacker* callbacker) = 0;
virtual void PlayerStop(const std::string& json, IResponseCallbacker* callbacker) = 0;
virtual void PlayerRemove(const std::string& json, IResponseCallbacker* callbacker) = 0;
};

3、消息设计

请求和响应消息采用比较通用的json形式

请求消息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class IRequestEvent {
public:
IRequestEvent(RequestEventType event_type) : event_type_(event_type) {}
virtual ~IRequestEvent() {}

public:
bool Parse(const std::string& json);

public:
RequestEventType get_event_type() const { return event_type_; }

private:
RequestEventType event_type_ = kRequestEventUnknow;
};

class RequestTest : public IRequestEvent {
public:
RequestTest() : IRequestEvent(kRequestEventTest) {}
virtual ~RequestTest() {}

public:
std::string type_;
std::string parmas_;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
static bool RequestTestParse(cJSON* root, RequestTest* event) {
cJSON* item = NULL;

item = cJSON_GetObjectItem(root, "type");
if (item && cJSON_IsString(item)) {
event->type_.assign(item->valuestring);
}

item = cJSON_GetObjectItem(root, "parmas");
if (item && cJSON_IsString(item)) {
event->parmas_.assign(item->valuestring);
}

return true;
}

响应消息

1
2
3
4
5
6
7
8
class ResponseTest : public IResponseEvent {
public:
ResponseTest() : IResponseEvent(kResponseEventTest) {}
virtual ~ResponseTest() {}

public:
std::string parmas_;
};
1
2
3
4
static bool ResponseTestFormat(cJSON* root, ResponseTest* event) {
cJSON_AddItemToObject(root, "parmas", cJSON_CreateString(event->parmas_.c_str()));
return true;
}

4、回调设计

回调对象分为通知和响应两种类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

class INotifyCallbacker {
public:
INotifyCallbacker() {}
virtual ~INotifyCallbacker() {}

public:
virtual void Call(const std::string& json) = 0;
};

class IResponseCallbacker {
public:
IResponseCallbacker() {}
virtual ~IResponseCallbacker() {}

public:
virtual void Call(const std::string& json) = 0;
};

5、线程设计

见代码

二、测试

1、重载回调

分别用block 和 function 实现闭包回调

block 实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

typedef void(^MediaBlockCallbacker)(NSDictionary* dic);

class MediaNotifyBlockCallbacker : public INotifyCallbacker {
public:
MediaNotifyBlockCallbacker(MediaBlockCallbacker callbacker) : callbacker_(callbacker) {}
virtual ~MediaNotifyBlockCallbacker() {}

public:
void Call(const std::string& json) override {
RunOnMainThread(^{
callbacker_(JsonToDictionary([NSData dataWithBytes:json.c_str() length:json.size()]));
});
}

private:
MediaBlockCallbacker callbacker_;
};

class MediaResponseBlockCallbacker : public IResponseCallbacker {
public:
MediaResponseBlockCallbacker(MediaBlockCallbacker callbacker) : callbacker_(callbacker) {}
virtual ~MediaResponseBlockCallbacker() {}

public:
void Call(const std::string& json) override {
RunOnMainThread(^{
callbacker_(JsonToDictionary([NSData dataWithBytes:json.c_str() length:json.size()]));
});
}

private:
MediaBlockCallbacker callbacker_;
};

function 实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

typedef std::function<void(NSDictionary* dic)> MediaFunctionCallbacker;

class MediaNotifyFunctionCallbacker : public INotifyCallbacker {
public:
MediaNotifyFunctionCallbacker(MediaFunctionCallbacker callbacker) : callbacker_(callbacker) {}
virtual ~MediaNotifyFunctionCallbacker() {}

public:
void Call(const std::string& json) override {
RunOnMainThread(^{
callbacker_(JsonToDictionary([NSData dataWithBytes:json.c_str() length:json.size()]));
});
}

private:
MediaFunctionCallbacker callbacker_;
};

class MediaResponseFunctionCallbacker : public IResponseCallbacker {
public:
MediaResponseFunctionCallbacker(MediaFunctionCallbacker callbacker) : callbacker_(callbacker) {}
virtual ~MediaResponseFunctionCallbacker() {}

public:
void Call(const std::string& json) override {
RunOnMainThread(^{
callbacker_(JsonToDictionary([NSData dataWithBytes:json.c_str() length:json.size()]));
});
}

private:
MediaFunctionCallbacker callbacker_;
};

2、测试代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

- (void) testCode {
NSMutableDictionary* dic = [[NSMutableDictionary alloc] init];
[dic setObject:@"testcode" forKey:@"type"];
[dic setObject:@"HelloWorld" forKey:@"parmas"];

{
weakify(self);
interface_->Test(std::string([DictionaryToString(dic) UTF8String]), new MediaResponseBlockCallbacker(^(NSDictionary* dic) {
strongify_or_return(self);

NSString* parmas = [dic objectForKey:@"parmas"];
NSLog(@"call from c++1: %@ \n", parmas);

self->_txTest.text = [NSString stringWithFormat:@"from c++: %@", parmas];
}));
}

{
weakify(self);
interface_->Test(std::string([DictionaryToString(dic) UTF8String]), new MediaResponseFunctionCallbacker([=] (NSDictionary* dic) {
strongify_or_return(self);

NSString* parmas = [dic objectForKey:@"parmas"];
NSLog(@"call from c++2: %@ \n", parmas);

self->_txTest.text = [NSString stringWithFormat:@"from c++: %@", parmas];
}));
}

}

3、测试效果

三、demo路径

https://github.com/hilive/hilive.git

用户的需求就是我的追求!