diff --git a/include/busModel.h b/include/busModel.h index 93e9c50..5b4da61 100644 --- a/include/busModel.h +++ b/include/busModel.h @@ -14,137 +14,39 @@ #include "sstream" #include "QObject" #include "QDebug" +#include "QTimer" /** - * 控制公交车的类,继承了QObject + * 公交车模型类 */ -class BusControllerModel : public QObject +class BusModel { - Q_OBJECT public: - /** - * 指向公交车所在站点的指针 - */ rail_node_t *rail_pos; /** - * 当前行进的距离 + * 公交车前进的速度 */ - int distance; + const int velocity = 1; /** * 当前前进的方向 */ int direction; - /** - * 公交车的计时时刻 - */ - int bus_time; + QTimer *bus_timer; + + explicit BusModel(); + + ~BusModel(); /** - * 轨道对象 + * 重置公交车 + * @param head 轨道的头节点位置 */ - RailsModel *rail_manager; + void ResetBus(rail_node_t *head); - /** - * 请求控制对象 - */ - QueryModel *query_manager; - - /** - * 选定的策略 - */ - int chosen_strategy = -1; - - /** - * 构造函数 - * - */ - BusControllerModel(); - - /** - * 析构函数 - */ - ~BusControllerModel(); - - /** - * 打印当前状态 - * @return 状态的字符串 - */ - std::string PrintState(); - - /** - * 判断公交车是否到站 - * @return - */ - bool JudgeOnStation(); - -public slots: - /** - * 处理打开配置文件信号的槽函数 - * @param file_name 配置文件名称 - */ - void ReadConfigFileSlot(const QString& file_name); - - /** - * 创建上下车请求的槽函数 - * @param query_type 请求的类型 - * @param node_id 请求站点的id - */ - void AddQuerySlot(int query_type, int node_id) const; - - /** - * 删除上下车请求的槽函数 - * @param query - */ - void DeleteQuerySlot(bus_query_t *query) const; - - /** - * 获得公交车应该前进方向的槽函数 - */ - void GetBusDirectionSlot(); - - /** - * 处理公交车可以处理请求的槽函数 - */ - void HandleQuerySlot(); - -signals: - /** - * 创建轨道链表完成的信号 - * @param node_num 轨道上节点的个数 - */ - void RailsCreated(int node_num); - - /** - * 删除指定请求的信号 - * @param query 需要删除的请求 - */ - void DeleteQuerySignal(bus_query_t *query); - - -private: - /** - * 轨道的总长度 - */ - int total_distance = 10; - - bus_query_t *target_query; - - void SetConnection() const; - - /** - * 获得公交车当前所在的位置 - * @return 公交车当前所在的位置 - */ - int GetBusPosition() const; - - /** - * 读取指定的配置文件 - * @param file_name 提供的配置文件路径 - */ - void ReadConfigFile(const std::string& file_name); + double GetBusPosition(); /** * 给出在指定的方向下,指定的请求于公交车当前位置的距离 @@ -154,56 +56,16 @@ private: */ int GetQueryDistance(bus_query_t *query, int orientation) const; +private: /** - * 在先来先服务策略下应该前进的方向 - * @return 前进的方向 + * 轨道的头节点 */ - int FCFSDirection() const; + rail_node_t *rail_head; /** - * 在先来先服务策略下给出处理的请求 - * @return 需要处理的请求 + * 当前指定处理的请求 */ - bus_query_t *FCFSQuery() const; - - /** - * 获得在SSTF策略下应该处理的请求 - * @return 指向需要处理的请求的指针 - */ - bus_query_t *SSTFGetQuery(); - - /** - * 根据指定的请求获得前进的方向,也就是前往指定的请求最近的方向 - * 在SSTF策略中使用 - * @return 前进的方向 - */ - int SSTFDirection(); - - /** - * 在当前站上可以顺便服务的请求 - * @return 服务的请求指针 - */ - bus_query_t *SSTFBTWQuery() const; - - /** - * 获得在SCAN策略下应该处理的请求 - * @return 指向需要处理的请求的指针 - */ - bus_query_t *SCANGetQuery(); - - /** - * 根据指定的请求获得前进的方向 - * 在SCAN策略中使用 - * @param query 指定完成的请求 - * @return 前进的方向 - */ - int SCANDirection(); - - /** - * 在当前站上可以顺便服务的请求 - * @return 服务的请求指针 - */ - bus_query_t *SCANBTWQuery() const; + bus_query_t *target_query; }; #endif //AUTO_BUS_GUI_BUS_MODEL_H diff --git a/src/busModel.cpp b/src/busModel.cpp index afe77c1..24e020b 100644 --- a/src/busModel.cpp +++ b/src/busModel.cpp @@ -2,154 +2,37 @@ // Created by ricardo on 2022/6/10. // -#include "moc_busModel.cpp" +#include "busModel.h" -BusControllerModel::BusControllerModel() +BusModel::BusModel() { - rail_manager = new RailsModel; - query_manager = new QueryModel; - - // 设置公交车的初始状态 - rail_pos = rail_manager->rails; - distance = 0; + rail_pos = nullptr; direction = BUS_STOP; target_query = nullptr; + rail_head = nullptr; - // 设置初始时间 - bus_time = 0; - - SetConnection(); + bus_timer = new QTimer; } -BusControllerModel::~BusControllerModel() +BusModel::~BusModel() { - delete(rail_manager); - delete(query_manager); + delete bus_timer; } -void BusControllerModel::SetConnection() const +void BusModel::ResetBus(rail_node_t *head) { - QObject::connect(this, &BusControllerModel::DeleteQuerySignal, - this, &BusControllerModel::DeleteQuerySlot); + rail_head = head; + + direction = BUS_STOP; + target_query = nullptr; + rail_pos = rail_head; } -void BusControllerModel::ReadConfigFileSlot(const QString& file_name) +double BusModel::GetBusPosition() { - ReadConfigFile(file_name.toStdString()); -} - -void BusControllerModel::AddQuerySlot(int query_type, int node_id) const -{ - rail_node_t *node_pos = rail_manager->FindNode(node_id); - query_manager->CreateQuery(query_type, node_pos); -} - -void BusControllerModel::DeleteQuerySlot(bus_query_t *query) const -{ - query_manager->DeleteQuery(query); -} - -void BusControllerModel::GetBusDirectionSlot() -{ - switch (chosen_strategy) - { - case BUS_FCFS: - direction = FCFSDirection(); - break; - case BUS_SSTF: - if(target_query == nullptr) - { - target_query = SSTFGetQuery(); - } - direction = SSTFDirection(); - case BUS_SCAN: - if(target_query == nullptr) - { - target_query = SCANGetQuery(); - } - direction = SCANDirection(); - default: - break; - } -} - - -void BusControllerModel::HandleQuerySlot() -{ - bus_query_t *finished_query; - - switch (chosen_strategy) - { - case BUS_FCFS: - finished_query = FCFSQuery(); - while (finished_query != nullptr) - { - emit DeleteQuerySignal(finished_query); - finished_query = FCFSQuery(); - } - break; - case BUS_SSTF: - if(target_query == nullptr) - { - // 这里可能需要处理一下新生成的请求可以处理的情况 - } - else if(target_query->node == rail_pos) - { - // 到达目标站点 - while (target_query != nullptr and target_query->node == rail_pos) - { - emit DeleteQuerySignal(target_query); - target_query = SSTFGetQuery(); - } - } - else - { - // 顺便处理请求 - finished_query = SSTFBTWQuery(); - while (finished_query != nullptr) - { - emit DeleteQuerySignal(finished_query); - finished_query = SSTFBTWQuery(); - } - } - break; - case BUS_SCAN: - if(target_query == nullptr) - { - // 这里可能需要处理一下新生成的请求可以处理的情况 - } - else if(target_query->node == rail_pos) - { - // 到达目标站点 - while (target_query != nullptr and target_query->node == rail_pos) - { - emit DeleteQuerySignal(target_query); - target_query = SCANGetQuery(); - } - } - else - { - // 顺便处理 - finished_query = SCANBTWQuery(); - while (finished_query != nullptr) - { - emit DeleteQuerySignal(finished_query); - finished_query = SCANBTWQuery(); - } - } - } -} - -/* - * 以下函数的实现移植自auto_pilot_bus - * 源程序采用C写成 - */ - -int BusControllerModel::GetBusPosition() const -{ - int result = 0; + double result = 0; rail_node_t *now_pos = rail_pos; - rail_node_t *node = rail_manager->rails; + rail_node_t *node = rail_head; // 先求一下当前所在位置离起始点的距离 do @@ -158,61 +41,27 @@ int BusControllerModel::GetBusPosition() const node = node->next_node; } while (node != now_pos); - if (now_pos == rail_manager->rails) + int remaining_time = bus_timer->remainingTime(); + + if(remaining_time > 0) { - int length = distance; - if(length >= 0) + if(direction == BUS_CLOCK_WISE) { - return length; + double length = now_pos->next_node_distance - (double)remaining_time / 1000.0 * velocity; + result = result + length; } - else + else if(direction == BUS_COUNTER_CLOCK_WISE) { - return result + length; + double length = now_pos->last_node_distance - (double)remaining_time / 1000.0 * velocity; + result = result - length; } } - else if (now_pos == rail_manager->rails->last_node) - { - int length = distance; - if (length == now_pos->next_node_distance) - { - return 0; - } - else - { - return distance + length; - } - } - else - { - return result + distance; - } + + return result; } -bool BusControllerModel::JudgeOnStation() -{ - if(distance == - rail_pos->last_node_distance)//表示逆时针 - { - distance = 0; - rail_pos = rail_pos->last_node;//逆时针往上一个 - return true; - } - else if(distance == rail_pos->next_node_distance)//表示顺时针 - { - distance = 0; - rail_pos = rail_pos->next_node;//顺时针往下一个 - return true; - } - else if(distance == 0)//在站点上原地不动 - { - return true; - } - else - { - return false; - } -} -int BusControllerModel::GetQueryDistance(bus_query_t *query, int orientation) const +int BusModel::GetQueryDistance(bus_query_t *query, int orientation) const { rail_node_t *target_node = query->node; rail_node_t *now_node = rail_pos; @@ -237,463 +86,3 @@ int BusControllerModel::GetQueryDistance(bus_query_t *query, int orientation) co return result; } - -std::string BusControllerModel::PrintState() -{ - int count, flag = 1; - rail_node_t *node; - char target[25], clockwise[25], counterclockwise[25]; - - //遍历轨道链表,将所有站点初始化为0,即:无任何请求; - for (count = 0, node = rail_manager->rails; flag == 1 || node != rail_manager->rails; - node = node->next_node, count++) - { - flag=0; - target[count] = '0'; - clockwise[count] = '0'; - counterclockwise[count] = '0'; - } - - // 在字符串的末尾填0 - target[count] = '\0'; - clockwise[count] = '\0'; - counterclockwise[count] = '\0'; - - bus_query_t *query = query_manager->queries; - int pos; - - while (query != nullptr) - { - pos = query->node->id - 1; - - if(query->type == BUS_CLOCK_WISE) - { - clockwise[pos] = '1'; - } - else if (query->type == BUS_COUNTER_CLOCK_WISE) - { - counterclockwise[pos] = '1'; - } - else - { - target[pos] = '1'; - } - - query = query->next_node; - } - - std::stringstream format; - - // 格式化输出字符串 - format << "Time:" << std::endl - << "BUS:" << std::endl - << "position:" << GetBusPosition() << std::endl - << "target:" << target << std::endl - << "STATION:" << std::endl - << "clockwise:" << clockwise << std::endl - << "counterclockwise:" << counterclockwise << std::endl; - - return format.str(); -} - -void BusControllerModel::ReadConfigFile(const std::string& file_name) -{ - FILE *config_file = nullptr; - - char buffer[30]; - int total_station = 0; - int node_space_length = 0; - - fopen_s(&config_file, file_name.c_str(), "r"); - - // 循环读取文件的每一行 - while (fgets(buffer, sizeof buffer, config_file) != nullptr) - { - char first_char = buffer[0]; - char *p; - - switch (first_char) - { - case '#': - // 如果读取到#什么都不做 - break; - case 'T': - // TOTAL_STATION - p = buffer; - - // 把数字前面的所有字符全部干掉 - while (*p < '0' || *p > '9') - { - p++; - } - - // 讲道理,应该只有两位数,所以就这样处理了 - if (*(p + 1) == '\n' || *(p + 1) == '\0') - { - total_station = *p - 48; - } - else - { - total_station = (*p - 48) * 10 + *(p + 1) - 48; - } - - break; - case 'S': - // STRATEGY - p = buffer; - - // 将=前的字符全部略去 - while (*p != '=') - { - p++; - } - // =也去掉 - p++; - // =和策略之间的空格也去掉 - while (*p == ' ') - { - p++; - } - - if (*p == 'F' && *(p + 1) == 'C') //FCFS - { - chosen_strategy = BUS_FCFS; - } - else if (*p == 'S' && *(p + 1) == 'S') //SSTF - { - chosen_strategy = BUS_SSTF; - } - else if (*p == 'S' && *(p + 1) == 'C') //SCAN - { - chosen_strategy = BUS_SCAN; - } - else - { - // 读取失败 - chosen_strategy = -1; - } - - break; - case 'D': - // DISTANCE - p = buffer; - - // 把数字前面的所有字符全部干掉 - while (*p < '0' || *p > '9') - { - p++; - } - - if (*(p + 1) == '\n' || *(p + 1) == '\0') - { - node_space_length = *p - 48; - } - - break; - default: - continue; - } - } - - // 处理参数去缺省值的情况 - if (node_space_length == 0) - { - node_space_length = 2; - } - if (total_station == 0) - { - total_station = 5; - } - if(chosen_strategy == -1) - { - chosen_strategy = BUS_FCFS; - } - - // 得到轨道的总长度 - total_distance = node_space_length * total_station; - rail_manager->CreateRails(node_space_length, total_station); - - // 发射信号说明创建完毕 - emit RailsCreated(total_station); -} - -int BusControllerModel::FCFSDirection() const -{ - bus_query_t *p = query_manager->queries; - - if(p == nullptr) - { - return BUS_STOP; - } //如果没有请求,公交车停止 - - else - { - int clockwise = 0; - int counterclockwise = 0; //用于顺,逆时针方向所经站台计数 - - /** - * 公交车当前所在位置 - */ - rail_node_t *now_position = rail_pos; - /** - * 公交车应该前进的方向 - */ - rail_node_t *target_position = p->node; - - rail_node_t *pos = now_position; - while (pos != target_position) //顺时针计数 - { - clockwise++; - pos = pos->next_node; - } - - pos = now_position; - while (pos != target_position) //逆时针计数 - { - counterclockwise++; - pos = pos->last_node; - } - - if(clockwise <= counterclockwise) - { - return BUS_CLOCK_WISE; - }//若顺时针距离短(或顺逆相等),公交车顺时针运行 - else - { - return BUS_COUNTER_CLOCK_WISE; - }//若逆时针距离短,公交车逆时针运行 - } -} - -bus_query_t *BusControllerModel::FCFSQuery() const -{ - bus_query_t *result = nullptr; - - if(query_manager->queries != nullptr) - { - if(rail_pos == query_manager->queries->node) - { - result = query_manager->queries; - } - } - - return result; -} - -bus_query_t *BusControllerModel::SSTFGetQuery() -{ - // 当前没有请求 - if(query_manager->queries == nullptr) - { - return nullptr; - } - int length = 9999; - bus_query_t *query = nullptr; - bus_query_t *p = query_manager->queries; - - // 遍历顺时针方向 - // 在两个方向路程相同时选择顺时针方向 - // 所以先遍历顺时针方向 - while (p != nullptr) - { - int temp = GetQueryDistance(p, BUS_CLOCK_WISE); - if(temp < length) - { - length = temp; - query = p; - } - p = p->next_node; - } - - // 遍历逆时针方向 - p = query_manager->queries; - while (p != nullptr) - { - int temp = GetQueryDistance(p, BUS_COUNTER_CLOCK_WISE); - if(temp < length) - { - length = temp; - query = p; - } - p = p->next_node; - } - - return query; -} - -int BusControllerModel::SSTFDirection() -{ - if (target_query == nullptr) - { - return BUS_STOP; - } - - int length = GetQueryDistance(target_query, BUS_CLOCK_WISE); - if(length > total_distance / 2) - { - return BUS_COUNTER_CLOCK_WISE; - } - else if(length == 0) - { - return BUS_STOP; - } - else - { - return BUS_CLOCK_WISE; - } -} - -bus_query_t *BusControllerModel::SSTFBTWQuery() const -{ - bus_query_t *query = query_manager->queries; - bus_query_t *allow_query = nullptr; - rail_node_t *now_node = rail_pos; - - while (query != nullptr) - { - if(query->node == now_node) - { - // 这里是设计上的缺陷,在bus_time显示时间的前一秒,公交车就实际上到达站台了 - if(query->time < bus_time - 1) - { - if(query->type == direction || query->type == BUS_TARGET) - { - allow_query = query; - break; - } - } - } - query = query->next_node; - } - - return allow_query; -} - -bus_query_t *BusControllerModel::SCANGetQuery() -{ - // 当前没有请求 - if(query_manager->queries == nullptr) - { - return nullptr; - } - - if(direction == BUS_STOP) - { - // 在停止的状态下第一次开始选择方向 - int length = 9999; - bus_query_t *query = nullptr; - bus_query_t *p = query_manager->queries; - - // 遍历顺时针方向 - // 在两个方向路程相同时选择顺时针方向 - // 所以先遍历顺时针方向 - while (p != nullptr) - { - int temp = GetQueryDistance(p, BUS_CLOCK_WISE); - if(temp < length) - { - length = temp; - query = p; - } - p = p->next_node; - } - - // 遍历逆时针方向 - p = query_manager->queries; - while (p != nullptr) - { - int temp = GetQueryDistance(p, BUS_COUNTER_CLOCK_WISE); - if(temp < length) - { - length = temp; - query = p; - } - p = p->next_node; - } - - return query; - } - else - { - // 在已经有方向的情况下处理方向 - int length = 9999; - bus_query_t *query = nullptr; - bus_query_t *p = query_manager->queries; - - while (p != nullptr) - { - int temp = GetQueryDistance(p, direction); - if(temp < length) - { - query = p; - length = temp; - } - p = p->next_node; - } - - return query; - } -} - -int BusControllerModel::SCANDirection() -{ - if(target_query == nullptr) - { - return BUS_STOP; - } - - if(direction == BUS_STOP) - { - int length = GetQueryDistance(target_query, BUS_CLOCK_WISE); - if(length > total_distance / 2) - { - return BUS_COUNTER_CLOCK_WISE; - } - else - { - return BUS_CLOCK_WISE; - } - } - else - { - int length = GetQueryDistance(target_query, direction); - if(length > total_distance / 2) - { - if(direction == BUS_CLOCK_WISE) - { - return BUS_COUNTER_CLOCK_WISE; - } - else - { - return BUS_CLOCK_WISE; - } - } - else - { - return direction; - } - } -} - -bus_query_t *BusControllerModel::SCANBTWQuery() const -{ - rail_node_t *now_position = rail_pos; - //获取公交车当前所在站点 - bus_query_t *p = query_manager->queries; - - while(p != nullptr) - { - if(p->node == now_position) - { - if(p->time < bus_time - 1) - { - return p; - } - } - p = p->next_node; - }//遍历请求链表,判断是否有可以顺便处理的请求 - - return nullptr; -} - - diff --git a/src/centralwidget.cpp b/src/centralwidget.cpp index 71d1807..f4ca00c 100644 --- a/src/centralwidget.cpp +++ b/src/centralwidget.cpp @@ -8,15 +8,13 @@ #include "form/ui_CentralWidget.h" -CentralWidget::CentralWidget(QWidget *parent, BusControllerModel *bus_controller) : QWidget(parent), ui(new Ui::CentralWidget) +CentralWidget::CentralWidget(QWidget *parent) : QWidget(parent), ui(new Ui::CentralWidget) { ui->setupUi(this); scene_manager = new SceneManager; ui->main_canva->setScene(scene_manager->scene); - controller = bus_controller; - SetControlConnection(); SetWidgetConnection(); SetupQueryList(); @@ -32,16 +30,7 @@ CentralWidget::~CentralWidget() void CentralWidget::SetControlConnection() { - // 处理轨道重新设置事件 - QObject::connect(controller, &BusControllerModel::RailsCreated, - this, &CentralWidget::SetRailsScene); - // 处理添加请求事件 - QObject::connect(this, &CentralWidget::AppendQuerySignal, - controller, &BusControllerModel::AddQuerySlot); - - QObject::connect(controller, &BusControllerModel::DeleteQuerySignal, - this, &CentralWidget::DeleteQueryItemSlot); } void CentralWidget::SetWidgetConnection() diff --git a/src/header/centralwidget.h b/src/header/centralwidget.h index 67eb989..8414dad 100644 --- a/src/header/centralwidget.h +++ b/src/header/centralwidget.h @@ -27,7 +27,7 @@ class CentralWidget : public QWidget Q_OBJECT public: - explicit CentralWidget(QWidget *parent = nullptr, BusControllerModel *bus_controller = nullptr); + explicit CentralWidget(QWidget *parent = nullptr); ~CentralWidget() override; @@ -75,11 +75,6 @@ private: */ SceneManager *scene_manager; - /** - * 公交车控制器 - */ - BusControllerModel *controller; - /** * 请求列表中的对象 */ diff --git a/src/header/mainwindow.h b/src/header/mainwindow.h index 2836274..d043bdd 100644 --- a/src/header/mainwindow.h +++ b/src/header/mainwindow.h @@ -82,10 +82,6 @@ private: * 中间的显示框架 */ CentralWidget *central_widget; - /** - * 控制类 - */ - BusControllerModel *controller; QThread *worker_thread; diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 4fc5bbd..f926a07 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -11,14 +11,12 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { ui = new Ui::MainWindow; - controller = new BusControllerModel; worker_thread = new QThread; // 开始多线程 - controller->moveToThread(worker_thread); worker_thread->start(); - central_widget = new CentralWidget(nullptr, controller); + central_widget = new CentralWidget(nullptr); ui->setupUi(this); this->setCentralWidget(central_widget); @@ -32,7 +30,6 @@ MainWindow::~MainWindow() delete ui; delete central_widget; - delete controller; delete worker_thread; } @@ -57,8 +54,7 @@ void MainWindow::SetMenuBarConnection() void MainWindow::SetControlConnection() { - QObject::connect(this, &MainWindow::OpenConfigFileSignal, - controller, &BusControllerModel::ReadConfigFileSlot); + } void MainWindow::ReadConfigFileButtonClicked()