\hypertarget{GpgFunctionObject_8h_source}{}\doxysection{Gpg\+Function\+Object.\+h}
\label{GpgFunctionObject_8h_source}\index{src/core/GpgFunctionObject.h@{src/core/GpgFunctionObject.h}}

\begin{DoxyCode}{0}
\DoxyCodeLine{1 }
\DoxyCodeLine{29 \textcolor{preprocessor}{\#ifndef GPGFRONTEND\_ZH\_CN\_TS\_FUNCTIONOBJECT\_H}}
\DoxyCodeLine{30 \textcolor{preprocessor}{\#define GPGFRONTEND\_ZH\_CN\_TS\_FUNCTIONOBJECT\_H}}
\DoxyCodeLine{31 }
\DoxyCodeLine{32 \textcolor{preprocessor}{\#include <map>}}
\DoxyCodeLine{33 \textcolor{preprocessor}{\#include <memory>}}
\DoxyCodeLine{34 \textcolor{preprocessor}{\#include <mutex>}}
\DoxyCodeLine{35 \textcolor{preprocessor}{\#include <shared\_mutex>}}
\DoxyCodeLine{36 \textcolor{preprocessor}{\#include <stdexcept>}}
\DoxyCodeLine{37 \textcolor{preprocessor}{\#include <string>}}
\DoxyCodeLine{38 }
\DoxyCodeLine{39 \textcolor{preprocessor}{\#include "{}GpgConstants.h"{}}}
\DoxyCodeLine{40 }
\DoxyCodeLine{41 \textcolor{keyword}{namespace }\mbox{\hyperlink{namespaceGpgFrontend}{GpgFrontend}} \{}
\DoxyCodeLine{42 }
\DoxyCodeLine{48 \textcolor{keyword}{template} <\textcolor{keyword}{typename} T>}
\DoxyCodeLine{49 \textcolor{keyword}{class }\mbox{\hyperlink{classGpgFrontend_1_1SingletonFunctionObject}{SingletonFunctionObject}} \{}
\DoxyCodeLine{50  \textcolor{keyword}{public}:}
\DoxyCodeLine{57   \textcolor{keyword}{static} T\& \mbox{\hyperlink{classGpgFrontend_1_1SingletonFunctionObject_a8a378452876a685af879e04bfa456b6f}{GetInstance}}(}
\DoxyCodeLine{58       \textcolor{keywordtype}{int} channel = GpgFrontend::GPGFRONTEND\_DEFAULT\_CHANNEL) \{}
\DoxyCodeLine{59     \textcolor{keyword}{static\_assert}(std::is\_base\_of<SingletonFunctionObject<T>, T>::value,}
\DoxyCodeLine{60                   \textcolor{stringliteral}{"{}T not derived from SingletonFunctionObject<T>"{}});}
\DoxyCodeLine{61 }
\DoxyCodeLine{62     \textcolor{keyword}{auto} \_p\_pbj = \mbox{\hyperlink{classGpgFrontend_1_1SingletonFunctionObject_a7ad3a06b1a64d953f4861f6c9d360c8a}{find\_object\_in\_channel}}(channel);}
\DoxyCodeLine{63     \textcolor{keywordflow}{if} (\_p\_pbj == \textcolor{keyword}{nullptr})}
\DoxyCodeLine{64       \textcolor{keywordflow}{return} *\mbox{\hyperlink{classGpgFrontend_1_1SingletonFunctionObject_a51f705fc4b4a60f07e924d0e5a027d2a}{set\_object\_in\_channel}}(channel, std::make\_unique<T>(channel));}
\DoxyCodeLine{65     \textcolor{keywordflow}{else}}
\DoxyCodeLine{66       \textcolor{keywordflow}{return} *\_p\_pbj;}
\DoxyCodeLine{67   \}}
\DoxyCodeLine{68 }
\DoxyCodeLine{76   \textcolor{keyword}{static} T\& \mbox{\hyperlink{classGpgFrontend_1_1SingletonFunctionObject_a459af8206b25fed21b423aeb61c408fe}{CreateInstance}}(\textcolor{keywordtype}{int} channel,}
\DoxyCodeLine{77                            std::function<std::unique\_ptr<T>(\textcolor{keywordtype}{void})> factory) \{}
\DoxyCodeLine{78     \textcolor{keyword}{static\_assert}(std::is\_base\_of<SingletonFunctionObject<T>, T>::value,}
\DoxyCodeLine{79                   \textcolor{stringliteral}{"{}T not derived from SingletonFunctionObject<T>"{}});}
\DoxyCodeLine{80 }
\DoxyCodeLine{81     \textcolor{keyword}{auto} \_p\_pbj = \mbox{\hyperlink{classGpgFrontend_1_1SingletonFunctionObject_a7ad3a06b1a64d953f4861f6c9d360c8a}{find\_object\_in\_channel}}(channel);}
\DoxyCodeLine{82     \textcolor{keywordflow}{if} (\_p\_pbj == \textcolor{keyword}{nullptr})}
\DoxyCodeLine{83       \textcolor{keywordflow}{return} *\mbox{\hyperlink{classGpgFrontend_1_1SingletonFunctionObject_a51f705fc4b4a60f07e924d0e5a027d2a}{set\_object\_in\_channel}}(channel, std::move(factory()));}
\DoxyCodeLine{84     \textcolor{keywordflow}{else}}
\DoxyCodeLine{85       \textcolor{keywordflow}{return} *\_p\_pbj;}
\DoxyCodeLine{86   \}}
\DoxyCodeLine{87 }
\DoxyCodeLine{95   \textcolor{keyword}{static} T\& \mbox{\hyperlink{classGpgFrontend_1_1SingletonFunctionObject_a3116637b021c316ec3b615baaa5a77a1}{CreateInstance}}(\textcolor{keywordtype}{int} channel, std::unique\_ptr<T> p\_obj = \textcolor{keyword}{nullptr}) \{}
\DoxyCodeLine{96     \textcolor{keyword}{static\_assert}(std::is\_base\_of<SingletonFunctionObject<T>, T>::value,}
\DoxyCodeLine{97                   \textcolor{stringliteral}{"{}T not derived from SingletonFunctionObject<T>"{}});}
\DoxyCodeLine{98 }
\DoxyCodeLine{99     \textcolor{keyword}{auto} \_p\_pbj = \mbox{\hyperlink{classGpgFrontend_1_1SingletonFunctionObject_a7ad3a06b1a64d953f4861f6c9d360c8a}{find\_object\_in\_channel}}(channel);}
\DoxyCodeLine{100     \textcolor{keywordflow}{if} (\_p\_pbj == \textcolor{keyword}{nullptr})}
\DoxyCodeLine{101       \textcolor{keywordflow}{return} *\mbox{\hyperlink{classGpgFrontend_1_1SingletonFunctionObject_a51f705fc4b4a60f07e924d0e5a027d2a}{set\_object\_in\_channel}}(channel, std::move(p\_obj));}
\DoxyCodeLine{102     \textcolor{keywordflow}{else}}
\DoxyCodeLine{103       \textcolor{keywordflow}{return} *\_p\_pbj;}
\DoxyCodeLine{104   \}}
\DoxyCodeLine{105 }
\DoxyCodeLine{112   \textcolor{keyword}{static} T\& \mbox{\hyperlink{classGpgFrontend_1_1SingletonFunctionObject_abb1ea69c668223ee9da79e6c92d5a9fa}{ReleaseChannel}}(\textcolor{keywordtype}{int} channel) \{}
\DoxyCodeLine{113     \textcolor{keyword}{decltype}(\_instances\_map.end()) \_it;}
\DoxyCodeLine{114     \{}
\DoxyCodeLine{115       std::shared\_lock lock(\_instances\_mutex);}
\DoxyCodeLine{116       \_it = \_instances\_map.find(channel);}
\DoxyCodeLine{117     \}}
\DoxyCodeLine{118     \textcolor{keywordflow}{if} (\_it != \_instances\_map.end()) \_instances\_map.erase(\_it);}
\DoxyCodeLine{119     DLOG(INFO) << \textcolor{stringliteral}{"{}channel"{}} << channel << \textcolor{stringliteral}{"{}released"{}};}
\DoxyCodeLine{120   \}}
\DoxyCodeLine{121 }
\DoxyCodeLine{127   \textcolor{keyword}{static} \textcolor{keywordtype}{int} \mbox{\hyperlink{classGpgFrontend_1_1SingletonFunctionObject_a50e2b3794d6553f4231eaec72d9d0a50}{GetDefaultChannel}}() \{ \textcolor{keywordflow}{return} \_default\_channel; \}}
\DoxyCodeLine{128 }
\DoxyCodeLine{134   [[nodiscard]] \textcolor{keywordtype}{int} \mbox{\hyperlink{classGpgFrontend_1_1SingletonFunctionObject_aa99440b9177f5d0c18840f08a40d64b7}{GetChannel}}()\textcolor{keyword}{ const }\{ \textcolor{keywordflow}{return} channel\_; \}}
\DoxyCodeLine{135 }
\DoxyCodeLine{140   \mbox{\hyperlink{classGpgFrontend_1_1SingletonFunctionObject_aabc5fe8e5a372ac276a265286457cb9a}{SingletonFunctionObject}}(T\&\&) = \textcolor{keyword}{delete};}
\DoxyCodeLine{141 }
\DoxyCodeLine{146   \mbox{\hyperlink{classGpgFrontend_1_1SingletonFunctionObject_a7090636bed6f4bad5b99f28f6872c645}{SingletonFunctionObject}}(\textcolor{keyword}{const} T\&) = \textcolor{keyword}{delete};}
\DoxyCodeLine{147 }
\DoxyCodeLine{152   \textcolor{keywordtype}{void} operator=(\textcolor{keyword}{const} T\&) = \textcolor{keyword}{delete};}
\DoxyCodeLine{153 }
\DoxyCodeLine{154  \textcolor{keyword}{protected}:}
\DoxyCodeLine{159   \mbox{\hyperlink{classGpgFrontend_1_1SingletonFunctionObject_a02e76b42ab51d77588b01c7508bed258}{SingletonFunctionObject}}() = \textcolor{keywordflow}{default};}
\DoxyCodeLine{160 }
\DoxyCodeLine{166   \textcolor{keyword}{explicit} \mbox{\hyperlink{classGpgFrontend_1_1SingletonFunctionObject_a4aa7f1eb1d3281bb1fccfcbb1b416251}{SingletonFunctionObject}}(\textcolor{keywordtype}{int} channel) : channel\_(channel) \{\}}
\DoxyCodeLine{167 }
\DoxyCodeLine{172   \textcolor{keyword}{virtual} \mbox{\hyperlink{classGpgFrontend_1_1SingletonFunctionObject_a8296be8c449f88175285186831b995bc}{\string~SingletonFunctionObject}}() = \textcolor{keywordflow}{default};}
\DoxyCodeLine{173 }
\DoxyCodeLine{179   \textcolor{keywordtype}{void} \mbox{\hyperlink{classGpgFrontend_1_1SingletonFunctionObject_a56ba12077251893e48f5ec360e8c7040}{SetChannel}}(\textcolor{keywordtype}{int} channel) \{ this-\/>channel\_ = channel; \}}
\DoxyCodeLine{180 }
\DoxyCodeLine{181  \textcolor{keyword}{private}:}
\DoxyCodeLine{182   \textcolor{keywordtype}{int} channel\_ = \_default\_channel;                          }
\DoxyCodeLine{183   \textcolor{keyword}{static} \textcolor{keywordtype}{int} \_default\_channel;                              }
\DoxyCodeLine{184   \textcolor{keyword}{static} std::mutex \_instance\_mutex;                        }
\DoxyCodeLine{185   \textcolor{keyword}{static} std::shared\_mutex \_instances\_mutex;                }
\DoxyCodeLine{186   \textcolor{keyword}{static} std::unique\_ptr<T> \_instance;                      }
\DoxyCodeLine{187   \textcolor{keyword}{static} std::map<int, std::unique\_ptr<T>> \_instances\_map;  }
\DoxyCodeLine{188 }
\DoxyCodeLine{195   \textcolor{keyword}{static} T* \mbox{\hyperlink{classGpgFrontend_1_1SingletonFunctionObject_a7ad3a06b1a64d953f4861f6c9d360c8a}{find\_object\_in\_channel}}(\textcolor{keywordtype}{int} channel) \{}
\DoxyCodeLine{196     \textcolor{comment}{// read \_instances\_map}}
\DoxyCodeLine{197     \textcolor{keyword}{decltype}(\_instances\_map.end()) \_it;}
\DoxyCodeLine{198     \{}
\DoxyCodeLine{199       std::shared\_lock lock(\_instances\_mutex);}
\DoxyCodeLine{200       \_it = \_instances\_map.find(channel);}
\DoxyCodeLine{201       \textcolor{keywordflow}{if} (\_it == \_instances\_map.end())}
\DoxyCodeLine{202         \textcolor{keywordflow}{return} \textcolor{keyword}{nullptr};}
\DoxyCodeLine{203       \textcolor{keywordflow}{else}}
\DoxyCodeLine{204         \textcolor{keywordflow}{return} \_it-\/>second.get();}
\DoxyCodeLine{205     \}}
\DoxyCodeLine{206   \}}
\DoxyCodeLine{207 }
\DoxyCodeLine{215   \textcolor{keyword}{static} T* \mbox{\hyperlink{classGpgFrontend_1_1SingletonFunctionObject_a51f705fc4b4a60f07e924d0e5a027d2a}{set\_object\_in\_channel}}(\textcolor{keywordtype}{int} channel, std::unique\_ptr<T> p\_obj) \{}
\DoxyCodeLine{216     \{}
\DoxyCodeLine{217       \textcolor{keywordflow}{if} (p\_obj == \textcolor{keyword}{nullptr}) p\_obj = std::make\_unique<T>();}
\DoxyCodeLine{218       T* obj = p\_obj.get();}
\DoxyCodeLine{219       obj-\/>SetChannel(channel);}
\DoxyCodeLine{220       \{}
\DoxyCodeLine{221         std::unique\_lock lock(\_instances\_mutex);}
\DoxyCodeLine{222         \_instances\_map.insert(\{channel, std::move(p\_obj)\});}
\DoxyCodeLine{223       \}}
\DoxyCodeLine{224       \textcolor{keywordflow}{return} obj;}
\DoxyCodeLine{225     \}}
\DoxyCodeLine{226   \}}
\DoxyCodeLine{227 \};}
\DoxyCodeLine{228 }
\DoxyCodeLine{229 \textcolor{keyword}{template} <\textcolor{keyword}{typename} T>}
\DoxyCodeLine{230 \textcolor{keywordtype}{int} SingletonFunctionObject<T>::\_default\_channel =}
\DoxyCodeLine{231     GpgFrontend::GPGFRONTEND\_DEFAULT\_CHANNEL;}
\DoxyCodeLine{232 }
\DoxyCodeLine{233 \textcolor{keyword}{template} <\textcolor{keyword}{typename} T>}
\DoxyCodeLine{234 std::mutex SingletonFunctionObject<T>::\_instance\_mutex;}
\DoxyCodeLine{235 }
\DoxyCodeLine{236 \textcolor{keyword}{template} <\textcolor{keyword}{typename} T>}
\DoxyCodeLine{237 std::shared\_mutex SingletonFunctionObject<T>::\_instances\_mutex;}
\DoxyCodeLine{238 }
\DoxyCodeLine{239 \textcolor{keyword}{template} <\textcolor{keyword}{typename} T>}
\DoxyCodeLine{240 std::unique\_ptr<T> SingletonFunctionObject<T>::\_instance = \textcolor{keyword}{nullptr};}
\DoxyCodeLine{241 }
\DoxyCodeLine{242 \textcolor{keyword}{template} <\textcolor{keyword}{typename} T>}
\DoxyCodeLine{243 std::map<int, std::unique\_ptr<T>> SingletonFunctionObject<T>::\_instances\_map;}
\DoxyCodeLine{244 }
\DoxyCodeLine{245 \}  \textcolor{comment}{// namespace GpgFrontend}}
\DoxyCodeLine{246 }
\DoxyCodeLine{247 \textcolor{preprocessor}{\#endif  }\textcolor{comment}{// GPGFRONTEND\_ZH\_CN\_TS\_FUNCTIONOBJECT\_H}}

\end{DoxyCode}
