临时保存

This commit is contained in:
cpdl
2025-04-30 17:36:24 +08:00
parent 7ed7033716
commit 43515d8058
60 changed files with 29146 additions and 67 deletions

View File

@@ -0,0 +1,46 @@
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
// Use of this source code is governed by a MIT license that can be
// found in the LICENSE file.
#include "FLTConvert.h"
Convert::Convert() {}
std::string Convert::getStringFormMapForLog(
const flutter::EncodableMap* arguments) const {
if (!arguments) {
return "";
}
// todo
return "";
}
void Convert::getLogList(const std::string& strLog,
std::list<std::string>& listLog) const {
listLog.clear();
int num = 15 * 1024; // 分割定长大小
int len = strLog.length(); // 字符串长度
int end = num;
for (int start = 0; start < len;) {
if (end > len) // 针对最后一个分割串
{
listLog.emplace_back(
strLog.substr(start, len - start)); // 最后一个字符串的原始部分
break;
}
listLog.emplace_back(
strLog.substr(start, num)); // 从0开始分割num位字符串
start = end;
end = end + num;
}
}
std::string Convert::getStringFormListForLog(
const flutter::EncodableList* arguments) const {
if (!arguments) {
return "";
}
return "";
}

29
windows/src/FLTConvert.h Normal file
View File

@@ -0,0 +1,29 @@
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
// Use of this source code is governed by a MIT license that can be
// found in the LICENSE file.
#ifndef FLTCONVERT_H
#define FLTCONVERT_H
#include <string>
#include <unordered_map>
#include "common/FLTService.h"
#include "common/utils/singleton.h"
class Convert {
public:
SINGLETONG(Convert)
std::string getStringFormMapForLog(
const flutter::EncodableMap* arguments) const;
void getLogList(const std::string& strLog,
std::list<std::string>& listLog) const;
std::string getStringFormListForLog(
const flutter::EncodableList* arguments) const;
private:
Convert();
};
#endif // FLTCONVERT_H

View File

@@ -0,0 +1,45 @@
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
// Use of this source code is governed by a MIT license that can be
// found in the LICENSE file.
#include "MethodCallHandlerImpl.h"
#include <flutter/method_channel.h>
#include <flutter/plugin_registrar_windows.h>
#include <flutter/standard_method_codec.h>
#include <memory>
#include "NimCore.h"
MethodCallHandlerImpl::MethodCallHandlerImpl() {}
void MethodCallHandlerImpl::onMethodCall(
const flutter::MethodCall <flutter::EncodableValue> &method_call,
std::shared_ptr <flutter::MethodResult<flutter::EncodableValue>> result) {
const auto *arguments =
std::get_if<flutter::EncodableMap>(method_call.arguments());
if (arguments) {
NimCore::getInstance()->onMethodCall(method_call.method_name(), arguments,
result);
} else {
if (result) {
result->NotImplemented();
}
}
}
flutter::MethodChannel <flutter::EncodableValue> *
MethodCallHandlerImpl::startListening(flutter::PluginRegistrar *registrar) {
m_methodChannel =
std::make_unique < flutter::MethodChannel < flutter::EncodableValue >> (
registrar->messenger(), "flutter_openim_sdk",
&flutter::StandardMethodCodec::GetInstance());
NimCore::getInstance()->setMethodChannel(m_methodChannel.get());
return m_methodChannel.get();
}
void MethodCallHandlerImpl::stopListening() {
NimCore::getInstance()->setMethodChannel(nullptr);
}

View File

@@ -0,0 +1,34 @@
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
// Use of this source code is governed by a MIT license that can be
// found in the LICENSE file.
#ifndef METHODCALLHANDLERIMPL_H
#define METHODCALLHANDLERIMPL_H
#include <flutter/method_channel.h>
#include <flutter/plugin_registrar_windows.h>
#include <flutter/standard_method_codec.h>
#include <memory>
#include "NimCore.h"
class MethodCallHandlerImpl {
public:
MethodCallHandlerImpl();
void onMethodCall(
const flutter::MethodCall<flutter::EncodableValue>& method_call,
std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
flutter::MethodChannel<flutter::EncodableValue>* startListening(
flutter::PluginRegistrar* registrar);
void stopListening();
private:
std::unique_ptr<flutter::MethodChannel<flutter::EncodableValue>>
m_methodChannel;
};
#endif // METHODCALLHANDLERIMPL_H

252
windows/src/NimCore.cpp Normal file
View File

@@ -0,0 +1,252 @@
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
// Use of this source code is governed by a MIT license that can be
// found in the LICENSE file.
#include "NimCore.h"
#include <flutter/encodable_value.h>
#include <flutter/method_channel.h>
#include <flutter/plugin_registrar_windows.h>
#include <flutter/standard_method_codec.h>
#include "FLTConvert.h"
#include "common/services/IMManager.h"
const std::string kFLTNimCoreService = "serviceName";
NimCore::NimCore() { regService(); }
NimCore::~NimCore() {}
void NimCore::regService() {
addService(new IMManagerService());
}
void NimCore::cleanService() {
// m_services.clear();
}
void NimCore::addService(FLTService* service) {
m_services[service->getServiceName()] = service;
}
// FLTMessageService* NimCore::getFLTMessageService() const {
// return dynamic_cast<FLTMessageService*>(getService("MessageService"));
// }
FLTService* NimCore::getService(const std::string& serviceName) const {
auto service = m_services.find(serviceName);
if (m_services.end() == service) {
return nullptr;
}
return service->second;
}
void NimCore::onMethodCall(
const std::string& method, const flutter::EncodableMap* arguments,
std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result) {
if (nullptr == arguments) {
if (result) {
result->NotImplemented();
}
return;
}
auto serviceName_iter =
arguments->find(flutter::EncodableValue("ManagerName"));
if (serviceName_iter != arguments->end() &&
!serviceName_iter->second.IsNull()) {
std::string serviceName = std::get<std::string>(serviceName_iter->second);
auto* service = getService(serviceName);
if (service) {
std::shared_ptr<MockMethodResult> mockResult =
std::make_shared<MockMethodResult>(serviceName, method, result);
YXLOG_API(Info) << "mn: " << method << ", args: "
<< Convert::getInstance()->getStringFormMapForLog(
arguments)
<< YXLOGEnd;
service->onMethodCalled(method, arguments, mockResult);
return;
}
} else {
YXLOG_API(Warn) << "sn not found, mn: " << method << YXLOGEnd;
}
if (result) {
result->NotImplemented();
}
}
void NimCore::invokeMethod(const std::string& method,
const flutter::EncodableMap& arguments) {
if (m_channel) {
m_channel->InvokeMethod(
method, std::make_unique<flutter::EncodableValue>(arguments));
}
}
template <typename T>
class InterResult : public flutter::MethodResult<T> {
protected:
void SuccessInternal(const T* result) override {
if (result != nullptr) {
NimCore::getInstance()->invokeCallback(flutter::EncodableValue(*result));
} else {
NimCore::getInstance()->invokeCallback(std::nullopt);
}
}
// Implementation of the public interface, to be provided by subclasses.
void ErrorInternal(const std::string& error_code,
const std::string& error_message,
const T* error_details) override {}
// Implementation of the public interface, to be provided by subclasses.
void NotImplementedInternal() override {}
};
void NimCore::invokeMethod(const std::string& eventName,
const flutter::EncodableMap& arguments,
const InvokeMehtodCallback& callback) {
invokeCallback = callback;
if (m_channel) {
m_channel->InvokeMethod(
eventName, std::make_unique<flutter::EncodableValue>(arguments),
std::make_unique<InterResult<flutter::EncodableValue>>());
}
}
void NimCore::setMethodChannel(NimMethodChannel* channel) {
m_channel = channel;
}
NimCore::NimMethodChannel* NimCore::getMethodChannel() { return m_channel; }
void NimCore::setAppkey(const std::string& appkey) { m_appKey = appkey; }
std::string NimCore::getAppkey() const { return m_appKey; }
void NimCore::setLogDir(const std::string& logDir) { m_logDir = logDir; }
std::string NimCore::getLogDir() const { return m_logDir; }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
MockMethodResult::MockMethodResult(
const std::string serviceName, const std::string methodName,
std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result)
: m_serviceName(serviceName),
m_methodName(methodName),
m_result(std::move(result)) {}
void MockMethodResult::ErrorInternal(const std::string& error_code,
const std::string& error_message,
const flutter::EncodableValue* details) {
YXLOG_API(Warn) << "cb error, sn: " << m_serviceName
<< ", mn: " << m_methodName << ", error_code: " << error_code
<< ", error_msg: " << error_message
<< ", details: " << getStringFormEncodableValue(details)
<< YXLOGEnd;
if (m_result) m_result->Success(*details);
// //失败情况下, 也调用success接口避免dart层抛出异常
// m_result->Error(error_code, error_message, *details);
}
void MockMethodResult::NotImplementedInternal() {
YXLOG_API(Warn) << "cb notImplemented, sn: " << m_serviceName
<< ", mn: " << m_methodName << YXLOGEnd;
if (m_result) m_result->NotImplemented();
}
void MockMethodResult::SuccessInternal(const flutter::EncodableValue* result) {
std::string strLog;
strLog.append("cb succ, sn: ")
.append(m_serviceName)
.append(", mn: ")
.append(m_methodName)
.append(", result: ")
.append(getStringFormEncodableValue(result));
std::list<std::string> logList;
Convert::getInstance()->getLogList(strLog, logList);
for (auto& it : logList) {
YXLOG_API(Info) << it << YXLOGEnd;
}
if (m_result) m_result->Success(*result);
}
std::string MockMethodResult::getStringFormEncodableValue(
const flutter::EncodableValue* value) const {
if (!value) {
return "";
}
std::string result;
if (auto it = std::get_if<bool>(value); it) {
result = *it ? "true" : "false";
} else if (auto it1 = std::get_if<int32_t>(value); it1) {
result = std::to_string(*it1);
} else if (auto it2 = std::get_if<int64_t>(value); it2) {
result = std::to_string(*it2);
} else if (auto it3 = std::get_if<double>(value); it3) {
result = std::to_string(*it3);
} else if (auto it4 = std::get_if<std::string>(value); it4) {
result = *it4;
} else if (auto it5 = std::get_if<std::vector<uint8_t>>(value); it5) {
result.append("[");
bool bFirst = true;
for (auto& it5Tmp : *it5) {
if (!bFirst) {
result.append("");
}
result.append(std::to_string(it5Tmp));
bFirst = false;
}
result.append("]");
} else if (auto it6 = std::get_if<std::vector<int32_t>>(value); it6) {
result.append("[");
bool bFirst = true;
for (auto& it6Tmp : *it6) {
if (!bFirst) {
result.append("");
}
result.append(std::to_string(it6Tmp));
bFirst = false;
}
result.append("]");
} else if (auto it7 = std::get_if<std::vector<int64_t>>(value); it7) {
result.append("[");
bool bFirst = true;
for (auto& it7Tmp : *it7) {
if (!bFirst) {
result.append("");
}
result.append(std::to_string(it7Tmp));
bFirst = false;
}
result.append("]");
} else if (auto it8 = std::get_if<std::vector<double>>(value); it8) {
result.append("[");
bool bFirst = true;
for (auto& it8Tmp : *it8) {
if (!bFirst) {
result.append("");
}
result.append(std::to_string(it8Tmp));
bFirst = false;
}
result.append("]");
} else if (auto it9 = std::get_if<EncodableList>(value); it9) {
result = Convert::getInstance()->getStringFormListForLog(it9);
} else if (auto it10 = std::get_if<EncodableMap>(value); it10) {
result = Convert::getInstance()->getStringFormMapForLog(it10);
} else {
// wjzh
}
return result;
}

105
windows/src/NimCore.h Normal file
View File

@@ -0,0 +1,105 @@
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
// Use of this source code is governed by a MIT license that can be
// found in the LICENSE file.
#ifndef NIMCORE_H
#define NIMCORE_H
#include <flutter/encodable_value.h>
#include <flutter/method_channel.h>
#include <flutter/plugin_registrar_windows.h>
#include <flutter/standard_method_codec.h>
class FLTService;
class FLTAuthService;
class FLTMessageService;
class NimCore {
public:
using NimMethodChannel = flutter::MethodChannel<flutter::EncodableValue>;
public:
SINGLETONG(NimCore)
private:
NimCore();
~NimCore();
public:
using InvokeMehtodCallback =
std::function<void(const std::optional <flutter::EncodableValue> &)>;
InvokeMehtodCallback invokeCallback;
void regService();
void cleanService();
void addService(FLTService *service);
// FLTAuthService* getFLTAuthService() const;
// FLTMessageService* getFLTMessageService() const;
FLTService *getService(const std::string &serviceName) const;
void onMethodCall(
const std::string &method, const flutter::EncodableMap *arguments,
std::shared_ptr <flutter::MethodResult<flutter::EncodableValue>> result);
void invokeMethod(const std::string &method,
const flutter::EncodableMap &arguments);
void invokeMethod(const std::string &eventName,
const flutter::EncodableMap &arguments,
const InvokeMehtodCallback &callback);
void setMethodChannel(NimMethodChannel *channel);
NimMethodChannel *getMethodChannel();
public:
void setAppkey(const std::string &appkey);
std::string getAppkey() const;
void setLogDir(const std::string &logDir);
std::string getLogDir() const;
std::string getAccountId() const;
private:
std::unordered_map<std::string, FLTService *> m_services;
NimMethodChannel *m_channel = nullptr;
std::string m_appKey = "";
std::string m_logDir;
};
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class MockMethodResult : public flutter::MethodResult<> {
public:
MockMethodResult(
const std::string serviceName, const std::string methodName,
std::shared_ptr <flutter::MethodResult<flutter::EncodableValue>> result);
virtual void ErrorInternal(const std::string &error_code,
const std::string &error_message,
const flutter::EncodableValue *details) override;
virtual void NotImplementedInternal() override;
virtual void SuccessInternal(const flutter::EncodableValue *result) override;
private:
std::string getStringFormEncodableValue(
const flutter::EncodableValue *value) const;
private:
std::string m_serviceName;
std::string m_methodName;
std::shared_ptr <flutter::MethodResult<flutter::EncodableValue>> m_result;
};
#endif // NIMCORE

View File

@@ -0,0 +1,65 @@
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
// Use of this source code is governed by a MIT license that can be
// found in the LICENSE file.
#include "FLTService.h"
#include "../FLTConvert.h"
std::string FLTService::getServiceName() const { return m_serviceName; }
void notifyEvent(const std::string& eventName,
flutter::EncodableMap& arguments) {
arguments.insert(std::make_pair(flutter::EncodableValue("serviceName"),
flutter::EncodableValue("")));
std::string strLog;
strLog.append("en: ")
.append(eventName)
.append(", args: ")
.append(Convert::getInstance()->getStringFormMapForLog(&arguments));
std::list<std::string> logList;
Convert::getInstance()->getLogList(strLog, logList);
for (auto& it : logList) {
YXLOG_API(Info) << it << YXLOGEnd;
}
NimCore::getInstance()->invokeMethod(eventName, arguments);
YXLOG_API(Info) << "notifyEvent invoke completation." << YXLOGEnd;
}
//void FLTService::notifyEvent(const std::string& eventName,
// flutter::EncodableMap& arguments,
// const NimCore::InvokeMehtodCallback& callback) {
// arguments.insert(std::make_pair(flutter::EncodableValue("serviceName"),
// flutter::EncodableValue(m_serviceName)));
// std::string strLog;
// strLog.append("en: ")
// .append(eventName)
// .append(", args: ")
// .append(Convert::getInstance()->getStringFormMapForLog(&arguments));
// std::list<std::string> logList;
// Convert::getInstance()->getLogList(strLog, logList);
// for (auto& it : logList) {
// YXLOG_API(Info) << it << YXLOGEnd;
// }
// NimCore::getInstance()->invokeMethod(eventName, arguments, callback);
// YXLOG_API(Info) << "notifyEvent invoke completation." << YXLOGEnd;
//}
void FLTService::notifyEventEx(const std::string& serviceName,
const std::string& eventName,
flutter::EncodableMap& arguments) {
arguments.insert(std::make_pair(flutter::EncodableValue("serviceName"),
flutter::EncodableValue(serviceName)));
std::string strLog;
strLog.append("en: ")
.append(eventName)
.append(", args: ")
.append(Convert::getInstance()->getStringFormMapForLog(&arguments));
std::list<std::string> logList;
Convert::getInstance()->getLogList(strLog, logList);
for (auto& it : logList) {
YXLOG_API(Info) << it << YXLOGEnd;
}
NimCore::getInstance()->invokeMethod(eventName, arguments);
YXLOG_API(Info) << "notifyEventEx invoke completation." << YXLOGEnd;
}

View File

@@ -0,0 +1,46 @@
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
// Use of this source code is governed by a MIT license that can be
// found in the LICENSE file.
#ifndef FLTSERVICE_H
#define FLTSERVICE_H
#include "../NimCore.h"
#include "NimResult.h"
#include "flutter/method_result.h"
#define DECLARE_FUN(fun) \
void fun(const flutter::EncodableMap* arguments, \
FLTService::MethodResult result);
void notifyEvent(const std::string& eventName,
flutter::EncodableMap& arguments);
class FLTService {
public:
using MethodResult =
std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>>;
public:
virtual void onMethodCalled(
const std::string& method, const flutter::EncodableMap* arguments,
std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>>
result) = 0;
std::string getServiceName() const;
//void notifyEvent(const std::string& eventName,
// flutter::EncodableMap& arguments,
// const NimCore::InvokeMehtodCallback& callback);
static void notifyEventEx(const std::string& serviceName,
const std::string& eventName,
flutter::EncodableMap& arguments);
protected:
std::string m_serviceName;
};
#endif // FLTSERVICE_H

View File

@@ -0,0 +1,88 @@
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
// Use of this source code is governed by a MIT license that can be
// found in the LICENSE file.
#include "NimResult.h"
using namespace flutter;
EncodableValue NimResult::getErrorResult(int code, const std::string& msg) {
EncodableMap result;
result.insert(std::make_pair(EncodableValue("code"), EncodableValue(code)));
result.insert(
std::make_pair(EncodableValue("errorDetails"), EncodableValue(msg)));
result.insert(std::make_pair(EncodableValue("data"), EncodableValue()));
return EncodableValue(result);
}
EncodableValue NimResult::getErrorResult(int code, const std::string& msg,
const EncodableMap& data) {
EncodableMap result;
result.insert(std::make_pair(EncodableValue("code"), EncodableValue(code)));
result.insert(
std::make_pair(EncodableValue("errorDetails"), EncodableValue(msg)));
result.insert(std::make_pair(EncodableValue("data"), EncodableValue(data)));
return EncodableValue(result);
}
EncodableValue NimResult::getSuccessResult() {
EncodableMap result;
result.insert(std::make_pair(EncodableValue("code"), EncodableValue(0)));
result.insert(
std::make_pair(EncodableValue("errorDetails"), EncodableValue("")));
result.insert(std::make_pair(EncodableValue("data"), EncodableValue()));
return EncodableValue(result);
}
EncodableValue NimResult::getSuccessResult(bool data) {
return getSuccessResult(EncodableValue(data));
}
EncodableValue NimResult::getSuccessResult(int32_t data) {
return getSuccessResult(EncodableValue(data));
}
EncodableValue NimResult::getSuccessResult(int64_t data) {
return getSuccessResult(EncodableValue(data));
}
EncodableValue NimResult::getSuccessResult(const std::string& data) {
return getSuccessResult(EncodableValue(data));
}
EncodableValue NimResult::getSuccessResult(const EncodableValue& data) {
EncodableMap result;
result.insert(std::make_pair(EncodableValue("code"), EncodableValue(0)));
result.insert(
std::make_pair(EncodableValue("errorDetails"), EncodableValue("")));
result.insert(std::make_pair(EncodableValue("data"), data));
return EncodableValue(result);
}
EncodableValue NimResult::getSuccessResult(const EncodableMap& data) {
EncodableMap result;
result.insert(std::make_pair(EncodableValue("code"), EncodableValue(0)));
result.insert(
std::make_pair(EncodableValue("errorDetails"), EncodableValue("")));
result.insert(std::make_pair(EncodableValue("data"), data));
return EncodableValue(result);
}
EncodableValue NimResult::getSuccessResult(const EncodableList& data) {
EncodableMap result;
result.insert(std::make_pair(EncodableValue("code"), EncodableValue(0)));
result.insert(
std::make_pair(EncodableValue("errorDetails"), EncodableValue("")));
result.insert(std::make_pair(EncodableValue("data"), data));
return EncodableValue(result);
}
EncodableValue NimResult::getSuccessResult(const std::string& msg,
const EncodableMap& data) {
EncodableMap result;
result.insert(std::make_pair(EncodableValue("code"), EncodableValue(0)));
result.insert(
std::make_pair(EncodableValue("errorDetails"), EncodableValue(msg)));
result.insert(std::make_pair(EncodableValue("data"), EncodableValue(data)));
return EncodableValue(result);
}

View File

@@ -0,0 +1,34 @@
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
// Use of this source code is governed by a MIT license that can be
// found in the LICENSE file.
#ifndef NIMRESULT_H
#define NIMRESULT_H
#include "flutter/encodable_value.h"
using namespace flutter;
class NimResult {
public:
static EncodableValue getErrorResult(int code, const std::string& msg);
static EncodableValue getErrorResult(int code, const std::string& msg,
const flutter::EncodableMap& data);
static EncodableValue getSuccessResult();
static EncodableValue getSuccessResult(bool data);
static EncodableValue getSuccessResult(int32_t data);
static EncodableValue getSuccessResult(int64_t data);
static EncodableValue getSuccessResult(const std::string& data);
static EncodableValue getSuccessResult(const flutter::EncodableValue& data);
static EncodableValue getSuccessResult(const flutter::EncodableMap& data);
static EncodableValue getSuccessResult(const flutter::EncodableList& data);
static EncodableValue getSuccessResult(const std::string& msg,
const flutter::EncodableMap& data);
};
#endif // NIMRESULT_H

View File

@@ -0,0 +1,71 @@
#include "ZegoDataUtils.h"
bool zego_value_is_null(flutter::EncodableValue value) { return value.IsNull(); }
int32_t zego_value_get_int(flutter::EncodableValue value) {
// dart 没有 int32_t int64_t 区分,这里处理了 int32 最高位为 1负数的 case
return (int32_t)zego_value_get_long(value);
}
int64_t zego_value_get_long(flutter::EncodableValue value) { return value.LongValue(); }
bool zego_value_get_bool(flutter::EncodableValue value) { return std::get<bool>(value); }
double zego_value_get_double(flutter::EncodableValue value) { return std::get<double>(value); }
std::string zego_value_get_string(flutter::EncodableValue value) {
return std::get<std::string>(value);
}
std::vector<float> zego_value_get_vector_float(flutter::EncodableValue value) {
return std::get<std::vector<float>>(value);
}
std::vector<uint8_t> zego_value_get_vector_uint8(flutter::EncodableValue value) {
return std::get<std::vector<uint8_t>>(value);
}
ZFMap zego_value_get_map(flutter::EncodableValue value) { return std::get<ZFMap>(value); }
ZFArray zego_value_get_list(flutter::EncodableValue value) { return std::get<ZFArray>(value); }
// 将 EncodableValue 转换为 nlohmann::json
nlohmann::json EncodableValueToJson(const flutter::EncodableValue& value) {
if (std::holds_alternative<bool>(value)) {
return std::get<bool>(value);
} else if (std::holds_alternative<int32_t>(value)) {
return std::get<int32_t>(value);
} else if (std::holds_alternative<int64_t>(value)) {
return std::get<int64_t>(value);
} else if (std::holds_alternative<double>(value)) {
return std::get<double>(value);
} else if (std::holds_alternative<std::string>(value)) {
return std::get<std::string>(value);
} else if (std::holds_alternative<flutter::EncodableList>(value)) {
nlohmann::json json_array = nlohmann::json::array();
for (const auto& item : std::get<flutter::EncodableList>(value)) {
json_array.push_back(EncodableValueToJson(item));
}
return json_array;
} else if (std::holds_alternative<flutter::EncodableMap>(value)) {
nlohmann::json json_object = nlohmann::json::object();
for (const auto& pair : std::get<flutter::EncodableMap>(value)) {
std::string key = std::get<std::string>(pair.first); // 假设键是字符串
json_object[key] = EncodableValueToJson(pair.second);
}
return json_object;
}
return nullptr; // 处理空值或不支持的类型
}
// 将 EncodableMap 转换为 JSON 字符串
std::string map_2_json(const flutter::EncodableMap& map) {
nlohmann::json json_object = nlohmann::json::object();
for (const auto& pair : map) {
std::string key = std::get<std::string>(pair.first); // 假设键是字符串
json_object[key] = EncodableValueToJson(pair.second);
}
auto json_string = json_object.dump(); // 序列化为 JSON 字符串
return json_string; // 序列化为 JSON 字符串
}

View File

@@ -0,0 +1,36 @@
#pragma once
#include <flutter/encodable_value.h>
#include <flutter/event_channel.h>
#include <memory>
#include "json.hpp"
#define ZFValue(varName) flutter::EncodableValue(varName)
#define ZFMap flutter::EncodableMap
#define ZFArray flutter::EncodableList
#define ZFArgument flutter::EncodableMap &
#define ZFResult std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>>
#define ZFEventSink std::unique_ptr<flutter::EventSink<flutter::EncodableValue>>
#define ZFMoveResult(result) std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>>(std::move(result))
#define ZFPluginRegistrar flutter::PluginRegistrarWindows
#define ZFBinaryMessenger flutter::BinaryMessenger
#define ZFTextureRegistrar flutter::TextureRegistrar
bool zego_value_is_null(flutter::EncodableValue value);
int32_t zego_value_get_int(flutter::EncodableValue value);
int64_t zego_value_get_long(flutter::EncodableValue value);
bool zego_value_get_bool(flutter::EncodableValue value);
double zego_value_get_double(flutter::EncodableValue value);
std::string zego_value_get_string(flutter::EncodableValue value);
std::vector<float> zego_value_get_vector_float(flutter::EncodableValue value);
std::vector<uint8_t> zego_value_get_vector_uint8(flutter::EncodableValue value);
ZFMap zego_value_get_map(flutter::EncodableValue value);
ZFArray zego_value_get_list(flutter::EncodableValue value);
std::string map_2_json(const flutter::EncodableMap& map);

25526
windows/src/common/json.hpp Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,70 @@
#ifndef CONST_DEFINE_H
#define CONST_DEFINE_H
enum class ConstDefine {
CONNECTING = 0,
CONNECT_SUCCESS,
CONNECT_FAILED,
KICKED_OFFLINE,
USER_TOKEN_EXPIRED,
JOINED_GROUP_ADDED,
JOINED_GROUP_DELETED,
GROUP_MEMBER_ADDED,
GROUP_MEMBER_DELETED,
GROUP_APPLICATION_ADDED,
GROUP_APPLICATION_DELETED,
GROUP_INFO_CHANGED,
GROUP_DISMISSED,
GROUP_MEMBER_INFO_CHANGED,
GROUP_APPLICATION_ACCEPTED,
GROUP_APPLICATION_REJECTED,
FRIEND_APPLICATION_ADDED,
FRIEND_APPLICATION_DELETED,
FRIEND_APPLICATION_ACCEPTED,
FRIEND_APPLICATION_REJECTED,
FRIEND_ADDED,
FRIEND_DELETED,
FRIEND_INFO_CHANGED,
BLACK_ADDED,
BLACK_DELETED,
SYNC_SERVER_START,
SYNC_SERVER_FINISH,
SYNC_SERVER_PROGRESS,
SYNC_SERVER_FAILED,
NEW_CONVERSATION,
CONVERSATION_CHANGED,
TOTAL_UNREAD_MESSAGE_COUNT_CHANGED,
RECV_NEW_MESSAGE,
RECV_C2C_READ_RECEIPT,
RECV_GROUP_READ_RECEIPT,
NEW_RECV_MESSAGE_REVOKED,
RECV_MESSAGE_EXTENSIONS_CHANGED,
RECV_MESSAGE_EXTENSIONS_DELETED,
RECV_MESSAGE_EXTENSIONS_ADDED,
RECV_OFFLINE_NEW_MESSAGE,
MSG_DELETED,
RECV_NEW_MESSAGES,
RECV_OFFLINE_NEW_MESSAGES,
SELF_INFO_UPDATED,
USER_STATUS_CHANGED,
RECV_CUSTOM_BUSINESS_MESSAGE,
MESSAGE_KV_INFO_CHANGED,
OPEN,
PART_SIZE,
HASH_PART_PROGRESS,
HASH_PART_COMPLETE,
UPLOAD_ID,
UPLOAD_PART_COMPLETE,
UPLOAD_COMPLETE,
COMPLETE,
CONVERSATION_USER_INPUT_STATUS_CHANGED,
RECV_ONLINE_ONLY_MESSAGE,
RECV_MESSAGE_EDIT,
USER_TOKEN_INVALID,
ON_PROGRESS
};
#endif // EVENT_TYPES_H

View File

@@ -0,0 +1,339 @@
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
// Use of this source code is governed by a MIT license that can be
// found in the LICENSE file.
#include "IMManager.h"
#if defined(_WIN32)
#include <windows.h>
#endif
#include "../NimResult.h"
#include <libopenimsdk.h>
#include "../ZegoDataUtils.h"
#include "ConstDefine.h"
IMManagerService::IMManagerService() {
m_serviceName = "imManager";
_im_manager_listener.onInitSdk = [](int state, char *msg) {
// friend added, handle friendInfo
flutter::EncodableMap arguments;
switch (ConstDefine(state)) {
case ConstDefine::CONNECTING:
arguments.insert(std::make_pair("type", "onConnecting"));
arguments.insert(std::make_pair("data", *msg));
break;
case ConstDefine::CONNECT_SUCCESS:
arguments.insert(std::make_pair("type", "onConnectSuccess"));
arguments.insert(std::make_pair("data", *msg));
break;
case ConstDefine::CONNECT_FAILED:
arguments.insert(std::make_pair("type", "onConnectFailed"));
arguments.insert(std::make_pair("data", *msg));
break;
case ConstDefine::KICKED_OFFLINE:
arguments.insert(std::make_pair("type", "onKickedOffline"));
arguments.insert(std::make_pair("data", *msg));
break;
case ConstDefine::USER_TOKEN_EXPIRED:
arguments.insert(std::make_pair("type", "onUserTokenExpired"));
arguments.insert(std::make_pair("data", *msg));
break;
case ConstDefine::USER_TOKEN_INVALID:
arguments.insert(std::make_pair("type", "onUserTokenExpired"));
arguments.insert(std::make_pair("data", *msg));
break;
}
notifyEvent("connectListener", arguments);
};
_im_manager_listener.baseCallBack = [](char *opid, int errCode, char *errMsg, char *msg) {
CallBaseCallBack(msg, errCode, errMsg, msg);
};
_im_manager_listener.uploadCallback = [](int state, char *msg) {
// upload progress
flutter::EncodableMap arguments;
switch (ConstDefine(state)) {
case ConstDefine::OPEN:
arguments.insert(std::make_pair("type", "onConnecting"));
arguments.insert(std::make_pair("data", *msg));
break;
case ConstDefine::PART_SIZE:
arguments.insert(std::make_pair("type", "onConnectSuccess"));
arguments.insert(std::make_pair("data", *msg));
break;
case ConstDefine::HASH_PART_PROGRESS:
arguments.insert(std::make_pair("type", "onConnectFailed"));
arguments.insert(std::make_pair("data", *msg));
break;
case ConstDefine::HASH_PART_COMPLETE:
arguments.insert(std::make_pair("type", "onKickedOffline"));
arguments.insert(std::make_pair("data", *msg));
break;
case ConstDefine::UPLOAD_ID:
arguments.insert(std::make_pair("type", "onUserTokenExpired"));
arguments.insert(std::make_pair("data", *msg));
break;
case ConstDefine::UPLOAD_PART_COMPLETE:
arguments.insert(std::make_pair("type", "onUserTokenExpired"));
arguments.insert(std::make_pair("data", *msg));
break;
case ConstDefine::UPLOAD_COMPLETE:
arguments.insert(std::make_pair("type", "onUserTokenExpired"));
arguments.insert(std::make_pair("data", *msg));
break;
case ConstDefine::COMPLETE:
arguments.insert(std::make_pair("type", "onUserTokenExpired"));
arguments.insert(std::make_pair("data", *msg));
break;
}
notifyEvent("uploadFileListener", arguments);
};
}
void IMManagerService::onMethodCalled(
const std::string &method, const flutter::EncodableMap *arguments,
std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result) {
if (method == "initSDK") {
initializeSDK(arguments, result);
} else if (method == "unInitSDK") {
unInitSDK(arguments, result);
} else if (method == "login") {
login(arguments, result);
} else if (method == "logout") {
logout(arguments, result);
} else if (method == "getLoginStatus") {
getLoginStatus(arguments, result);
} else if (method == "uploadFile") {
uploadFile(arguments, result);
} else if (method == "uploadLogs") {
uploadLogs(arguments, result);
} else if (method == "logs") {
logs(arguments, result);
} else if (method == "updateFcmToken") {
updateFcmToken(arguments, result);
} else if (method == "setAppBackgroundStatus") {
setAppBackgroundStatus(arguments, result);
} else if (method == "networkStatusChanged") {
networkStatusChanged(arguments, result);
} else {
result->NotImplemented();
}
}
void IMManagerService::initializeSDK(
const flutter::EncodableMap *arguments,
std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result) {
if (arguments) {
auto operationID = zego_value_get_string(arguments->at(ZFValue("operationID")));
char *operationID_cs = const_cast<char *>(operationID.c_str());
auto config = map_2_json(*arguments);
char *config_cs = const_cast<char *>(config.c_str());
auto error = init_sdk(_im_manager_listener.onInitSdk,
operationID_cs,
config_cs);
if (error == 0) {
// handle error
std::string msg = "IM init failed";
result->Error("", "",
NimResult::getErrorResult(error, ""));
} else {
result->Success(EncodableValue(error == 0));
}
}
}
void IMManagerService::unInitSDK(
const flutter::EncodableMap *arguments,
std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result) {
if (arguments) {
auto operationID = zego_value_get_string(
arguments->at(flutter::EncodableValue("operationID")));
char *operationID_cs = const_cast<char *>(operationID.c_str());
un_init_sdk(operationID_cs);
} else {
result->Error("INVALID_ARGUMENT", "Arguments cannot be null");
}
}
void IMManagerService::login(
const flutter::EncodableMap *arguments,
std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result) {
if (arguments) {
auto operationID = zego_value_get_string(
arguments->at(flutter::EncodableValue("operationID")));
auto userID = zego_value_get_string(arguments->at(flutter::EncodableValue("userID")));
auto token = zego_value_get_string(arguments->at(flutter::EncodableValue("token")));
char *operationID_cs = const_cast<char *>(operationID.c_str());
char *userID_cs = const_cast<char *>(userID.c_str());
char *token_cs = const_cast<char *>(token.c_str());
NewBaseCallBack(operationID, result);
::login(_im_manager_listener.baseCallBack, operationID_cs, userID_cs, token_cs);
} else {
result->Error("INVALID_ARGUMENT", "Arguments cannot be null");
}
}
void IMManagerService::logout(
const flutter::EncodableMap *arguments,
std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result) {
if (arguments) {
auto operationID = zego_value_get_string(
arguments->at(flutter::EncodableValue("operationID")));
char *operationID_cs = const_cast<char *>(operationID.c_str());
NewBaseCallBack(operationID, result);
::logout(_im_manager_listener.baseCallBack, operationID_cs);
} else {
result->Error("INVALID_ARGUMENT", "Arguments cannot be null");
}
}
void IMManagerService::getLoginStatus(
const flutter::EncodableMap *arguments,
std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result) {
if (arguments) {
auto operationID = zego_value_get_string(
arguments->at(flutter::EncodableValue("operationID")));
char *operationID_cs = const_cast<char *>(operationID.c_str());
int status = get_login_status(operationID_cs);
flutter::EncodableMap statusMap;
result->Success(flutter::EncodableValue(status));
} else {
result->Error("INVALID_ARGUMENT", "Arguments cannot be null");
}
}
void IMManagerService::uploadFile(
const flutter::EncodableMap *arguments,
std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result) {
// if (arguments) {
// auto operationID = zego_value_get_string(arguments->at(flutter::EncodableValue("operationID")));
// auto id = zego_value_get_string(arguments->at(flutter::EncodableValue("id")));
// auto fileInfo = map_2_json(*arguments);
// char* operationID_cs = const_cast<char*>(operationID.c_str());
// char* fileInfo_cs = const_cast<char*>(fileInfo.c_str());
// uploadFileResult = result;
// upload_file(_im_manager_listener.onUploadFile, operationID_cs, fileInfo_cs, _im_manager_listener.uploadCallback);
// }
// else {
// result->Error("INVALID_ARGUMENT", "Arguments cannot be null");
// }
}
void IMManagerService::uploadLogs(
const flutter::EncodableMap *arguments,
std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result) {
// if (arguments) {
// auto operationID = zego_value_get_string(
// arguments->at(flutter::EncodableValue("operationID")));
// auto line = zego_value_get_int(arguments->at(flutter::EncodableValue("line")));
// auto ex = zego_value_get_string(arguments->at(flutter::EncodableValue("ex")));
// char *operationID_cs = const_cast<char *>(operationID.c_str());
// char *ex_cs = const_cast<char *>(ex.c_str());
//
// upload_logs(_im_manager_listener.onUploadLogs, operationID_cs, line, ex_cs);
//
// } else {
// result->Error("INVALID_ARGUMENT", "Arguments cannot be null");
// }
}
void IMManagerService::logs(
const flutter::EncodableMap *arguments,
std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result) {
// if (arguments) {
// auto operationID = zego_value_get_string(arguments->at(flutter::EncodableValue("operationID")));
// auto logLevel = zego_value_get_int(arguments->at(flutter::EncodableValue("logLevel")));
// auto file = zego_value_get_string(arguments->at(flutter::EncodableValue("file")));
// auto line = zego_value_get_int(arguments->at(flutter::EncodableValue("line")));
// auto msgs = zego_value_get_string(arguments->at(flutter::EncodableValue("msgs")));
// auto err = zego_value_get_string(arguments->at(flutter::EncodableValue("err")));
// auto keyAndValue = zego_value_get_string(arguments->at(flutter::EncodableValue("keyAndValue")));
// char* operationID_cs = const_cast<char*>(operationID.c_str());
// char* file_cs = const_cast<char*>(file.c_str());
// char* msgs_cs = const_cast<char*>(msgs.c_str());
// char* err_cs = const_cast<char*>(err.c_str());
// char* keyAndValue_cs = const_cast<char*>(keyAndValue.c_str());
//
// auto error = logs(_im_manager_listener.onLogs, operationID_cs, logLevel, file_cs, line, msgs_cs, err_cs, keyAndValue_cs);
// if (error != 0) {
// std::string msg = "Logging failed";
// result->Error("", "", NimResult::getErrorResult(error, msg));
// }
// else {
// result->Success(NimResult::getSuccessResult());
// }
// }
// else {
// result->Error("INVALID_ARGUMENT", "Arguments cannot be null");
// }
}
void IMManagerService::updateFcmToken(
const flutter::EncodableMap *arguments,
std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result) {
if (arguments) {
auto operationID = zego_value_get_string(
arguments->at(flutter::EncodableValue("operationID")));
auto fcmToken = zego_value_get_string(arguments->at(flutter::EncodableValue("fcmToken")));
auto expireTime = zego_value_get_int(arguments->at(flutter::EncodableValue("expireTime")));
char *operationID_cs = const_cast<char *>(operationID.c_str());
char *fcmToken_cs = const_cast<char *>(fcmToken.c_str());
NewBaseCallBack(operationID, result);
update_fcm_token(_im_manager_listener.baseCallBack, operationID_cs, fcmToken_cs,
expireTime);
} else {
result->Error("INVALID_ARGUMENT", "Arguments cannot be null");
}
}
void IMManagerService::setAppBackgroundStatus(
const flutter::EncodableMap *arguments,
std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result) {
if (arguments) {
auto operationID = zego_value_get_string(arguments->at(flutter::EncodableValue("operationID")));
auto isBackground = zego_value_get_bool(arguments->at(flutter::EncodableValue("isBackground")));
char* operationID_cs = const_cast<char*>(operationID.c_str());
NewBaseCallBack(operationID, result);
set_app_background_status(_im_manager_listener.baseCallBack, operationID_cs, isBackground);
}
else {
result->Error("INVALID_ARGUMENT", "Arguments cannot be null");
}
}
void IMManagerService::networkStatusChanged(
const flutter::EncodableMap *arguments,
std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result) {
if (arguments) {
auto operationID = zego_value_get_string(arguments->at(flutter::EncodableValue("operationID")));
char* operationID_cs = const_cast<char*>(operationID.c_str());
NewBaseCallBack(operationID, result);
network_status_changed(_im_manager_listener.baseCallBack, operationID_cs);
}
else {
result->Error("INVALID_ARGUMENT", "Arguments cannot be null");
}
}

View File

@@ -0,0 +1,75 @@
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
// Use of this source code is governed by a MIT license that can be
// found in the LICENSE file.
#ifndef IMMANAGER_H
#define IMMANAGER_H
#include "../FLTService.h"
#include "Listen.h"
struct IMManagerServiceListener {
CB_I_S onInitSdk;
CB_S_I_S_S baseCallBack;
CB_I_S uploadCallback;
};
class IMManagerService : public FLTService {
public:
IMManagerService();
virtual void onMethodCalled(
const std::string& method, const flutter::EncodableMap* arguments,
std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result)
override;
private:
void initializeSDK(
const flutter::EncodableMap* arguments,
std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
void unInitSDK(
const flutter::EncodableMap* arguments,
std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
void login(
const flutter::EncodableMap* arguments,
std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
void logout(
const flutter::EncodableMap* arguments,
std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
void getLoginStatus(
const flutter::EncodableMap* arguments,
std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
void uploadFile(
const flutter::EncodableMap* arguments,
std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
void uploadLogs(
const flutter::EncodableMap* arguments,
std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
void logs(
const flutter::EncodableMap* arguments,
std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
void updateFcmToken(
const flutter::EncodableMap* arguments,
std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
void setAppBackgroundStatus(
const flutter::EncodableMap* arguments,
std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
void networkStatusChanged(
const flutter::EncodableMap* arguments,
std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
IMManagerServiceListener _im_manager_listener;
};
#endif // IMMANAGER_H

View File

@@ -0,0 +1,20 @@
#include "Listen.h"
#include <unordered_map>
std::unordered_map <std::string, std::unique_ptr<BaseCallBack>> g_baseCallBackMap;
std::mutex g_baseCallBackMapMutex;
void NewBaseCallBack(std::string opid,
std::shared_ptr <flutter::MethodResult<flutter::EncodableValue>> result) {
std::lock_guard <std::mutex> lock(g_baseCallBackMapMutex);
g_baseCallBackMap[opid] = std::make_unique<BaseCallBack>(result);
}
void CallBaseCallBack(char *opid, int errCode, char *errMsg, char *msg) {
std::lock_guard <std::mutex> lock(g_baseCallBackMapMutex);
auto it = g_baseCallBackMap.find(std::string(opid));
if (it != g_baseCallBackMap.end()) {
auto ctx = std::move(it->second); //unique_ptr
ctx->HandleCallback(opid, errCode, errMsg, msg);
}
}

View File

@@ -0,0 +1,58 @@
#ifndef LISTEN_H
#define LISTEN_H
#include <libopenimsdk.h>
#include "flutter/encodable_value.h"
#include "flutter/method_result.h"
class BaseCallBack {
public:
BaseCallBack(std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result) {
this->result = result;
}
std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result = nullptr;
void HandleCallback(char* opid, int errCode, char* errMsg, char* msg) {
if (result == nullptr) {
return;
}
if (errCode == 0) {
result->Success(flutter::EncodableValue(std::string(msg)));
}
else {
result->Error(std::to_string(errCode), std::string(errMsg), flutter::EncodableValue(std::string(msg)));
}
}
};
// 全局映射表
extern std::unordered_map<std::string, std::unique_ptr<BaseCallBack>> g_baseCallBackMap;
extern std::mutex g_baseCallBackMapMutex;
void NewBaseCallBack(std::string opid, std::shared_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
void CallBaseCallBack(char* opid, int errCode, char* errMsg, char* msg);
//todo 没想好怎么实现
class uploadFileCallBack {
public:
uploadFileCallBack(std::string id) {
this->id = id;
}
std::string id = "";
void HandleCallback(char* opid, int errCode, char* errMsg, char* msg) {
}
};
#endif

View File

@@ -0,0 +1,311 @@
/*
Using C++ template functions and recursion to initialize a function pointer pool,
combined with lambda expressions, this implementation manages function pointers,
achieving acquisition and release of pointers.All wrappers are used to convert
and map C++ functions to C functions, and with the use of indexed locking,
a thread-safe function pointer pool is implemented.For example, the wrapping
functions essentially map C++ functions to C functions. When a C function callback is triggered,
the function pointer pool, initialized through template recursion, locates the corresponding C++ function and invokes it.
*/
#define MAX_NUM_OF_CB_S 10
#define MAX_NUM_OF_CB_I_S 10
#define MAX_NUM_OF_CB_S_I_S_S 10
#define MAX_NUM_OF_CB_S_I_S_S_I 10
#define SLEEP_TIME_FOR_GET_INDEX 100 //ms
// use recursive template to generate enough function pointer array
// and define c type function interface
// and define manager class to manage function pool
namespace {
CB_S* _fps_cb_s=new CB_S[MAX_NUM_OF_CB_S];
CB_I_S* _fps_cb_i_s=new CB_I_S[MAX_NUM_OF_CB_I_S];
CB_S_I_S_S* _fps_cb_s_i_s_s=new CB_S_I_S_S[MAX_NUM_OF_CB_S_I_S_S];
CB_S_I_S_S_I* _fps_cb_s_i_s_s_i=new CB_S_I_S_S_I[MAX_NUM_OF_CB_S_I_S_S_I];
// c type func interface call cpp function
std::function<void(const std::string&)>* _cpp_function_cb_s=new std::function<void(const std::string&)>[MAX_NUM_OF_CB_S];
std::function<void(int,const std::string&)>* _cpp_function_cb_i_s=new std::function<void(int,const std::string&)>[MAX_NUM_OF_CB_I_S];
std::function<void(const std::string&,int,const std::string&,const std::string&)>* _cpp_function_cb_s_i_s_s=new std::function<void(const std::string&,int,const std::string&,const std::string&)>[MAX_NUM_OF_CB_S_I_S_S];
std::function<void(const std::string&,int,const std::string&,const std::string&,int)>* _cpp_function_cb_s_i_s_s_i=new std::function<void(const std::string&,int,const std::string&,const std::string&,int)>[MAX_NUM_OF_CB_S_I_S_S_I];
template<int N>
void _generate_cb_s(){
_fps_cb_s[N]=[](char* c_str){
_cpp_function_cb_s[N](std::string(c_str));
};
_generate_cb_s<N-1>();
}
template<>
void _generate_cb_s<0>(){
_fps_cb_s[0]=[](char* c_str){
_cpp_function_cb_s[0](std::string(c_str));
};
}
template<int N>
void _generate_cb_i_s(){
_fps_cb_i_s[N]=[](int code,char* c_str){
_cpp_function_cb_i_s[N](code,std::string(c_str));
};
_generate_cb_i_s<N-1>();
}
template<>
void _generate_cb_i_s<0>(){
_fps_cb_i_s[0]=[](int code,char* c_str){
_cpp_function_cb_i_s[0](code,std::string(c_str));
};
}
template<int N>
void _generate_cb_s_i_s_s(){
_fps_cb_s_i_s_s[N]=[](char* operationID,int code,char* c_str,char* c_str2){
_cpp_function_cb_s_i_s_s[N](std::string(operationID),code,std::string(c_str),std::string(c_str2));
};
_generate_cb_s_i_s_s<N-1>();
}
template<>
void _generate_cb_s_i_s_s<0>(){
_fps_cb_s_i_s_s[0]=[](char* operationID,int code,char* c_str,char* c_str2){
_cpp_function_cb_s_i_s_s[0](std::string(operationID),code,std::string(c_str),std::string(c_str2));
};
}
template<int N>
void _generate_cb_s_i_s_s_i(){
_fps_cb_s_i_s_s_i[N]=[](char* operationID,int code,char* c_str,char* c_str2,int c_int){
_cpp_function_cb_s_i_s_s_i[N](std::string(operationID),code,std::string(c_str),std::string(c_str2),c_int);
};
_generate_cb_s_i_s_s_i<N-1>();
}
template<>
void _generate_cb_s_i_s_s_i<0>(){
_fps_cb_s_i_s_s_i[0]=[](char* operationID,int code,char* c_str,char* c_str2,int c_int){
_cpp_function_cb_s_i_s_s_i[0](std::string(operationID),code,std::string(c_str),std::string(c_str2),c_int);
};
}
// init global function pointer array
void init(){
_generate_cb_s<MAX_NUM_OF_CB_S-1>();
_generate_cb_i_s<MAX_NUM_OF_CB_I_S-1>();
_generate_cb_s_i_s_s<MAX_NUM_OF_CB_S_I_S_S-1>();
_generate_cb_s_i_s_s_i<MAX_NUM_OF_CB_S_I_S_S_I-1>();
}
// define sigle instance class to manage function pool
class FuncPoolManager{
private:
// define a global bitmap, and support atomic operation, to manage cb_s pool
std::bitset<MAX_NUM_OF_CB_S> _cb_s_bitmap;
std::bitset<MAX_NUM_OF_CB_I_S> _cb_i_s_bitmap;
std::bitset<MAX_NUM_OF_CB_S_I_S_S> _cb_s_i_s_s_bitmap;
std::bitset<MAX_NUM_OF_CB_S_I_S_S_I> _cb_s_i_s_s_i_bitmap;
std::mutex _cb_s_mutex;
std::mutex _cb_i_s_mutex;
std::mutex _cb_s_i_s_s_mutex;
std::mutex _cb_s_i_s_s_i_mutex;
FuncPoolManager(){
init();
}
FuncPoolManager(const FuncPoolManager&){}
public:
static FuncPoolManager& get_instance(){
static FuncPoolManager instance;
return instance;
}
// get a available cb_s function index
int get_cb_s_index(){
std::lock_guard<std::mutex> lock(_cb_s_mutex);
int index=-1;
for(int i=0;i<_cb_s_bitmap.size();i++){
if(_cb_s_bitmap[i]==0){
_cb_s_bitmap[i]=1;
index=i;
break;
}
}
return index;
}
// get a available cb_i_s function index
int get_cb_i_s_index(){
std::lock_guard<std::mutex> lock(_cb_i_s_mutex);
int index=-1;
for(int i=0;i<_cb_i_s_bitmap.size();i++){
if(_cb_i_s_bitmap[i]==0){
_cb_i_s_bitmap[i]=1;
index=i;
break;
}
}
return index;
}
// get a available cb_s_i_s_s function index
int get_cb_s_i_s_s_index(){
std::lock_guard<std::mutex> lock(_cb_s_i_s_s_mutex);
int index=-1;
for(int i=0;i<_cb_s_i_s_s_bitmap.size();i++){
if(_cb_s_i_s_s_bitmap[i]==0){
_cb_s_i_s_s_bitmap[i]=1;
index=i;
break;
}
}
return index;
}
// get a available cb_s_i_s_s_i function index
int get_cb_s_i_s_s_i_index(){
std::lock_guard<std::mutex> lock(_cb_s_i_s_s_i_mutex);
int index=-1;
for(int i=0;i<_cb_s_i_s_s_i_bitmap.size();i++){
if(_cb_s_i_s_s_i_bitmap[i]==0){
_cb_s_i_s_s_i_bitmap[i]=1;
index=i;
break;
}
}
return index;
}
// release a available cb_s function index
int release_cb_s_index(int index){
std::lock_guard<std::mutex> lock(_cb_s_mutex);
if(index<0||index>=_cb_s_bitmap.size()){
return -1;
}
_cpp_function_cb_s[index]=nullptr;
_cb_s_bitmap[index]=0;
return 0;
}
// release a available cb_i_s function index
int release_cb_i_s_index(int index){
std::lock_guard<std::mutex> lock(_cb_i_s_mutex);
if(index<0||index>=_cb_i_s_bitmap.size()){
return -1;
}
_cpp_function_cb_i_s[index]=nullptr;
_cb_i_s_bitmap[index]=0;
return 0;
}
// release a available cb_s_i_s_s function index
int release_cb_s_i_s_s_index(int index){
std::lock_guard<std::mutex> lock(_cb_s_i_s_s_mutex);
if(index<0||index>=_cb_s_i_s_s_bitmap.size()){
return -1;
}
_cpp_function_cb_s_i_s_s[index]=nullptr;
_cb_s_i_s_s_bitmap[index]=0;
return 0;
}
// release a available cb_s_i_s_s_i function index
int release_cb_s_i_s_s_i_index(int index){
std::lock_guard<std::mutex> lock(_cb_s_i_s_s_i_mutex);
if(index<0||index>=_cb_s_i_s_s_i_bitmap.size()){
return -1;
}
_cpp_function_cb_s_i_s_s_i[index]=nullptr;
_cb_s_i_s_s_i_bitmap[index]=0;
return 0;
}
};
FuncPoolManager& instance=FuncPoolManager::get_instance();
// wrapper persistent function
// wrapp CB_S,if function pool is full,return nullptr
CB_S _wrapper_cpp_function(const std::function<void(const std::string&)>& cpp_function) {
int index=FuncPoolManager::get_instance().get_cb_s_index();
while(index<0){
std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME_FOR_GET_INDEX));
index=FuncPoolManager::get_instance().get_cb_s_index();
}
_cpp_function_cb_s[index]=cpp_function;
return _fps_cb_s[index];
}
// wrapp CB_I_S
CB_I_S _wrapper_cpp_function(const std::function<void(int,const std::string&)>& cpp_function)
{
int index=FuncPoolManager::get_instance().get_cb_i_s_index();
while(index<0){
std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME_FOR_GET_INDEX));
index=FuncPoolManager::get_instance().get_cb_i_s_index();
}
_cpp_function_cb_i_s[index]=cpp_function;
return _fps_cb_i_s[index];
}
// wrapp CB_S_I_S_S
CB_S_I_S_S _wrapper_cpp_function(const std::function<void(const std::string&,int,const std::string&,const std::string&)>& cpp_function)
{
int index=FuncPoolManager::get_instance().get_cb_s_i_s_s_index();
while(index<0){
std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME_FOR_GET_INDEX));
index=FuncPoolManager::get_instance().get_cb_s_i_s_s_index();
}
_cpp_function_cb_s_i_s_s[index]=cpp_function;
return _fps_cb_s_i_s_s[index];
}
// wrapp CB_S_I_S_S_I
CB_S_I_S_S_I _wrapper_cpp_function(const std::function<void(const std::string&,int,const std::string&,const std::string&,int)>& cpp_function)
{
int index=FuncPoolManager::get_instance().get_cb_s_i_s_s_i_index();
while(index<0){
std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME_FOR_GET_INDEX));
index=FuncPoolManager::get_instance().get_cb_s_i_s_s_i_index();
}
_cpp_function_cb_s_i_s_s_i[index]=cpp_function;
return _fps_cb_s_i_s_s_i[index];
}
// wrapp function to onetime function
CB_S _wrapper_callonce_cpp_function(const std::function<void(const std::string&)>& cpp_function) {
int index=FuncPoolManager::get_instance().get_cb_s_index();
while(index<0){
std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME_FOR_GET_INDEX));
index=FuncPoolManager::get_instance().get_cb_s_index();
}
_cpp_function_cb_s[index]=[cpp_function,index](const std::string& str)->void {
cpp_function(str);
FuncPoolManager::get_instance().release_cb_s_index(index);
};
return _fps_cb_s[index];
}
CB_I_S _wrapper_callonce_cpp_function(const std::function<void(int,const std::string&)>& cpp_function)
{
int index=FuncPoolManager::get_instance().get_cb_i_s_index();
while(index<0){
std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME_FOR_GET_INDEX));
index=FuncPoolManager::get_instance().get_cb_i_s_index();
}
_cpp_function_cb_i_s[index]=[cpp_function,index](int code,const std::string& str)->void {
cpp_function(code,str);
FuncPoolManager::get_instance().release_cb_i_s_index(index);
};
return _fps_cb_i_s[index];
}
CB_S_I_S_S _wrapper_callonce_cpp_function(const std::function<void(const std::string&,int,const std::string&,const std::string&)>& cpp_function)
{
int index=FuncPoolManager::get_instance().get_cb_s_i_s_s_index();
while(index<0){
std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME_FOR_GET_INDEX));
index=FuncPoolManager::get_instance().get_cb_s_i_s_s_index();
}
_cpp_function_cb_s_i_s_s[index]=[cpp_function,index](const std::string& operationID,int code,const std::string& str,const std::string& str2)->void {
cpp_function(operationID,code,str,str2);
FuncPoolManager::get_instance().release_cb_s_i_s_s_index(index);
};
return _fps_cb_s_i_s_s[index];
}
CB_S_I_S_S_I _wrapper_callonce_cpp_function(const std::function<void(const std::string&,int,const std::string&,const std::string&,int)>& cpp_function)
{
int index=FuncPoolManager::get_instance().get_cb_s_i_s_s_i_index();
// while loop util get a available index
while(index<0){
std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME_FOR_GET_INDEX));
index=FuncPoolManager::get_instance().get_cb_s_i_s_s_i_index();
}
_cpp_function_cb_s_i_s_s_i[index]=[cpp_function,index](const std::string& operationID,int code,const std::string& str,const std::string& str2,int c_int)->void {
cpp_function(operationID,code,str,str2,c_int);
FuncPoolManager::get_instance().release_cb_s_i_s_s_i_index(index);
};
return _fps_cb_s_i_s_s_i[index];
}
}

View File

@@ -0,0 +1,40 @@
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
// Use of this source code is governed by a MIT license that can be
// found in the LICENSE file.
#ifndef STABLE_H
#define STABLE_H
#if defined __cplusplus
// std
#include <any>
#include <filesystem>
#include <functional>
#include <iostream>
#include <list>
#include <map>
#include <memory>
#include <mutex>
#include <optional>
#include <sstream>
#include <string>
#include <unordered_map>
#include <vector>
#ifdef _WIN32
#endif
#include "utils/singleton.h"
#include "utils/stringHash.hpp"
// third parties
#include "alog.h"
#define YXLOGEnd ALOGEnd
#define YXLOG(level) ALOG_DIY("nim_core_plugin", LogNormal, level)
#define YXLOG_API(level) ALOG_DIY("nim_core_plugin", LogApi, level)
#endif
#endif // STABLE_H

View File

@@ -0,0 +1,54 @@
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
// Use of this source code is governed by a MIT license that can be
// found in the LICENSE file.
#ifndef BASE_SINGLETON_H_
#define BASE_SINGLETON_H_
#include <memory>
#include <mutex>
namespace utils {
template <typename T>
class Singleton {
public:
static T* getInstance();
Singleton(const Singleton& other) = delete;
Singleton<T>& operator=(const Singleton& other) = delete;
private:
static std::mutex mutex;
static T* instance;
};
template <typename T>
std::mutex Singleton<T>::mutex;
template <typename T>
T* Singleton<T>::instance;
template <typename T>
T* Singleton<T>::getInstance() {
if (instance == nullptr) {
std::lock_guard<std::mutex> locker(mutex);
if (instance == nullptr) {
instance = new T();
}
}
return instance;
}
#define SINGLETONG(Class) \
private: \
friend class utils::Singleton<Class>; \
\
public: \
static Class* getInstance() { return utils::Singleton<Class>::getInstance(); }
#define HIDE_CONSTRUCTOR(Class) \
private: \
Class() = default; \
Class(const Class& other) = delete; \
Class& operator=(const Class& other) = delete; \
}
}
#endif // BASE_SINGLETON_H_

View File

@@ -0,0 +1,35 @@
// Copyright (c) 2022 NetEase, Inc. All rights reserved.
// Use of this source code is governed by a MIT license that can be
// found in the LICENSE file.
#ifndef BASE_STRINGHASH_H_
#define BASE_STRINGHASH_H_
namespace utils {
typedef std::uint64_t hash_t;
constexpr hash_t prime = 0x100000001B3ull;
constexpr hash_t basis = 0xCBF29CE484222325ull;
inline hash_t hash_(char const* str) {
hash_t ret{basis};
while (*str) {
ret ^= *str;
ret *= prime;
str++;
}
return ret;
}
constexpr hash_t hash_compile_time(char const* str, hash_t last_value = basis) {
return *str ? hash_compile_time(str + 1, (*str ^ last_value) * prime) : last_value;
}
} // namespace utils
constexpr unsigned long long operator"" _hash(char const* p, size_t) {
return utils::hash_compile_time(p);
}
#endif // BASE_STRINGHASH_H_