commit
ebb9887739
@ -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,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,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,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…
Reference in new issue