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

设计了单独的公交车类
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 "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

View File

@ -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;
}

View File

@ -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()

View File

@ -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;
/**
*
*/

View File

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

View File

@ -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()