用于存放学校的作业便于复习。
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

92 lines
3.1 KiB

  1. // @Time : 2023-10-24 11:17:40
  2. // @FileName: controller.h
  3. // @Author : 423A35C7
  4. // @Software: VSCode
  5. #ifndef _CONTROLLER
  6. #define _CONTROLLER
  7. #include "constants.h"
  8. // #include "model.hpp" // view里已经依赖model了
  9. #include "view.hpp"
  10. class Controller {
  11. // virtual Status main() = 0;
  12. };
  13. template <typename T>
  14. class DriftingController;
  15. template <typename T>
  16. class SingleQueueController : Controller {
  17. friend class DriftingController<T>;
  18. private:
  19. int_ consumed_time = 0;
  20. int speed = DEFAULT_SPEED;
  21. SingleQueueModel<T> &model;
  22. // BackgroundView background_view;
  23. QueueView<T, SingleQueueModel<T>> &view;
  24. // void (View:: a)() = background_view.init;
  25. // 捕获了this的lambda函数好像不能转化为void函数指针
  26. // initializer_list<void ()> temp {
  27. // [&](this){background_view.init();},
  28. // [&](this){view.refresh(model);}
  29. // };
  30. public:
  31. // refresh可以认为是controller内部自己进行更新
  32. void refresh() {
  33. if (this->model.get_length() <= 0) {
  34. this->consumed_time = 0;
  35. } else {
  36. this->consumed_time++;
  37. if (this->consumed_time * this->speed >= this->model.top().cash) {
  38. this->model.shift();
  39. this->consumed_time = 0;
  40. }
  41. }
  42. }
  43. SingleQueueController(SingleQueueModel<T> &model, QueueView<T, SingleQueueModel<T>> &view, int speed = DEFAULT_SPEED) : model(model), view(view), speed(speed) {
  44. this->refresh();
  45. }
  46. };
  47. template <typename T>
  48. class DriftingController : Controller {
  49. private:
  50. std::vector<std::shared_ptr<SingleQueueController<T>>> &single_queue_controllers;
  51. DriftingView<T> &drifting_view;
  52. double walk_speed = DEFAULT_WALK_SPEED;
  53. public:
  54. void push(T data, int target, coordinate current_pos = std::make_pair(DEFAULT_GATE_X, DEFAULT_GATE_Y), double walk_speed = DEFAULT_WALK_SPEED) {
  55. auto &view = this->single_queue_controllers[target]->view;
  56. coordinate target_pos = view.get_last_pos();
  57. int_ remained_time = (int_)(sqrt(pow(target_pos.first - current_pos.first, 2) + pow(target_pos.second - current_pos.second, 2)) / walk_speed);
  58. // DriftingView<Customer>::Node temp ;
  59. // 如果形参是引用的话会出现如下问题:
  60. // error: cannot bind non-const lvalue reference of type 'DriftingView<Customer>::Node&' to an rvalue of type 'DriftingView<Customer>::Node'
  61. this->drifting_view.push({
  62. data,
  63. view,
  64. remained_time,
  65. current_pos
  66. });
  67. }
  68. DriftingController(
  69. std::vector<std::shared_ptr<SingleQueueController<T>>> &single_queue_controllers,
  70. DriftingView<T> &drifting_view
  71. ) :
  72. single_queue_controllers(single_queue_controllers),
  73. drifting_view(drifting_view) {}
  74. };
  75. Status mainloop(std::function<Status()> main, std::function<void()> refresh, int_ total_time = DEFAULT_TOTAL_TIME) {
  76. Status temp;
  77. for (int i = 0; i < total_time; i++) {
  78. if ((temp = main()) != OK)
  79. return temp;
  80. refresh();
  81. }
  82. return OK;
  83. }
  84. #endif