first commit

main
commit ebb9887739

4
.gitignore vendored

@ -0,0 +1,4 @@
third_party/*
!third_party/.gitkeep
.idea
cmake-build-debug

@ -0,0 +1,100 @@
cmake_minimum_required(VERSION 3.26)
project(csci)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_PREFIX_PATH $ENV{QT_5_MINGW64})
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${CMAKE_CURRENT_BINARY_DIR}")
set(BOOST_INCLUDES third_party/boost-1_83/include)
# QxOrm
include(third_party/QxOrm/QxOrm.cmake)
add_executable(${PROJECT_NAME} main.cpp)
add_subdirectory(third_party/QxOrm)
add_dependencies(${PROJECT_NAME} QxOrm)
find_package(Qt5 COMPONENTS
Core
Concurrent
Sql
REQUIRED)
target_link_libraries(${PROJECT_NAME} PUBLIC
Qt5::Core
Qt5::Concurrent
Qt5::Sql
)
#
aux_source_directory(config CONFIG_DIR)
aux_source_directory(controller CONTROLLER_DIR)
aux_source_directory(service SERVICE_DIR)
aux_source_directory(entity ENTITY_DIR)
aux_source_directory(handler HANDLER_DIR)
aux_source_directory(compute COMPUTE_DIR)
aux_source_directory(kafka KAFKA_DIR)
target_include_directories(${PROJECT_NAME} PRIVATE
include/code
include/kafka
include/controller
${BOOST_INCLUDES}
)
target_sources(${PROJECT_NAME} PRIVATE
${CONFIG_DIR}
${CONTROLLER_DIR}
${SERVICE_DIR}
${ENTITY_DIR}
${HANDLER_DIR}
${COMPUTE_DIR}
${KAFKA_DIR}
)
target_link_libraries(${PROJECT_NAME} PUBLIC
rdkafka
rdkafka++
QxOrm
)
#
file(COPY application.ini DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) # QxOrm
file(COPY lib/kafka/ DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) # kafka
file(GLOB LIB "lib/*.dll")
file(COPY ${LIB} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) # mysql
file(COPY lib/sqldrivers DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) # QT mysql
file(COPY third_party/QxOrm/lib/ DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) # QxOrm
if (WIN32 AND NOT DEFINED CMAKE_TOOLCHAIN_FILE)
set(DEBUG_SUFFIX)
if (MSVC AND CMAKE_BUILD_TYPE MATCHES "Debug")
set(DEBUG_SUFFIX "d")
endif ()
set(QT_INSTALL_PATH "${CMAKE_PREFIX_PATH}")
if (NOT EXISTS "${QT_INSTALL_PATH}/bin")
set(QT_INSTALL_PATH "${QT_INSTALL_PATH}/..")
if (NOT EXISTS "${QT_INSTALL_PATH}/bin")
set(QT_INSTALL_PATH "${QT_INSTALL_PATH}/..")
endif ()
endif ()
if (EXISTS "${QT_INSTALL_PATH}/plugins/platforms/qwindows${DEBUG_SUFFIX}.dll")
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory
"$<TARGET_FILE_DIR:${PROJECT_NAME}>/plugins/platforms/")
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
"${QT_INSTALL_PATH}/plugins/platforms/qwindows${DEBUG_SUFFIX}.dll"
"$<TARGET_FILE_DIR:${PROJECT_NAME}>/plugins/platforms/")
endif ()
foreach (QT_LIB Core Concurrent Sql)
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
"${QT_INSTALL_PATH}/bin/Qt5${QT_LIB}${DEBUG_SUFFIX}.dll"
"$<TARGET_FILE_DIR:${PROJECT_NAME}>")
endforeach (QT_LIB)
endif ()

@ -0,0 +1,13 @@
[database]
host=localhost
port=3306
database=csci
username=csci
password=csci@1234
driver=QMYSQL
[kafka]
consumer.servers=localhost:9092
consumer.topics=test_topic
producer.servers=localhost:9092

@ -0,0 +1,2 @@
#include "operator.h"

@ -0,0 +1,36 @@
#ifndef CSCI_OPERATOR_H
#define CSCI_OPERATOR_H
class Operator {
public:
/// 初始化
void init();
/// 更新
void update();
/// 上报状态
void report();
///
private:
/// 模型参数
int model;
};
#endif //CSCI_OPERATOR_H

@ -0,0 +1,66 @@
#include "database_config.h"
DatabaseConfig* DatabaseConfig::getIns() {
static DatabaseConfig dataBaseConfig;
return &dataBaseConfig;
}
DatabaseConfig::DatabaseConfig() {
_host = "localhost";
_port = 0;
_database = "";
_username = "root";
_password = "";
_driver = "QSQLITE";
}
void DatabaseConfig::load(QSettings *configs) {
if(configs->value("host").isValid()){
_host = configs->value("host").toString();
}
if(configs->value("port").isValid()){
_port = configs->value("port").toInt();
}
if(configs->value("database").isValid()){
_database = configs->value("database").toString();
}
if(configs->value("username").isValid()){
_username = configs->value("username").toString();
}
if(configs->value("password").isValid()){
_password = configs->value("password").toString();
}
if(configs->value("driver").isValid()){
_driver = configs->value("driver").toString();
}
}
QString DatabaseConfig::getHost() const {
return _host;
}
int DatabaseConfig::getPort() const {
return _port;
}
QString DatabaseConfig::getDatabase() const {
return _database;
}
QString DatabaseConfig::getUsername() const {
return _username;
}
QString DatabaseConfig::getPassword() const {
return _password;
}
QString DatabaseConfig::getDriver() const {
return _driver;
}
DatabaseConfig::~DatabaseConfig() = default;

@ -0,0 +1,43 @@
#ifndef CSCI_DATABASE_CONFIG_H
#define CSCI_DATABASE_CONFIG_H
#include <QSettings>
class DatabaseConfig {
private:
QString _host;
int _port;
QString _database;
QString _username;
QString _password;
QString _driver;
private:
DatabaseConfig();
public:
~DatabaseConfig();
void load(QSettings* configs);
QString getHost() const;
int getPort() const;
QString getDatabase() const;
QString getUsername() const;
QString getPassword() const;
QString getDriver() const;
public:
static DatabaseConfig* getIns();
};
#endif //CSCI_DATABASE_CONFIG_H

@ -0,0 +1,36 @@
#include "kafka_config.h"
KafkaConfig* KafkaConfig::getIns() {
static KafkaConfig kafkaConfig;
return &kafkaConfig;
}
KafkaConfig::KafkaConfig() = default;
void KafkaConfig::load(QSettings *configs) {
if(configs->value("consumer.servers").isValid()){
_consumerServers = configs->value("consumer.servers").toStringList();
}
if(configs->value("consumer.topics").isValid()){
_consumerTopics = configs->value("consumer.topics").toStringList();
}
if(configs->value("producer.servers").isValid()){
_producerServers = configs->value("producer.servers").toStringList();
}
}
QStringList KafkaConfig::getConsumerServers() const {
return _consumerServers;
}
QStringList KafkaConfig::getConsumerTopics() const {
return _consumerTopics;
}
QStringList KafkaConfig::getProducerServers() const {
return _producerServers;
}
KafkaConfig::~KafkaConfig() = default;

@ -0,0 +1,36 @@
#ifndef CSCI_KAFKA_CONFIG_H
#define CSCI_KAFKA_CONFIG_H
#include <QSettings>
class KafkaConfig {
private:
QStringList _consumerServers;
QStringList _consumerTopics;
QStringList _producerServers;
private:
KafkaConfig();
public:
~KafkaConfig();
void load(QSettings* configs);
QStringList getConsumerServers() const;
QStringList getConsumerTopics() const;
QStringList getProducerServers() const;
public:
static KafkaConfig* getIns();
};
#endif //CSCI_KAFKA_CONFIG_H

@ -0,0 +1,49 @@
#include "log_config.h"
LogConfig* LogConfig::getIns() {
static LogConfig logConfig;
return &logConfig;
}
void LogConfig::load(QSettings *configs) {
if (configs->value("fileDir").isValid()){
_fileDir = configs->value("fileDir").toString();
}
if (configs->value("filesize").isValid()){
_filesize = configs->value("filesize").toInt();
}
if (configs->value("validity").isValid()){
_validity = configs->value("validity").toInt();
}
}
void LogConfig::setFileDir(const QString& fileDir) {
_fileDir = fileDir;
}
void LogConfig::setFileSize(int filesize) {
_filesize = filesize;
}
LogConfig::LogConfig() {
_fileDir = "./logs";
_filesize = 10 * 1024 * 1024;
_validity = 30;
}
QString LogConfig::getFileDir() const {
return _fileDir;
}
int LogConfig::getFileSize() const {
return _filesize;
}
int LogConfig::getValidity() const {
return _validity;
}
LogConfig::~LogConfig() = default;

@ -0,0 +1,37 @@
#ifndef CSCI_LOG_CONFIG_H
#define CSCI_LOG_CONFIG_H
#include <QSettings>
class LogConfig {
private:
QString _fileDir;
int _filesize;
int _validity;
private:
LogConfig();
public:
~LogConfig();
void load(QSettings* configs);
void setFileDir(const QString& dir);
void setFileSize(int filesize);
QString getFileDir() const;
int getFileSize() const;
int getValidity() const;
public:
static LogConfig* getIns();
};
#endif //CSCI_LOG_CONFIG_H

@ -0,0 +1,26 @@
#include "map_controller.h"
bool MapController::loadMap(long mapId) {
auto mapEntity = MapEntity::findById(mapId);
qDebug() << mapEntity.mapName;
// TODO 获取数据
// 分析模型
// 初始化
return false;
}
void MapController::route(const QString& key, const QString& message) {
qDebug() << key << ":" << message;
// TODO route to function
if(key == "loadMap"){
loadMap(1);
}
}

@ -0,0 +1,28 @@
#ifndef CSCI_MAP_CONTROLLER_H
#define CSCI_MAP_CONTROLLER_H
#include "../entity/map_entity.h"
#include "../include/controller/base_controller.h"
/// 仿真场景控制
class MapController: public BaseController<MapController> {
Q_OBJECT
public:
/**
*
* @param int mapId id
* @return boolfalse
*/
bool loadMap(long mapId);
public slots:
void route(const QString& key, const QString& message);
};
#endif //CSCI_MAP_CONTROLLER_H

@ -0,0 +1,31 @@
#include "simulation_controller.h"
void SimulationController::route(const QString &key, const QString &message) {
qDebug() << "form simulation" << key << message;
}
void SimulationController::setStepTime(int stepTime) {
if(stepTime <= 50){
message("DC_TOPIC", "仿真步长不能低于50ms");
}
// TODO 暂不支持设置
}
void SimulationController::start(long mapId) {
}
void SimulationController::stop(long simId) {
}

@ -0,0 +1,52 @@
#ifndef CSCI_SIMULATION_CONTROLLER_H
#define CSCI_SIMULATION_CONTROLLER_H
#include "../include/controller/base_controller.h"
#include "../service/simulation_service.h"
class SimulationController : public BaseController<SimulationController> {
Q_OBJECT
public:
/**
* 仿
* @param stepTime 仿ms
*/
void setStepTime(int stepTime);
/**
* 仿
* @param mapId id
*/
void start(long mapId);
/**
* 仿
* @param simId 仿id
*/
void stop(long simId);
/***
* / 仿
* @param simID
*/
void pause(long simID);
/**
*
* FIXME
*/
void speed();
public slots:
void route(const QString& key, const QString& message) override;
};
#endif //CSCI_SIMULATION_CONTROLLER_H

@ -0,0 +1,26 @@
#include "map_entity.h"
QX_REGISTER_CPP(MapEntity)
namespace qx {
template <> void register_class(QxClass<MapEntity> & t)
{
t.setName("csci_map");
t.id(& MapEntity::id, "id");
t.data(& MapEntity::mapName, "map_name");
}}
MapEntity::MapEntity(): id(0) {
}
MapEntity MapEntity::findById(long id) {
MapEntity mapEntity;
mapEntity.id = id;
qx::dao::fetch_by_id(mapEntity);
return mapEntity;
}
MapEntity::~MapEntity() = default;

@ -0,0 +1,24 @@
#ifndef CSCI_MAP_ENTITY_H
#define CSCI_MAP_ENTITY_H
#include <precompiled.h>
#include <QxOrm_Impl.h>
class MapEntity{
public:
long id;
QString mapName;
public:
MapEntity();
virtual ~MapEntity();
public:
static MapEntity findById(long id);
};
QX_REGISTER_HPP(MapEntity, qx::trait::no_base_class_defined, 0)
#endif //CSCI_MAP_ENTITY_H

@ -0,0 +1,40 @@
#include "controller_handler.h"
QString ControllerHandler::getClassname(const char *mangled_name) {
#ifndef _MSC_VER
std::size_t len = 0;
int status = 0;
std::unique_ptr<char, decltype(&std::free)> ptr(
__cxxabiv1::__cxa_demangle(mangled_name, nullptr, &len, &status),
&std::free);
if (status == 0) {
return { ptr.get() };
}
return "";
#else
auto pos = strstr(mangled_name, " ");
if (pos == nullptr)
return std::string{mangled_name};
else
return std::string{pos + 1};
#endif
}
void ControllerHandler::registerCtl(const QString &key, const ControllerFunc &fun) {
getControllerFuncMap().insert(key.toUtf8(), fun);
}
ControllerFuncMap &ControllerHandler::getControllerFuncMap() {
static ControllerFuncMap controllerFuncMap;
return controllerFuncMap;
}
void ControllerHandler::init() {
auto funcMap = getControllerFuncMap();
for (const auto &key: funcMap.keys()){
auto ins = funcMap.value(key)();
QObject::connect(KafkaHandler::getIns(), SIGNAL(handle(QString, QString)), ins, SLOT(route(QString,QString)));
}
}

@ -0,0 +1,37 @@
#ifndef CSCI_CONTROLLER_HANDLER_H
#define CSCI_CONTROLLER_HANDLER_H
#include <functional>
#include <QString>
#include <memory>
#include <QMap>
#ifndef _MSC_VER
#include <cxxabi.h>
#endif
#include "kafka_handler.h"
#include "../include/controller/controller.h"
using ControllerFunc = std::function<Controller *()>;
using ControllerFuncMap = QMap<QByteArray, ControllerFunc>;
class ControllerHandler: public QObject {
Q_OBJECT
private:
static ControllerFuncMap &getControllerFuncMap();
public:
static void init();
static QString getClassname(const char *mangled_name);
static void registerCtl(const QString &key, const ControllerFunc &fun);
};
#endif //CSCI_CONTROLLER_HANDLER_H

@ -0,0 +1,22 @@
#include "database_handler.h"
void DataBaseHandler::init() {
auto databaseConf = DatabaseConfig::getIns();
qx::QxSqlDatabase::getSingleton()->setDriverName(databaseConf->getDriver());
qx::QxSqlDatabase::getSingleton()->setDatabaseName(databaseConf->getDatabase());
qx::QxSqlDatabase::getSingleton()->setHostName(databaseConf->getHost());
qx::QxSqlDatabase::getSingleton()->setPort(databaseConf->getPort());
qx::QxSqlDatabase::getSingleton()->setUserName(databaseConf->getUsername());
qx::QxSqlDatabase::getSingleton()->setPassword(databaseConf->getPassword());
qx::QxSqlDatabase::getSingleton()->setFormatSqlQueryBeforeLogging(true);
QSqlDatabase database = qx::QxSqlDatabase::getSingleton()->getDatabase();
if(database.open())
{
qWarning("database is connect success!");
}
else
{
qWarning("database is connect failed!");
}
}

@ -0,0 +1,18 @@
#ifndef CSCI_DATABASE_HANDLER_H
#define CSCI_DATABASE_HANDLER_H
#include <QObject>
#include <precompiled.h>
#include <QxOrm_Impl.h>
#include "../config/database_config.h"
class DataBaseHandler: public QObject{
Q_OBJECT
public:
static void init();
};
#endif //CSCI_DATABASE_HANDLER_H

@ -0,0 +1,162 @@
#include "kafka_handler.h"
#include <QVector>
bool KafkaHandler::_run = false;
RdKafka::Producer* KafkaHandler::_producer = nullptr;
void KafkaHandler::init() {
auto conf = KafkaConfig::getIns();
auto consumerServers = conf->getConsumerServers().join(",").toStdString();
auto consumerTopics = conf->getConsumerTopics();
auto producer = conf->getProducerServers().join(",").toStdString();
if(consumerTopics.empty()){
qFatal("kafka consumer topic can`t empty ");
}
// 初始化 consumer
_run = true;
_initConsumer(consumerServers, consumerTopics);
// 实例化 producer
_initProducer(producer);
}
void KafkaHandler::_initConsumer(const std::string& servers, const QStringList& topics) {
auto conf=RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL);
std::string err;
if(conf->set("bootstrap.servers", servers, err) != RdKafka::Conf::CONF_OK){
qFatal("kafka consumer set bootstrap servers error: %s", &err);
}
if(conf->set("group.id",topics.join(",").toStdString(),err) != RdKafka::Conf::CONF_OK){
qFatal("kafka consumer set group id error: %s", &err);
}
//创建消费者
auto consumer= RdKafka::KafkaConsumer::create(conf,err);
if (!consumer) {
qFatal("create consumer error: %s", &err);
}
QVector<std::string> vector;
for (const auto &item: topics.toVector()){
vector.push_back(item.toStdString());
}
consumer->subscribe(vector.toStdVector());
QtConcurrent::run(_consumerStart, consumer);
}
void KafkaHandler::_consumerStart(RdKafka::KafkaConsumer * consumer) {
while (_run){
RdKafka::Message *msg = consumer->consume(100);
_receive(msg);
}
consumer->close();
delete consumer;
}
void KafkaHandler::_receive(RdKafka::Message *message) {
switch (message->err())
{
case RdKafka::ERR__TIMED_OUT:
break;
case RdKafka::ERR_NO_ERROR:
{
// TODO key 校验 message->key()
QString key;
if(message->key()){
key = QString::fromStdString(*message->key());
qDebug() << "receive message key:" << key;
}
// TODO header 校验 message->headers()
auto headers = message->headers();
if (headers) {
std::vector<RdKafka::Headers::Header> hdrs = headers->get_all();
for (size_t i = 0; i < hdrs.size(); i++) {
const RdKafka::Headers::Header hdr = hdrs[i];
if (hdr.value() != nullptr){
std::string value (static_cast<const char*>(hdr.value()), hdr.value_size());
qDebug() << "receive message headers: " << QString::fromStdString(hdr.key())
<< "-" << QString::fromStdString(value);
}
}
}
std::string payload (static_cast<const char*>(message->payload()), message->len());
auto msg = QString::fromStdString(payload);
qDebug() << "receive message payload:" << msg;
emit getIns()->handle(key, msg);
}
break;
case RdKafka::ERR__PARTITION_EOF:
break;
case RdKafka::ERR__UNKNOWN_TOPIC:
case RdKafka::ERR__UNKNOWN_PARTITION:
qCritical("consume failed: %s", qPrintable(QString::fromStdString(message->errstr())));
_run = false;
break;
default:
qWarning("consume failed: %s" , qPrintable(QString::fromStdString(message->errstr())));
_run = false;
break;
}
}
void KafkaHandler::stop() {
_run = false;
}
void KafkaHandler::_initProducer(const std::string &servers) {
auto conf= RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL);
std::string err;
if(conf->set("bootstrap.servers", servers, err) != RdKafka::Conf::CONF_OK){
qFatal("kafka consumer set bootstrap servers error: %s", &err);
}
//创建生产者
_producer = RdKafka::Producer::create(conf,err);
if(!_producer)
{
qFatal("create producer error: %s", &err);
}
}
bool KafkaHandler::message(const QString& topic, const QString& message,const QString& key, RdKafka::Headers *headers, int partition, void * que) {
auto payload = message.toStdString();
std::string k;
if(nullptr != key){
k = key.toStdString();
}
auto code = _producer->produce(topic.toStdString(),
partition,
RdKafka::Producer::RK_MSG_COPY,
const_cast<char *>(payload.c_str()),
payload.size(),
const_cast<char *>(k.c_str()), k.size(),
0,
headers,
que
);
return RdKafka::ERR_NO_ERROR == code;
}
KafkaHandler *KafkaHandler::getIns() {
static KafkaHandler kafkaHandler;
return &kafkaHandler;
}
KafkaHandler::KafkaHandler() = default;
KafkaHandler::~KafkaHandler() = default;

@ -0,0 +1,53 @@
#ifndef CSCI_KAFKA_HANDLER_H
#define CSCI_KAFKA_HANDLER_H
#include <QObject>
#include <QDebug>
#include <QtConcurrent>
#include "../config/kafka_config.h"
#include "../include/kafka/rdkafkacpp.h"
class KafkaHandler: public QObject{
Q_OBJECT
private:
static bool _run;
static RdKafka::Producer* _producer;
private:
static void _initConsumer(const std::string& servers, const QStringList& topics);
static void _consumerStart(RdKafka::KafkaConsumer * consumer);
static void _receive(RdKafka::Message *message);
static void _initProducer(const std::string& servers);
public:
static void init();
static void stop();
static KafkaHandler* getIns();
static bool message(const QString& topic, const QString& message, const QString& key = nullptr,
RdKafka::Headers *headers = RdKafka::Headers::create(),
int partition = RdKafka::Topic::PARTITION_UA, void * que = nullptr);
public:
KafkaHandler();
public:
~KafkaHandler();
public: signals:
void handle(const QString & key, const QString & message);
};
#endif //CSCI_KAFKA_HANDLER_H

@ -0,0 +1,84 @@
#include "log_handler.h"
void LogHandler::_log(QtMsgType msgType, const QMessageLogContext &context, const QString &msg) {
// 加锁
static QMutex mutex;
static int count = 0;
QString type;
switch(msgType) {
case QtDebugMsg:
type = QString("Debug");
break;
case QtWarningMsg:
type = QString("Warning");
break;
case QtCriticalMsg:
type = QString("Critical");
break;
case QtFatalMsg:
type = QString("Fatal");
break;
default:
type = QString("Info");
}
mutex.lock();
QString context_info = QString("%1#%2@%3").arg(context.file).arg(context.function).arg(context.line);
QString current_date_time = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");
QString current_date = QString("(%1)").arg(current_date_time);
QString message = QString("%1|%2|%3: %4").arg(current_date, type, context_info, msg);
_write(message);
mutex.unlock();
count ++;
if(count > 5000){
count = 0;
_clear();
}
}
void LogHandler::init() {
qInstallMessageHandler(_log);
auto logDir = QCoreApplication::applicationDirPath() + LogConfig::getIns()->getFileDir();
QDir dir(logDir);
if (!dir.exists()){
dir.mkdir(logDir);
}
_clear();
}
void LogHandler::_clear() {
auto logCof = LogConfig::getIns();
auto logDir = QCoreApplication::applicationDirPath() + logCof->getFileDir();
QDir dir(logDir);
QFileInfoList fileInfos = dir.entryInfoList(QDir::Files);
auto validity = logCof->getValidity();
foreach (QFileInfo fileInfo, fileInfos) {
if(fileInfo.birthTime().addDays(validity) <= QDateTime::currentDateTime()){
QFile::setPermissions(logDir + "/" +fileInfo.fileName(), QFileDevice::ReadOther | QFileDevice::WriteOther);
QFile::remove(logDir + "/" +fileInfo.fileName());
}
}
}
void LogHandler::_write(const QString& message) {
auto filename = QDateTime::currentDateTime().toString("yyyy-MM-dd");
auto filepath = QCoreApplication::applicationDirPath() + LogConfig::getIns()->getFileDir() + "/" + filename + ".log";
int i = 1;
QFile file(filepath);
while(file.size() >= LogConfig::getIns()->getFileSize()){
auto nextFilename= filename + "_" + i + ".log";
file.setFileName(nextFilename);
i++;
}
if(file.open(QIODevice::WriteOnly | QIODevice::Append)){
QTextStream write(&file);
write.setCodec("utf-8");
write << message << "\r\n";
file.flush();
file.close();
}
}

@ -0,0 +1,30 @@
#ifndef CSCI_LOG_HANDLER_H
#define CSCI_LOG_HANDLER_H
#include <QDir>
#include <QMutex>
#include <QObject>
#include <QDateTime>
#include <QTextStream>
#include <QCoreApplication>
#include "../config/log_config.h"
class LogHandler : public QObject{
Q_OBJECT
private:
static void _log(QtMsgType msgType, const QMessageLogContext &context, const QString &msg);
static void _clear();
static void _write(const QString& message);
public:
static void init();
};
#endif //CSCI_LOG_HANDLER_H

@ -0,0 +1,5 @@
#ifndef CSCI_ERR_CODE_H
#define CSCI_ERR_CODE_H
#endif //CSCI_ERR_CODE_H

@ -0,0 +1,54 @@
#ifndef CSCI_BASE_CONTROLLER_H
#define CSCI_BASE_CONTROLLER_H
#include "controller.h"
#include "../../handler/controller_handler.h"
template<typename T>
class BaseController : public Controller {
private:
class Allocator{
public:
Allocator() {
registerClass<T>();
}
[[nodiscard]] const QString &className() const {
static QString class_name = ControllerHandler::getClassname(typeid(T).name());
return class_name;
}
template<typename D>
typename std::enable_if<std::is_default_constructible<D>::value,
void>::type
registerClass() {
ControllerHandler::registerCtl(className(), []() -> BaseController * { return new T(); });
}
template<typename D>
typename std::enable_if<!std::is_default_constructible<D>::value,
void>::type
registerClass() {
}
};
public:
const QString className() const override {
return allocator.className();
}
private:
static Allocator allocator;
public:
static QString getClassName() {
return allocator.className();
}
};
template<typename T>
typename BaseController<T>::Allocator BaseController<T>::allocator;
#endif //CSCI_BASE_CONTROLLER_H

@ -0,0 +1,35 @@
#ifndef CSCI_CONTROLLER_H
#define CSCI_CONTROLLER_H
#include <QString>
#include <QObject>
#include "../../handler/kafka_handler.h"
class Controller : public QObject {
public:
virtual const QString className() const {
return "Controller";
}
virtual void route(const QString& key, const QString& message){}
/**
*
* @param topic
* @param message
* @param key
* @param headers
*/
void message(const QString& topic, const QString& message, const QString& key = nullptr,
RdKafka::Headers *headers = RdKafka::Headers::create()){
KafkaHandler::message(topic,message,key,headers);
}
};
#endif //CSCI_CONTROLLER_H

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -0,0 +1,156 @@
#include <QCoreApplication>
#include "config/log_config.h"
#include "config/database_config.h"
#include "config/kafka_config.h"
#include "handler/log_handler.h"
#include "handler/database_handler.h"
#include "handler/kafka_handler.h"
#include "handler/controller_handler.h"
void loadConfig(const QString& filename){
QFile file(filename);
if(!file.exists()){
qFatal("config file %s is not found!" , qPrintable(filename));
}
auto configs = new QSettings(filename, QSettings::IniFormat);
auto logConf = LogConfig::getIns();
configs->beginGroup("log");
logConf->load(configs);
configs->endGroup();
auto kafkaConf = KafkaConfig::getIns();
configs->beginGroup("kafka");
kafkaConf->load(configs);
configs->endGroup();
auto databaseConf = DatabaseConfig::getIns();
configs->beginGroup("database");
databaseConf->load(configs);
configs->endGroup();
}
void init(){
// 初始化日志, 开启会记录日志到文件
LogHandler::init();
// 初始化数据库
DataBaseHandler::init();
// 初始化Kafka
KafkaHandler::init();
// 初始化Controller
ControllerHandler::init();
}
#include <boost/numeric/odeint.hpp>
using namespace std;
using namespace boost::numeric::odeint;
typedef vector<double> State;
typedef vector<double> Control;
double Nx = 3.0;
double Nz = 2.0;
double mu = M_PI / 12.;
Control control = { Nx, Nz, mu };
vector<State> state_list;
// 飞行器的运动学方程
void dmove2(const State& x_input, State& dxdt, const double t) {
double velocity = x_input[0];
double gamma = x_input[1];
double varphi = x_input[2];
double nx = control[0];
double nz = control[1];
varphi = control[2];
// if(varphi == 0){
// varphi = control[2];
// }
double g = 9.81; // 重力加速度
double velocity_ = g * (nx - sin(gamma)); // 米每秒
double gamma_ = (g / velocity) * (nz * cos(varphi) - cos(gamma)); // 米每秒
double varphi_ = g * nz * sin(varphi) / (velocity * cos(gamma));
dxdt[0] = velocity_;
dxdt[1] = gamma_;
dxdt[2] = varphi_;
}
int k = 1;
void write_pendulum(const State &x, const double t)
{
double velocity = x[0];
double gamma = x[1];
double varphi = x[2];
double dx = velocity * cos(gamma) * sin(varphi);
double dy = velocity * cos(gamma) * cos(varphi);
double dz = velocity * sin(gamma);
State new_state(6);
new_state[0] = state_list[k - 1][0] + dx;
new_state[1] = state_list[k - 1][1] + dy;
new_state[2] = state_list[k - 1][2] + dz;
new_state[3] = velocity;
new_state[4] = gamma;
new_state[5] = varphi;
k++;
state_list.push_back(new_state);
}
void boost_test(){
double init_velocity = 260.0;
double init_gamma = M_PI / 10.0;
double init_varphi = 0.0;
double init_x = 0.0;
double init_y = 0.0;
double init_z = 1000.0;
State int_state(6);
int_state[0] = init_x;
int_state[1] = init_y;
int_state[2] = init_z;
int_state[3] = init_velocity;
int_state[4] = init_gamma;
int_state[5] = init_varphi;
state_list.push_back(int_state);
State init_state = { init_velocity, init_gamma, init_varphi };
integrate_const(runge_kutta4<State>(), dmove2, init_state, 0.0 ,10.0 ,0.1, write_pendulum);
string filename = R"(test.csv)";
ofstream ofs(filename);
if(ofs.is_open()){
ofs << "x,y,z,v,g,f\n";
for (const auto& state : state_list) {
int i = 0;
for (const auto& val : state) {
cout << val << ",";
if(i == 5){
ofs << val;
i = 0;
}else{
ofs << val << ",";
i++;
}
}
cout << "\n";
ofs << "\n";
}
ofs.close();
}
}
/// TODO 当前是将消息广播全部消费者自行判断是否消费,该种机制是否合理后续在进行论证
int main(int argc, char *argv[]) {
QCoreApplication app(argc, argv);
// 加载配置文件
// loadConfig(QCoreApplication::applicationDirPath() + "/application.ini");
// 初始化系统
// init();
/// test -start
// qDebug() << "init";
// QString msg = "{\"name\":\"张三\"}";
// QString key = "loadMap";
// auto headers = RdKafka::Headers::create();
// headers->add("token", "safdasgdagafgafdsghfsjh");
// KafkaHandler::message("test_topic" , msg, key , headers);
boost_test();
/// test -end
return QCoreApplication::exec();
}

@ -0,0 +1,2 @@
#include "simulation_service.h"

@ -0,0 +1,22 @@
#ifndef CSCI_SIMULATION_SERVICE_H
#define CSCI_SIMULATION_SERVICE_H
#include <QObject>
#include "../include/code/err_code.h"
enum SimulationCommand { START, STOP , PAUSE, RESUME, EXPEDITE, RETARD };
class SimulationService : public QObject{
Q_OBJECT
public:
};
#endif //CSCI_SIMULATION_SERVICE_H

@ -0,0 +1,26 @@
#include "timer_service.h"
bool TimerService::_run = false;
int TimerService::_interval = 200;
QTimer TimerService::_timer;
void TimerService::start() {
if(_run){
}
_run = true;
_timer.start(_interval);
}
void TimerService::stop() {
_timer.stop();
}
TimerService *TimerService::getIns() {
// _timer->stop();
// return nullptr;
}

@ -0,0 +1,29 @@
#ifndef CSCI_TIMER_SERVICE_H
#define CSCI_TIMER_SERVICE_H
#include <QObject>
#include <QTimer>
class TimerService : public QObject{
Q_OBJECT
private:
static bool _run;
static int _interval;
static QTimer _timer;
public:
static void start();
static void stop();
static TimerService* getIns();
};
#endif //CSCI_TIMER_SERVICE_H
Loading…
Cancel
Save