用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