1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #ifndef WIFI_DIRECT_EVENT_TEMPLATE_DISPATCHER_H
16 #define WIFI_DIRECT_EVENT_TEMPLATE_DISPATCHER_H
17 
18 #include <functional>
19 #include "conn_log.h"
20 #include "wifi_direct_event_queue.h"
21 #include "wifi_direct_event_wrapper.h"
22 
23 namespace OHOS::SoftBus {
24 template<typename PrevDispatcher, typename Content>
25 class WifiDirectEventTemplateDispatcher {
26 public:
27     using Func =  std::function<void(Content&)>;
WifiDirectEventTemplateDispatcher(WifiDirectEventQueue * queue,PrevDispatcher * prev,Func && func)28     WifiDirectEventTemplateDispatcher(WifiDirectEventQueue *queue, PrevDispatcher *prev, Func &&func)
29         : queue_(queue), prev_(prev), func_(std::forward<Func>(func)), chained_(false)
30     {
31         prev->chained_ = true;
32     }
33 
noexcept(false)34     ~WifiDirectEventTemplateDispatcher() noexcept(false)
35     {
36         if (!chained_) {
37             WaitAndDispatch();
38         }
39     }
40 
41     template<typename OtherContent>
42     WifiDirectEventTemplateDispatcher<WifiDirectEventTemplateDispatcher, OtherContent>
Handle(std::function<void (OtherContent &)> && otherFunc)43     Handle(std::function<void(OtherContent&)> &&otherFunc)
44     {
45         return WifiDirectEventTemplateDispatcher<WifiDirectEventTemplateDispatcher, OtherContent>(
46             queue_, this, std::forward<std::function<void(OtherContent&)>>(otherFunc));
47     }
48 
49 private:
50     template<typename Dispatcher, typename OtherEvent>
51     friend class WifiDirectEventTemplateDispatcher;
52 
WaitAndDispatch()53     void WaitAndDispatch()
54     {
55         for (;;) {
56             if (Dispatch(queue_->WaitAndPop())) {
57                 break;
58             }
59         }
60     }
61 
Dispatch(const std::shared_ptr<WifiDirectEventBase> & content)62     bool Dispatch(const std::shared_ptr<WifiDirectEventBase> &content)
63     {
64         auto wrapper = dynamic_cast<WifiDirectEventWrapper<Content> *>(content.get());
65         if (wrapper != nullptr) {
66             func_(wrapper->content_);
67             return true;
68         }
69         return prev_->Dispatch(content);
70     }
71 
72     WifiDirectEventQueue *queue_;
73     PrevDispatcher *prev_;
74     Func func_;
75     bool chained_;
76 };
77 }
78 #endif
79