删除了冗长的公交车控制类

设计了单独的公交车类
This commit is contained in:
jackfiled 2022-06-27 13:18:50 +08:00
parent 50aa9d9c6a
commit ce7986b5a6
6 changed files with 51 additions and 824 deletions

View File

@ -14,137 +14,39 @@
#include "sstream" #include "sstream"
#include "QObject" #include "QObject"
#include "QDebug" #include "QDebug"
#include "QTimer"
/** /**
* QObject *
*/ */
class BusControllerModel : public QObject class BusModel
{ {
Q_OBJECT
public: public:
/**
*
*/
rail_node_t *rail_pos; rail_node_t *rail_pos;
/** /**
* *
*/ */
int distance; const int velocity = 1;
/** /**
* *
*/ */
int direction; int direction;
/** QTimer *bus_timer;
*
*/ explicit BusModel();
int bus_time;
~BusModel();
/** /**
* *
* @param head
*/ */
RailsModel *rail_manager; void ResetBus(rail_node_t *head);
/** double GetBusPosition();
*
*/
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);
/** /**
* *
@ -154,56 +56,16 @@ private:
*/ */
int GetQueryDistance(bus_query_t *query, int orientation) const; 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; bus_query_t *target_query;
/**
* 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;
}; };
#endif //AUTO_BUS_GUI_BUS_MODEL_H #endif //AUTO_BUS_GUI_BUS_MODEL_H

View File

@ -2,154 +2,37 @@
// Created by ricardo on 2022/6/10. // Created by ricardo on 2022/6/10.
// //
#include "moc_busModel.cpp" #include "busModel.h"
BusControllerModel::BusControllerModel() BusModel::BusModel()
{ {
rail_manager = new RailsModel; rail_pos = nullptr;
query_manager = new QueryModel;
// 设置公交车的初始状态
rail_pos = rail_manager->rails;
distance = 0;
direction = BUS_STOP; direction = BUS_STOP;
target_query = nullptr; target_query = nullptr;
rail_head = nullptr;
// 设置初始时间 bus_timer = new QTimer;
bus_time = 0;
SetConnection();
} }
BusControllerModel::~BusControllerModel() BusModel::~BusModel()
{ {
delete(rail_manager); delete bus_timer;
delete(query_manager);
} }
void BusControllerModel::SetConnection() const void BusModel::ResetBus(rail_node_t *head)
{ {
QObject::connect(this, &BusControllerModel::DeleteQuerySignal, rail_head = head;
this, &BusControllerModel::DeleteQuerySlot);
direction = BUS_STOP;
target_query = nullptr;
rail_pos = rail_head;
} }
void BusControllerModel::ReadConfigFileSlot(const QString& file_name) double BusModel::GetBusPosition()
{ {
ReadConfigFile(file_name.toStdString()); double result = 0;
}
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;
rail_node_t *now_pos = rail_pos; rail_node_t *now_pos = rail_pos;
rail_node_t *node = rail_manager->rails; rail_node_t *node = rail_head;
// 先求一下当前所在位置离起始点的距离 // 先求一下当前所在位置离起始点的距离
do do
@ -158,61 +41,27 @@ int BusControllerModel::GetBusPosition() const
node = node->next_node; node = node->next_node;
} while (node != now_pos); } while (node != now_pos);
if (now_pos == rail_manager->rails) int remaining_time = bus_timer->remainingTime();
if(remaining_time > 0)
{ {
int length = distance; if(direction == BUS_CLOCK_WISE)
if(length >= 0)
{ {
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)
{ return result;
int length = distance;
if (length == now_pos->next_node_distance)
{
return 0;
}
else
{
return distance + length;
}
}
else
{
return result + distance;
}
} }
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 *target_node = query->node;
rail_node_t *now_node = rail_pos; rail_node_t *now_node = rail_pos;
@ -237,463 +86,3 @@ int BusControllerModel::GetQueryDistance(bus_query_t *query, int orientation) co
return result; 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;
}

View File

@ -8,15 +8,13 @@
#include "form/ui_CentralWidget.h" #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); ui->setupUi(this);
scene_manager = new SceneManager; scene_manager = new SceneManager;
ui->main_canva->setScene(scene_manager->scene); ui->main_canva->setScene(scene_manager->scene);
controller = bus_controller;
SetControlConnection(); SetControlConnection();
SetWidgetConnection(); SetWidgetConnection();
SetupQueryList(); SetupQueryList();
@ -32,16 +30,7 @@ CentralWidget::~CentralWidget()
void CentralWidget::SetControlConnection() 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() void CentralWidget::SetWidgetConnection()

View File

@ -27,7 +27,7 @@ class CentralWidget : public QWidget
Q_OBJECT Q_OBJECT
public: public:
explicit CentralWidget(QWidget *parent = nullptr, BusControllerModel *bus_controller = nullptr); explicit CentralWidget(QWidget *parent = nullptr);
~CentralWidget() override; ~CentralWidget() override;
@ -75,11 +75,6 @@ private:
*/ */
SceneManager *scene_manager; SceneManager *scene_manager;
/**
*
*/
BusControllerModel *controller;
/** /**
* *
*/ */

View File

@ -82,10 +82,6 @@ private:
* *
*/ */
CentralWidget *central_widget; CentralWidget *central_widget;
/**
*
*/
BusControllerModel *controller;
QThread *worker_thread; QThread *worker_thread;

View File

@ -11,14 +11,12 @@
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
{ {
ui = new Ui::MainWindow; ui = new Ui::MainWindow;
controller = new BusControllerModel;
worker_thread = new QThread; worker_thread = new QThread;
// 开始多线程 // 开始多线程
controller->moveToThread(worker_thread);
worker_thread->start(); worker_thread->start();
central_widget = new CentralWidget(nullptr, controller); central_widget = new CentralWidget(nullptr);
ui->setupUi(this); ui->setupUi(this);
this->setCentralWidget(central_widget); this->setCentralWidget(central_widget);
@ -32,7 +30,6 @@ MainWindow::~MainWindow()
delete ui; delete ui;
delete central_widget; delete central_widget;
delete controller;
delete worker_thread; delete worker_thread;
} }
@ -57,8 +54,7 @@ void MainWindow::SetMenuBarConnection()
void MainWindow::SetControlConnection() void MainWindow::SetControlConnection()
{ {
QObject::connect(this, &MainWindow::OpenConfigFileSignal,
controller, &BusControllerModel::ReadConfigFileSlot);
} }
void MainWindow::ReadConfigFileButtonClicked() void MainWindow::ReadConfigFileButtonClicked()