/* * @Description: 车位分配算法模块,使用单例模式,接收外部请求并通过调用通信块接口发送反馈 * @Author: yct * @Date: 2020-07-10 11:02:40 * @LastEditTime: 2020-07-10 16:57:14 * @LastEditors: yct */ #include "parkspace_allocator.h" #include "parkspace_allocation_communicator.h" Parkspace_allocator::Parkspace_allocator() { } Parkspace_allocator::~Parkspace_allocator() { parkspace_allocator_uninit(); } //初始化 Error_manager Parkspace_allocator::parkspace_allocator_init(int threads_size) { m_thread_pool.thread_pool_init(threads_size); m_current_status = eParkspace_allocator_normal; return Error_code::SUCCESS; } //反初始化 Error_manager Parkspace_allocator::parkspace_allocator_uninit() { m_thread_pool.thread_pool_uninit(); m_current_status = eParkspace_allocator_unknown; return Error_code::SUCCESS; } //检查执行者的状态, 判断能否处理这条消息, Error_manager Parkspace_allocator::check_executer(Communication_message* p_msg) { if ( p_msg == NULL ) { return Error_manager(Error_code::POINTER_IS_NULL, Error_level::MINOR_ERROR, " POINTER IS NULL "); } Error_manager t_error = SUCCESS; return t_error; } //处理消息的执行函数 Error_manager Parkspace_allocator::execute_msg(Communication_message* p_msg) { if ( p_msg == nullptr ) { return Error_manager(Error_code::POINTER_IS_NULL, Error_level::MINOR_ERROR, " POINTER IS NULL "); } switch ( p_msg->get_message_type() ) { ///车位分配请求消息 case Communication_message::eParkspace_allocation_request_msg: { message::Parkspace_allocation_request_msg request; bool result = request.ParseFromString(p_msg->get_message_buf()); LOG(INFO)<<"allocation request, car license: "<get_message_buf()); LOG(INFO)<<"search request, car license: "<get_message_buf()); LOG(INFO)<<"release request, parkspace id: "<get_message_buf()); LOG(INFO)<<"force update request, parkspace id: "< lck(m_mutex); LOG(INFO) << "分配"; //根据请求的信息反馈分配的车位,并封装发送 message::Parkspace_allocation_response_msg response_msg; message::Base_info t_response_header; t_response_header.set_msg_type(message::Message_type::eParkspace_allocation_response_msg); t_response_header.set_timeout_ms(1000); t_response_header.set_sender(message::Communicator::eParkspace_allocator); t_response_header.set_receiver(message::Communicator::eMain); message::Error_manager t_error; message::Parkspace_info t_allocated_space; //获取当前所有车位状态,分配车位 message::Parkspace_allocation_status_msg t_current_parkspace_status = Parkspace_allocation_communicator::get_instance_references().get_status(); int index = -1; if(t_current_parkspace_status.parkspace_info_size()<=0) { t_error.set_error_code(PARKSPACE_ALLOCATOR_SPACE_EMPTY); t_error.set_error_level(message::Error_level::MAJOR_ERROR); LOG(ERROR) << "无车位"; } else { for (size_t i = 0; i < t_current_parkspace_status.parkspace_info_size(); i++) { // 找到高于车高且空闲车位,则分配 if (t_current_parkspace_status.parkspace_info(i).height() > car_info.car_height() && t_current_parkspace_status.parkspace_info(i).width() > car_info.car_width() && t_current_parkspace_status.parkspace_info(i).parkspace_status() == message::Parkspace_status::eParkspace_empty) { index = i; break; } } if(index<0){ t_error.set_error_code(PARKSPACE_ALLOCATOR_ALLOCATE_FAILED); t_error.set_error_level(message::Error_level::MAJOR_ERROR); t_allocated_space.CopyFrom(t_current_parkspace_status.parkspace_info(0)); LOG(WARNING) << "分配车位失败"; }else{ t_error.set_error_code(SUCCESS); t_error.set_error_level(message::Error_level::NORMAL); message::Parkspace_info t_space_to_lock = t_current_parkspace_status.parkspace_info(index); t_space_to_lock.set_parkspace_status(message::Parkspace_status::eParkspace_occupied); t_space_to_lock.mutable_car_info()->CopyFrom(car_info); t_allocated_space.CopyFrom(t_space_to_lock); // 分配车位后更新车位状态 Parkspace_allocation_communicator::get_instance_references().update_parkspace_status(index, t_space_to_lock); LOG(INFO) << "第"<CopyFrom(t_response_header); response_msg.set_command_id(command_id); response_msg.mutable_error_manager()->CopyFrom(t_error); response_msg.mutable_allocated_space_info()->CopyFrom(t_allocated_space); Communication_message* response=new Communication_message(); response->reset(t_response_header, response_msg.SerializeAsString()); Parkspace_allocation_communicator::get_instance_references().send_response(response); } //查询车位线程函数 void Parkspace_allocator::execute_for_search(message::Car_info car_info, int command_id) { std::lock_guard lck(m_mutex); LOG(INFO) << "查询"; //根据车辆凭证信息查询车辆位置 //!!!!!此处跳过外部处理与调用的过程,直接在内部调用,发送分配结果用于测试,目前一直发布第一个车位 message::Parkspace_search_response_msg response_msg; message::Base_info t_response_header; message::Error_manager t_error; message::Parkspace_info t_car_position; t_response_header.set_msg_type(message::Message_type::eParkspace_search_response_msg); t_response_header.set_timeout_ms(1000); t_response_header.set_sender(message::Communicator::eParkspace_allocator); t_response_header.set_receiver(message::Communicator::eMain); //获取当前所有车位状态,查询车辆位置 message::Parkspace_allocation_status_msg t_current_parkspace_status = Parkspace_allocation_communicator::get_instance_references().get_status(); int index = -1; if(t_current_parkspace_status.parkspace_info_size()<=0) { t_error.set_error_code(PARKSPACE_ALLOCATOR_SPACE_EMPTY); t_error.set_error_level(message::Error_level::MAJOR_ERROR); LOG(ERROR) << "无车位"; } else { for (size_t i = 0; i < t_current_parkspace_status.parkspace_info_size(); i++) { // 找到凭证号/号牌对应车位,记录 if (t_current_parkspace_status.parkspace_info(i).has_car_info() && t_current_parkspace_status.parkspace_info(i).car_info().license() == car_info.license() && t_current_parkspace_status.parkspace_info(i).parkspace_status() == message::Parkspace_status::eParkspace_occupied) { index = i; break; } } if(index<0){ t_error.set_error_code(PARKSPACE_ALLOCATOR_SEARCH_FAILED); t_error.set_error_level(message::Error_level::MAJOR_ERROR); LOG(INFO) << "查询车位失败"; }else{ t_error.set_error_code(SUCCESS); t_error.set_error_level(message::Error_level::NORMAL); message::Parkspace_info t_space_searching = t_current_parkspace_status.parkspace_info(index); t_car_position.CopyFrom(t_space_searching); LOG(INFO) << "车辆"<CopyFrom(t_response_header); response_msg.set_command_id(command_id); response_msg.mutable_error_manager()->CopyFrom(t_error); response_msg.mutable_car_position()->CopyFrom(t_car_position); Communication_message* response=new Communication_message(); response->reset(t_response_header, response_msg.SerializeAsString()); Parkspace_allocation_communicator::get_instance_references().send_response(response); } //释放车位线程函数 void Parkspace_allocator::execute_for_release(message::Parkspace_info space_info, int command_id) { std::lock_guard lck(m_mutex); LOG(INFO) << "释放"; //根据车位信息定位待释放车位位置,车辆凭证号用于校验 //!!!!!此处跳过外部处理与调用的过程,直接在内部调用,发送分配结果用于测试,目前一直发布第一个车位 message::Parkspace_release_response_msg response_msg; message::Base_info t_response_header; message::Error_manager t_error; message::Parkspace_info t_release_space; //获取当前所有车位状态,找到待释放的车位 message::Parkspace_allocation_status_msg t_current_parkspace_status = Parkspace_allocation_communicator::get_instance_references().get_status(); int index = -1; if(t_current_parkspace_status.parkspace_info_size()<=0) { t_error.set_error_code(PARKSPACE_ALLOCATOR_SPACE_EMPTY); t_error.set_error_level(message::Error_level::MAJOR_ERROR); LOG(ERROR) << "无车位"; } else if (!space_info.has_car_info()) { t_error.set_error_code(PARKSPACE_ALLOCATOR_RELEASE_FAILED); t_error.set_error_level(message::Error_level::MAJOR_ERROR); LOG(WARNING) << "传入待释放车位无车辆信息"; } else { for (size_t i = 0; i < t_current_parkspace_status.parkspace_info_size(); i++) { // 找到高于车高且空闲车位,则分配 if (t_current_parkspace_status.parkspace_info(i).parkspace_id() == space_info.parkspace_id() && t_current_parkspace_status.parkspace_info(i).parkspace_status() == message::Parkspace_status::eParkspace_occupied && t_current_parkspace_status.parkspace_info(i).has_car_info() && t_current_parkspace_status.parkspace_info(i).car_info().license() == space_info.car_info().license()) { index = i; break; } } if(index<0){ t_error.set_error_code(PARKSPACE_ALLOCATOR_RELEASE_FAILED); t_error.set_error_level(message::Error_level::MAJOR_ERROR); LOG(WARNING) << "释放车位失败"; }else{ t_error.set_error_code(SUCCESS); t_error.set_error_level(message::Error_level::NORMAL); message::Parkspace_info t_space_to_release = t_current_parkspace_status.parkspace_info(index); t_space_to_release.set_parkspace_status(message::Parkspace_status::eParkspace_empty); t_release_space.CopyFrom(t_space_to_release); // 分配车位后更新车位状态 Parkspace_allocation_communicator::get_instance_references().update_parkspace_status(index, t_space_to_release); LOG(INFO) << "第"<CopyFrom(t_response_header); response_msg.set_command_id(command_id); response_msg.mutable_error_manager()->CopyFrom(t_error); response_msg.mutable_release_space_info()->CopyFrom(t_release_space); Communication_message* response=new Communication_message(); response->reset(t_response_header, response_msg.SerializeAsString()); Parkspace_allocation_communicator::get_instance_references().send_response(response); } //强制更新车位信息线程函数 void Parkspace_allocator::execute_for_force_update(message::Parkspace_info space_info, int command_id) { std::lock_guard lck(m_mutex); LOG(INFO) << "手动"; //根据车位信息定位待释放车位位置,车辆凭证号用于校验 //!!!!!此处跳过外部处理与调用的过程,直接在内部调用,发送分配结果用于测试,目前一直发布第一个车位 message::Parkspace_force_update_response_msg response_msg; message::Base_info t_response_header; message::Error_manager t_error; message::Parkspace_info t_update_space; //获取当前所有车位状态,找到待释放的车位 message::Parkspace_allocation_status_msg t_current_parkspace_status = Parkspace_allocation_communicator::get_instance_references().get_status(); int index = -1; if(t_current_parkspace_status.parkspace_info_size()<=0) { t_error.set_error_code(PARKSPACE_ALLOCATOR_SPACE_EMPTY); t_error.set_error_level(message::Error_level::MAJOR_ERROR); LOG(ERROR) << "无车位"; } else { for (size_t i = 0; i < t_current_parkspace_status.parkspace_info_size(); i++) { // 找到高于车高且空闲车位,则分配 if (t_current_parkspace_status.parkspace_info(i).parkspace_id() == space_info.parkspace_id()) { index = i; break; } } if(index<0){ t_error.set_error_code(PARKSPACE_ALLOCATOR_FORCE_UPDATE_FAILED); t_error.set_error_level(message::Error_level::MAJOR_ERROR); LOG(WARNING) << "手动更新车位失败"; }else{ t_error.set_error_code(SUCCESS); t_error.set_error_level(message::Error_level::NORMAL); t_update_space.CopyFrom(space_info); // 分配车位后更新车位状态 Parkspace_allocation_communicator::get_instance_references().update_parkspace_status(index, t_update_space); LOG(INFO) << "第"<CopyFrom(t_response_header); response_msg.set_command_id(command_id); response_msg.mutable_error_manager()->CopyFrom(t_error); response_msg.mutable_update_space_info()->CopyFrom(t_update_space); Communication_message* response=new Communication_message(); response->reset(t_response_header, response_msg.SerializeAsString()); Parkspace_allocation_communicator::get_instance_references().send_response(response); }