// @Time : 2023-10-24 11:17:40
|
|
// @FileName: controller.h
|
|
// @Author : 423A35C7
|
|
// @Software: VSCode
|
|
|
|
#ifndef _CONTROLLER
|
|
#define _CONTROLLER
|
|
|
|
#include "constants.h"
|
|
// #include "model.hpp" // view里已经依赖model了
|
|
#include "view.hpp"
|
|
|
|
class Controller {
|
|
// virtual Status main() = 0;
|
|
};
|
|
|
|
template <typename T>
|
|
class DriftingController;
|
|
|
|
template <typename T>
|
|
class SingleQueueController : Controller {
|
|
friend class DriftingController<T>;
|
|
private:
|
|
int_ consumed_time = 0;
|
|
int speed = DEFAULT_SPEED;
|
|
|
|
SingleQueueModel<T> &model;
|
|
// BackgroundView background_view;
|
|
QueueView<T, SingleQueueModel<T>> &view;
|
|
// void (View:: a)() = background_view.init;
|
|
// 捕获了this的lambda函数好像不能转化为void函数指针
|
|
// initializer_list<void ()> temp {
|
|
// [&](this){background_view.init();},
|
|
// [&](this){view.refresh(model);}
|
|
// };
|
|
public:
|
|
// refresh可以认为是controller内部自己进行更新
|
|
void refresh() {
|
|
if (this->model.get_length() <= 0) {
|
|
this->consumed_time = 0;
|
|
} else {
|
|
this->consumed_time++;
|
|
if (this->consumed_time * this->speed >= this->model.top().cash) {
|
|
this->model.shift();
|
|
this->consumed_time = 0;
|
|
}
|
|
}
|
|
}
|
|
SingleQueueController(SingleQueueModel<T> &model, QueueView<T, SingleQueueModel<T>> &view, int speed = DEFAULT_SPEED) : model(model), view(view), speed(speed) {
|
|
this->refresh();
|
|
}
|
|
};
|
|
|
|
template <typename T>
|
|
class DriftingController : Controller {
|
|
private:
|
|
std::vector<std::shared_ptr<SingleQueueController<T>>> &single_queue_controllers;
|
|
DriftingView<T> &drifting_view;
|
|
double walk_speed = DEFAULT_WALK_SPEED;
|
|
public:
|
|
void push(T data, int target, coordinate current_pos = std::make_pair(DEFAULT_GATE_X, DEFAULT_GATE_Y), double walk_speed = DEFAULT_WALK_SPEED) {
|
|
auto &view = this->single_queue_controllers[target]->view;
|
|
coordinate target_pos = view.get_last_pos();
|
|
int_ remained_time = (int_)(sqrt(pow(target_pos.first - current_pos.first, 2) + pow(target_pos.second - current_pos.second, 2)) / walk_speed);
|
|
// DriftingView<Customer>::Node temp ;
|
|
// 如果形参是引用的话会出现如下问题:
|
|
// error: cannot bind non-const lvalue reference of type 'DriftingView<Customer>::Node&' to an rvalue of type 'DriftingView<Customer>::Node'
|
|
this->drifting_view.push({
|
|
data,
|
|
view,
|
|
remained_time,
|
|
current_pos
|
|
});
|
|
}
|
|
DriftingController(
|
|
std::vector<std::shared_ptr<SingleQueueController<T>>> &single_queue_controllers,
|
|
DriftingView<T> &drifting_view
|
|
) :
|
|
single_queue_controllers(single_queue_controllers),
|
|
drifting_view(drifting_view) {}
|
|
};
|
|
|
|
Status mainloop(std::function<Status()> main, std::function<void()> refresh, int_ total_time = DEFAULT_TOTAL_TIME) {
|
|
Status temp;
|
|
for (int i = 0; i < total_time; i++) {
|
|
if ((temp = main()) != OK)
|
|
return temp;
|
|
refresh();
|
|
}
|
|
return OK;
|
|
}
|
|
|
|
#endif
|