139 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			139 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| // @Time    :   2023-10-28 16:11:17
 | ||
| // @FileName:   MVC.cpp
 | ||
| // @Author  :   423A35C7
 | ||
| // @Software:   VSCode
 | ||
| 
 | ||
| #include "controller.hpp"
 | ||
| #include "MVC.h"
 | ||
| // #ifdef __WIN32__
 | ||
| // 添加"-D_HAS_STD_BYTE=0",的方法不知道为什么没用
 | ||
| // #include <windows.h>
 | ||
| // #else
 | ||
| // #include <unistd.h>
 | ||
| // #define Sleep(a) usleep(a * 1000) // 需要小于一秒
 | ||
| // #endif
 | ||
| // 用_sleep了,虽然会提示不建议使用了,但是用window.h编译出来的会被认为是病毒
 | ||
| 
 | ||
| 
 | ||
| class Simple {
 | ||
| private:
 | ||
|     SingleQueueModel<Customer> model;
 | ||
|     SimpleQueueView<Customer, SingleQueueModel<Customer>> view{model, 5, 5};
 | ||
|     // SimpleQueueView<SingleQueueModel<Customer>> view = SimpleQueueView<SingleQueueModel<Customer>>(model, 5, 5, 20);
 | ||
|     BackgroundView background_view{gate_x, gate_y};
 | ||
|     SingleQueueController<Customer> controller{model, view, speed};
 | ||
|     // int probability_num = DEFAULT_PROBABILITY_NUM;
 | ||
| 
 | ||
| public:
 | ||
|     // main可以认为是外部对Controller的操作
 | ||
|     // num是序号
 | ||
|     Status _main() {
 | ||
|         static int_ num = 0;
 | ||
|         if (rand() % probability_num == 0) { // 0.01的概率
 | ||
|             Customer customer{num++, rand() % (max_money) + 1};
 | ||
|             this->model.push(customer);
 | ||
|         }
 | ||
|         return OK;
 | ||
|     }
 | ||
| 
 | ||
|     // 可以认为此操作不应出错
 | ||
|     void refresh() {
 | ||
|         this->controller.refresh();
 | ||
|         this->background_view.refresh();
 | ||
|         this->view.refresh();
 | ||
|         _sleep(sleep_time);
 | ||
|     }
 | ||
| };
 | ||
| 
 | ||
| class Multi {
 | ||
|     using one_model = SingleQueueModel<Customer>;
 | ||
|     using one_view = SimpleQueueView<Customer, SingleQueueModel<Customer>>;
 | ||
|     using one_controller = SingleQueueController<Customer>;
 | ||
| 
 | ||
|     std::vector<std::shared_ptr<one_model>> models;
 | ||
|     std::vector<std::shared_ptr<one_view>> views;
 | ||
|     BackgroundView background_view{gate_x, gate_y};
 | ||
|     std::vector<std::shared_ptr<one_controller>> controllers;
 | ||
|     DriftingView<Customer> drifting_view;
 | ||
|     DriftingController<Customer> drift_controller;
 | ||
|     int len = 0;
 | ||
|     int probability_num = DEFAULT_PROBABILITY_NUM;
 | ||
|     int speed = DEFAULT_SPEED;
 | ||
|     int max_money = MAX_MONEY;
 | ||
|     double walk_speed = DEFAULT_WALK_SPEED;
 | ||
| 
 | ||
| public:
 | ||
|     Multi(int len, int probability_num = DEFAULT_PROBABILITY_NUM, int speed = DEFAULT_SPEED, int max_money = MAX_MONEY, double walk_speed = DEFAULT_WALK_SPEED) : len(len), probability_num(probability_num), speed(speed), max_money(max_money), walk_speed(walk_speed), drift_controller(controllers, drifting_view) {
 | ||
|         if (len < 1)
 | ||
|             throw std::bad_array_new_length(); // 异常这样用好像不太对
 | ||
|         for (int i = 0; i < len; i++) {
 | ||
|             // one_model _model {};
 | ||
|             // one_view _view(_model, 5 + i * 20, 5);
 | ||
|             // one_controller _controller(_model, _view); // 这里的引用很奇怪,可能是自己创建的类在_model离开作用域后继续引用它无法保证它不被修改,也就是说它引用的可能还是原来的变量名,但原来的变量名被更改了,但vector里可以继续正确引用
 | ||
|             // one_view _view(this->models.back()); // 这样也无法正确引用,看来还是得用指针
 | ||
|             // one_controller _controller(this->models.back(), this->views.back());
 | ||
| 
 | ||
|             // vector内对一个对象可能有多个引用,所以可能使用了unique_ptr就无法放置在vector里
 | ||
|             std::shared_ptr<one_model> _model(new one_model());
 | ||
|             std::shared_ptr<one_view> _view(new one_view(*_model, base_x, base_y + i * sep));
 | ||
|             std::shared_ptr<one_controller> _controller(new one_controller(*_model, *_view, this->speed));
 | ||
|             this->models.push_back(_model);
 | ||
|             this->views.push_back(_view);
 | ||
|             this->controllers.push_back(_controller);
 | ||
|         }
 | ||
|     }
 | ||
| 
 | ||
|     // 如果有多个最短的,最左边的优先
 | ||
|     int get_shortest_queue() {
 | ||
|         int min_value = int_MAX;
 | ||
|         int argmin = 0;
 | ||
|         for (int i = 0; i < this->len; i++) {
 | ||
|             if (this->models[i]->get_length() < min_value) {
 | ||
|                 min_value = this->models[i]->get_length();
 | ||
|                 argmin = i;
 | ||
|             }
 | ||
|         }
 | ||
|         return argmin;
 | ||
|     }
 | ||
| 
 | ||
|     Status _main() {
 | ||
|         static int_ num = 0;
 | ||
|         this->drifting_view.main();
 | ||
|         if (rand() % this->probability_num == 0) { // 0.01的概率
 | ||
|             Customer customer{num++, rand() % (this->max_money) + 1};
 | ||
|             // this->models[this->get_shortest_queue()]->push(customer);
 | ||
|             this->drift_controller.push(
 | ||
|                 customer,
 | ||
|                 this->get_shortest_queue(),
 | ||
|                 std::make_pair(gate_x, gate_y),
 | ||
|                 this->walk_speed);
 | ||
|         }
 | ||
|         return OK;
 | ||
|     }
 | ||
| 
 | ||
|     void refresh() {
 | ||
|         for (auto _controller : this->controllers) {
 | ||
|             _controller->refresh();
 | ||
|         }
 | ||
|         this->background_view.refresh();
 | ||
|         for (auto _view : this->views) {
 | ||
|             _view->refresh();
 | ||
|         }
 | ||
|         this->drifting_view.refresh();
 | ||
|         _sleep(sleep_time);
 | ||
|     }
 | ||
| };
 | ||
| 
 | ||
| Status main_simple() {
 | ||
|     Simple simple;
 | ||
|     std::function<Status()> _main = std::bind(&Simple::_main, &simple);
 | ||
|     std::function<void()> refresh = std::bind(&Simple::refresh, &simple);
 | ||
|     return mainloop(_main, refresh, total_time);
 | ||
| }
 | ||
| 
 | ||
| Status main_multi() {
 | ||
|     Multi multi(window_num, probability_num, speed, max_money);
 | ||
|     std::function<Status()> _main = std::bind(&Multi::_main, &multi);
 | ||
|     std::function<void()> refresh = std::bind(&Multi::refresh, &multi);
 | ||
|     return mainloop(_main, refresh, total_time);
 | ||
| } |