#include "event.h" #include #include "ant.h" #include "area.h" #include "card.h" #include "common_tool.h" #include "websocket/constdef.h" #include "db/db_api/CDBSingletonDefine.h" #include "tool_time.h" #include "ant.h" #include "db/db_tool.h" #include "mine.h" #include "module_service/module_traffic_light_manager.h" uint64_t ya_event::get_list_id() { return m_id; } struct Event { OBJECT_TYPE m_oid; Event(OBJECT_TYPE oid) :m_oid(oid) {} void handle_alarm_event(EVENT_TYPE et,uint64_t id,double limit_value,double cur_value,bool f,EVENT_DIS_TYPE edt,const std::string &desc); virtual std::shared_ptr on_message(EVENT_TYPE et,uint64_t id,bool f)=0; std::shared_ptr create_event(const std::string&obj_id,EVENT_TYPE ev_type); virtual ~Event(){} }; struct mine_event:Event { mine_event() :Event(OT_MORE_CARD) {} virtual std::shared_ptr on_message(EVENT_TYPE et,uint64_t id,bool f); }; struct area_event:Event { area_event() :Event(OT_AREA) {} virtual std::shared_ptr on_message(EVENT_TYPE et,uint64_t id,bool f); }; struct device_reader_event:Event { device_reader_event() :Event(OT_DEVICE_READER) {} virtual std::shared_ptr on_message(EVENT_TYPE et,uint64_t id,bool f); }; struct card_event:Event { card_event() :Event(OT_CARD) {} virtual std::shared_ptr on_message(EVENT_TYPE et,uint64_t id,bool f); }; struct light_event:Event{ light_event() : Event(OT_DEVICE_LIGHT) {} virtual std::shared_ptr on_message(EVENT_TYPE et, uint64_t id, bool f); }; static event_tool et; event_tool * event_tool::instance() { return &et; } /* * @brief * 告警分类:一人带多卡告警、区域告警、基站告警、卡告警、红绿灯告警 * @param * 无 * @return * 无 * @note * @warning * @bug * * */ void event_tool::make_event_object() { m_map[OT_MORE_CARD] = std::make_shared(); m_map[OT_AREA] = std::make_shared(); m_map[OT_DEVICE_READER] = std::make_shared(); m_map[OT_CARD] = std::make_shared(); m_map[OT_DEVICE_LIGHT] = std::make_shared(); } void event_tool::handle_event(OBJECT_TYPE ot, EVENT_TYPE et, uint64_t id, double limit_value, double cur_value, bool f, EVENT_DIS_TYPE edt/*=DT_COMMON*/, const std::string &desc/*=""*/) { m_map[ot]->handle_alarm_event(et,id,limit_value,cur_value,f,edt,desc); } std::shared_ptr Event::create_event(const std::string&obj_id,EVENT_TYPE ev_type) { auto ev_ptr = std::make_shared(tool_time::now_to_us()); ev_ptr->m_ev_type = ev_type; ev_ptr->m_obj_type=m_oid; ev_ptr->m_obj_id = obj_id; return ev_ptr; } /* * @breif 构建开始或者取消告警事件, * 告警事件入口,生成事件对象,保存在内存中。 * end_time为零表示开始 * start_time为零表示结束 * 事件的唯一根据id判断。 * @param EVENT_TYPE et 事件设备类型 * @param uint64_t id * @param double limit_value 阈值 * @param double cur_value 当前值 * @param bool f 告警标志,true表示开始告警,false表示取消告警 * @param EVENT_DIS_TYPE edt * @param const std::string& desc 描述 * @return 无 * @note * @bug * @warning * */ void Event::handle_alarm_event(EVENT_TYPE et, uint64_t id, double limit_value, double cur_value, bool f, EVENT_DIS_TYPE edt, const std::string &desc) { std::shared_ptr ev_ptr = nullptr; uint64_t eid = event_list::to_list_id(et, m_oid, id, edt); //eid是告警的唯一id,如果存在,查找eid来找到的已经存在的事件 auto event_ptr = event_list::instance()->get(eid); if(f) { if(event_ptr) { //已经存在告警 event_ptr->m_cur_value = cur_value; if(et!=ET_READER_ERROR) event_ptr->m_is_sent=false; } else { uint64_t _id = id; //log_info("Create_Event:desc[%s],id:%d,et:%d",desc.c_str(),id,et); if((et == ET_UWB_MORE_CARD||et == ET_VEHICLE_REAR_END) && !desc.empty())//防追尾告警特殊处理 { std::string cardid = desc.substr(0, desc.find_first_of('&')); _id = tool_other::card_id_to_u64(cardid); } ev_ptr = on_message(et,_id,f); if(ev_ptr){ ev_ptr->m_cur_value = cur_value; ev_ptr->m_limit_value = limit_value; ev_ptr->m_desc = desc; ev_ptr->m_id = eid; ev_ptr->m_dis_type = edt; if(et == ET_VEHICLE_REAR_END|| et == ET_UWB_MORE_CARD)//一人多卡特殊处理 { ev_ptr->m_obj_id = desc; //ev_ptr->m_cur_time=std::chrono::system_clock::time_point(std::chrono::milliseconds((time_t)limit_value * 1000)); } //保存告警信息 event_list::instance()->add(eid, ev_ptr); } } } else { if(event_ptr && !event_ptr->is_end()) { //取消告警 event_ptr->m_cur_time = std::chrono::system_clock::now(); event_ptr->m_status = ES_END; event_ptr->m_cur_value = cur_value; event_ptr->m_desc = desc; event_ptr->m_is_sent = false; ev_ptr=event_ptr; } } if(ev_ptr) { //event_list::save_event(ev_ptr); //基站失联告警:人员和车辆都要有 if(ev_ptr->m_ev_type == 6){ event_list::save_event(ev_ptr); event_list::save_event_v(ev_ptr); }else if(ev_ptr->m_ev_type == 8 || ev_ptr->m_ev_type == 21 || ev_ptr->m_ev_type == 41){ // 红绿灯失联、人车防碰撞、超速告警这三类保存到his_event_data_v表中 event_list::save_event_v(ev_ptr); }else{ //其他的人员相关报警保存到his_event_data表中 event_list::save_event(ev_ptr); } } } std::shared_ptr mine_event::on_message(EVENT_TYPE et,uint64_t id,bool f) { std::shared_ptr event_ptr=nullptr; if(f){ event_ptr=create_event(std::to_string(id), et); auto card_ptr = card_list::instance()->get(id); if(!card_ptr) { event_ptr->m_map_id=5; return event_ptr; } if(auto site_ptr=card_ptr->get_area_tool()->m_site) { event_ptr->m_area_id = site_ptr->m_area_id; event_ptr->m_map_id = site_ptr->m_map_id; } } return event_ptr; } std::shared_ptr area_event::on_message(EVENT_TYPE et,uint64_t id,bool f) { std::shared_ptr event_ptr=nullptr; if(f) { auto area_ptr = area_list::instance()->get(id); if(!area_ptr) { log_error("create_event .can not find area ..%d",id); return event_ptr; } event_ptr=create_event(std::to_string(id), et); event_ptr->m_area_id = id; event_ptr->m_map_id = area_ptr->mapid(); } return event_ptr; } std::shared_ptr device_reader_event::on_message(EVENT_TYPE et,uint64_t id,bool f) { std::shared_ptr event_ptr=nullptr; if(f) { auto site_ptr = sit_list::instance()->get(id); if(!site_ptr) { log_info("create_event.can not find site :%d",id); return event_ptr; } if(site_ptr->m_special){ //log_info() return event_ptr; } event_ptr=create_event(std::to_string(id),et); event_ptr->m_area_id = site_ptr->m_area_id; event_ptr->m_map_id = site_ptr->m_map_id; event_ptr->x = site_ptr->x; event_ptr->y = site_ptr->y; } return event_ptr; } std::shared_ptr card_event::on_message(EVENT_TYPE et,uint64_t id,bool f) { std::shared_ptr event_ptr=nullptr; if(f) { auto card_ptr = card_list::instance()->get(id); std::string card_id = tool_other::get_string_cardid(id); if(!card_ptr) { log_error("Create_event.can not find card:%s",card_id.c_str()); return event_ptr; } event_ptr=create_event(card_id,et); event_ptr->x = card_ptr->x; event_ptr->y = card_ptr->y; //event_ptr->m_is_display = card_ptr->m_display; if(const auto area_ptr=card_ptr->get_area_tool()) { const auto area_info = area_ptr->m_area_info; if(!area_info.empty()){ const auto x=area_info.cbegin()->second; event_ptr->landmark_id=std::get<1>(x); event_ptr->landmark_dir=std::get<2>(x); event_ptr->landmark_dis=std::get<3>(x); } if(const auto site_ptr=area_ptr->m_site){ event_ptr->m_area_id = site_ptr->m_area_id; event_ptr->m_map_id = site_ptr->m_map_id; } } } return event_ptr; } std::shared_ptr light_event::on_message(EVENT_TYPE et, uint64_t id, bool f) { std::shared_ptr event_ptr = nullptr; if(f){ auto light_ptr = traffic_light_manager::instance()->get(id); if(!light_ptr) { log_info("create_event.can not find light :%d",id); return event_ptr; } event_ptr = create_event(std::to_string(id), et); event_ptr->m_area_id = light_ptr->m_area_id; event_ptr->m_map_id = light_ptr->m_map_id; event_ptr->x = light_ptr->x; event_ptr->y = light_ptr->y; } return event_ptr; } std::shared_ptr event_list::get_event_card(uint32_t card_id, int card_type, EVENT_TYPE ev_type,EVENT_DIS_TYPE edt) { uint64_t id64 = tool_other::type_id_to_u64(card_type, card_id); return base::get(to_list_id(ev_type, OT_CARD, id64,edt)); } void event_list::save_event(const std::shared_ptr &ev_ptr) { char sql[LENGTH_SQL] = {0}; std::string _time = tool_time::to_str_ex(ev_ptr->m_cur_time); sprintf(sql, "INSERT IGNORE INTO his_event_data(event_id,id, stat, event_type_id, obj_type_id, obj_id, dis_type,\ map_id, area_id, limit_value, cur_value, x, y, cur_time, description,landmark_id,landmark_dir,landmark_dist) \ VALUES(%ld,%ld, %d, %d, %d, %s, %d, %d, %d, %.2f, %.2f, %f, %f, '%s', '%s',%d,%d,%.2f);", ev_ptr->m_ev_id,ev_ptr->m_id,ev_ptr->m_status, ev_ptr->m_ev_type, ev_ptr->m_obj_type, ev_ptr->m_obj_id.c_str(),ev_ptr->m_dis_type, ev_ptr->m_map_id, ev_ptr->m_area_id, ev_ptr->m_limit_value, ev_ptr->m_cur_value, ev_ptr->x, ev_ptr->y, _time.c_str(), ev_ptr->m_desc.c_str(),ev_ptr->landmark_id,ev_ptr->landmark_dir,ev_ptr->landmark_dis); db_tool::PushAsync(sql); } /* * @brief * 保存告警事件 * @param * const std::shared_ptr& ev_ptr 告警对象 * int type 告警开始结束标志,开始为0,结束为1 * @return * 无 * @note * @warning * @bug * */ void event_list::save_event_v(const std::shared_ptr &ev_ptr) { char sql[LENGTH_SQL] = {0}; std::string _time = tool_time::to_str_ex(ev_ptr->m_cur_time); switch(ev_ptr->m_status){ case 0: sprintf(sql, "INSERT IGNORE INTO his_event_data_v(id, event_type_id, obj_id, x, y ,start_time) VALUES(%ld, %d, '%s', %.2f, %.2f, '%s');", ev_ptr->m_ev_id, ev_ptr->m_ev_type, ev_ptr->m_obj_id.c_str(), ev_ptr->x, ev_ptr->y, _time.c_str()); break; case 100: sprintf(sql, "update his_event_data_v set end_time='%s' where id=%ld;", _time.c_str(), ev_ptr->m_ev_id); break; default: break; } db_tool::PushAsync(sql); } void event_list::load_his_data_from_db(bool init /*=true*/) { static std::time_t s_last_time=0; if(!init){ std::time_t t=time(0); if(t-s_last_time<15)return; s_last_time=t; } std::unordered_map> map; std::string sql("SELECT event_id, id,stat,event_type_id,obj_type_id,obj_id,dis_type,map_id,area_id,\ limit_value,cur_value,x,y, cur_time FROM his_event_data \ WHERE event_id IN (SELECT MAX(event_id) FROM his_event_data \ WHERE cur_time > (CASE obj_type_id \ WHEN 1 THEN DATE_SUB(NOW(),INTERVAL 2 DAY) \ WHEN 4 THEN DATE_SUB(NOW(),INTERVAL 1 MONTH)\ WHEN 9 THEN DATE_SUB(NOW(),INTERVAL 2 DAY) \ WHEN 10 THEN DATE_SUB(NOW(),INTERVAL 2 DAY) \ END) \ AND cur_time < NOW()\ GROUP BY event_type_id, obj_id,dis_type) \ AND event_id NOT IN ( SELECT event_id FROM his_event_data WHERE stat=100)\ AND event_type_id NOT IN (21,22,31,36) and obj_type_id !=2;"); if(!init) sql="SELECT event_id, id,stat,event_type_id,obj_type_id,obj_id,dis_type,map_id,area_id,limit_value,cur_value,x,y, cur_time FROM his_event_data WHERE cur_time > date_sub(NOW(),interval 20 second) and source=1 order by stat;"; std::string Error; YADB::CDBResultSet DBRes; sDBConnPool.Query(sql.c_str(),DBRes,Error); if(!Error.empty()) log_error("初始化事件列表 Error,%s",Error.c_str()); uint64_t nCount = DBRes.GetRecordCount( Error ); if (nCount > 0) { log_info( "init_event_list. The record count=%ld\n", nCount ); while ( DBRes.GetNextRecod(Error) ) { long long int event_id = 0; DBRes.GetField( "event_id",event_id, Error ); long long int id = 0; DBRes.GetField( "id",id, Error ); int event_type_id = 0; DBRes.GetField( "event_type_id",event_type_id, Error ); int obj_type_id = 0; DBRes.GetField( "obj_type_id",obj_type_id, Error ); std::string obj_id = ""; DBRes.GetField( "obj_id",obj_id, Error ); int dis_type = 0; DBRes.GetField( "dis_type",dis_type, Error ); int map_id = 0; DBRes.GetField( "map_id",map_id, Error ); int area_id = 0; DBRes.GetField( "area_id",area_id, Error ); double limit_value = 0; DBRes.GetField( "limit_value",limit_value, Error ); double cur_value = 0; DBRes.GetField( "cur_value",cur_value, Error ); double x = 0; DBRes.GetField( "x",x, Error ); double y = 0; DBRes.GetField( "y",y, Error ); std::string cur_time = ""; DBRes.GetField( "cur_time",cur_time, Error ); int stat = 0; DBRes.GetField( "stat",stat, Error ); //增加虚拟告警处理逻辑 std::shared_ptr ev=nullptr; bool flag=false; if(!init){ ev=event_list::instance()->get(id); if(!ev){ ev = std::make_shared(event_id); }else{ flag=true; if(stat==100)ev->m_is_sent=false; } }else{ ev = std::make_shared(event_id); } ev->m_status = static_cast(stat); ev->m_ev_type = static_cast(event_type_id); ev->m_obj_type = static_cast(obj_type_id); ev->m_dis_type = static_cast(dis_type); ev->m_obj_id = obj_id; ev->m_cur_time = tool_time::to_time_ex(cur_time); ev->m_cur_value = cur_value; ev->m_limit_value = limit_value; ev->m_map_id = map_id; ev->m_area_id = area_id; ev->x = x; ev->y = y; ev->m_id = id; //这里当是卡告警的时候,对m_event数据进行赋值 //方便清理 //备注防追尾告警和一人多卡告警可能不适用,后续整理 if(ev->m_obj_type==OT_CARD){ uint64_t c_id= tool_other::card_id_to_u64(ev->m_obj_id); if(auto c=card_list::instance()->get(c_id)){ if(c->m_type==CT_PERSON){ auto mine_tool_ptr = c->get_mine_tool(); if(!mine_tool_ptr->m_is_attendance) { log_warn("person_not_att:%s",obj_id.c_str()); continue; } } c->set_event_flag(ev->m_ev_type); if(event_type_id==ET_CARD_LOW_POWER_SERIOUS) c->m_pwr_stat=STATUS_POWER_LOWER_SERIOUS; } else { log_warn("load_evnet_history:card_id:%s not exist...",obj_id.c_str()); continue; } }else if(ev->m_obj_type==OT_DEVICE_READER){ auto sit_ptr=sit_list::instance()->get(std::stoi(obj_id)); if(!sit_ptr){ log_warn("load_evnet_history:site_id:%s not exist...",obj_id.c_str()); continue; } if(ev->m_ev_type==ET_READER_POWER_BY_BATTERY) sit_ptr->m_power_ac_down=true; if(ev->m_ev_type==ET_READER_ERROR) sit_ptr->m_time=tool_time::to_ms(ev->m_cur_time)/1000; } if(!flag) map.insert(std::make_pair(id, ev)); log_info("event_list %lld,%lld,%d,%d,%d,%s,%d,%d,%d,%.2f,%.2f,%.2f,%.2f,%s" , ev->m_ev_id,ev->m_id,ev->m_status,ev->m_ev_type,ev->m_obj_type,ev->m_obj_id.c_str(),ev->m_dis_type ,ev->m_map_id,ev->m_area_id,ev->m_limit_value,ev->m_cur_value ,ev->x,ev->y ,tool_time::to_str_ex(ev->m_cur_time).c_str()); } if(!map.empty()) event_list::instance()->add(map); } } /* * @brief * 加载车辆历史告警表 * @param * * @return * 无 * @note * @warning * @bug * */ void event_list::load_his_data_v_from_db() { static std::time_t s_last_time=0; if(!init){ std::time_t t=time(0); if(t-s_last_time<15)return; s_last_time=t; } std::unordered_map> map; std::string sql("SELECT id, obj_id, event_type_id, x, y, start_time from his_event_data_v where id in (select max(id), obj_id, event_type_id, x, y, start_time from his_event_data_v where end_time is null and start_time > DATE_SUB(NOW(), INTERVAL 1 DAY) GROUP BY obj_id_id, event_type_id);"); std::string Error; YADB::CDBResultSet DBRes; sDBConnPool.Query(sql.c_str(),DBRes,Error); if(!Error.empty()) log_error("初始化事件列表 Error,%s",Error.c_str()); uint64_t nCount = DBRes.GetRecordCount( Error ); if (nCount > 0) { log_info( "init_event_list. The record count=%ld\n", nCount ); while ( DBRes.GetNextRecod(Error) ) { long long int event_id = 0; DBRes.GetField( "id",event_id, Error ); long long int id = 0; id = event_id; int event_type_id = 0; DBRes.GetField( "event_type_id",event_type_id, Error ); int obj_type_id = 0; std::string obj_id = ""; DBRes.GetField( "obj_id",obj_id, Error ); int dis_type = 0; int map_id = 0; int area_id = 0; double limit_value = 0; double cur_value = 0; double x = 0; DBRes.GetField( "x",x, Error ); double y = 0; DBRes.GetField( "y",y, Error ); std::string cur_time = ""; DBRes.GetField( "start_time",cur_time, Error ); int stat = 0; //增加虚拟告警处理逻辑 std::shared_ptr ev=nullptr; bool flag=false; if(!init){ ev=event_list::instance()->get(id); if(!ev){ ev = std::make_shared(event_id); }else{ flag=true; if(stat==100)ev->m_is_sent=false; } }else{ ev = std::make_shared(event_id); } ev->m_status = static_cast(stat); ev->m_ev_type = static_cast(event_type_id); ev->m_obj_type = static_cast(obj_type_id); ev->m_dis_type = static_cast(dis_type); ev->m_obj_id = obj_id; ev->m_cur_time = tool_time::to_time_ex(cur_time); ev->m_cur_value = cur_value; ev->m_limit_value = limit_value; ev->m_map_id = map_id; ev->m_area_id = area_id; ev->x = x; ev->y = y; ev->m_id = id; //这里当是卡告警的时候,对m_event数据进行赋值 //方便清理 //备注防追尾告警和一人多卡告警可能不适用,后续整理 if(!flag) map.insert(std::make_pair(id, ev)); log_info("event_list %lld,%lld,%d,%d,%d,%s,%d,%d,%d,%.2f,%.2f,%.2f,%.2f,%s" , ev->m_ev_id,ev->m_id,ev->m_status,ev->m_ev_type,ev->m_obj_type,ev->m_obj_id.c_str(),ev->m_dis_type ,ev->m_map_id,ev->m_area_id,ev->m_limit_value,ev->m_cur_value ,ev->x,ev->y ,tool_time::to_str_ex(ev->m_cur_time).c_str()); } if(!map.empty()) event_list::instance()->add(map); } } /* * @brief * 事件转为json * @param * std::vector> arr 事件列表 * @return * json字符串 * @note * @warning * @bug * */ std::string event_list::evs_to_json(std::vector> arr) { rapidjson::Document doc(rapidjson::kObjectType); rapidjson::Value data(rapidjson::kArrayType); rapidjson::Document::AllocatorType& allocator=doc.GetAllocator(); auto it=arr.begin(); for(;it!=arr.end();++it) { _ev_to_node(*it, allocator, data); } doc.AddMember(JSON_ROOT_KEY_CMD,JSON_CMD_VALUE_EVENT, allocator); doc.AddMember(JSON_ROOT_KEY_VERSION,INTERFACE_VERSION, allocator); doc.AddMember(JSON_ROOT_KEY_DATA,data, allocator); rapidjson::StringBuffer sb; rapidjson::Writer writer(sb); doc.Accept(writer); return sb.GetString(); } /* * @brief * 构造alarm的json字符串 * @param * std::vector> arr 告警事件列表 * @return * alarm的json字符串 * @note * @warning * @bug * * */ std::string event_list::evs_to_json_v(std::vector> arr) { rapidjson::Document doc(rapidjson::kObjectType); rapidjson::Value data(rapidjson::kArrayType); rapidjson::Document::AllocatorType& allocator=doc.GetAllocator(); auto it=arr.begin(); for(;it!=arr.end();++it) { _ev_to_node_v(*it, allocator, data); } doc.AddMember(JSON_ROOT_KEY_CMD, "alarm", allocator); doc.AddMember(JSON_ROOT_KEY_DATA, data, allocator); rapidjson::StringBuffer sb; rapidjson::Writer writer(sb); doc.Accept(writer); return sb.GetString(); } void event_list::_ev_to_node(std::shared_ptr ev_ptr, rapidjson::Document::AllocatorType& allocator, rapidjson::Value& out_data) { rapidjson::Value ev(rapidjson::kObjectType); //ev.AddMember(JSON_KEY_EVENT_EVENT_ID,ev_ptr->m_id, allocator); tool_json::add_member(ev, JSON_KEY_EVENT_EVENT_ID, std::to_string(ev_ptr->m_id), allocator); ev.AddMember(JSON_KEY_EVENT_STATUS,ev_ptr->m_status, allocator); ev.AddMember(JSON_KEY_EVENT_TYPE_ID,ev_ptr->m_ev_type, allocator); ev.AddMember(JSON_KEY_EVENT_OBJ_TYPE_ID,ev_ptr->m_obj_type, allocator); tool_json::add_member(ev, JSON_KEY_EVENT_OBJ_ID, ev_ptr->m_obj_id, allocator); ev.AddMember(JSON_KEY_EVENT_DIS_TYPE_ID,ev_ptr->m_dis_type, allocator); ev.AddMember(JSON_KEY_EVENT_MAP_ID,ev_ptr->m_map_id, allocator); ev.AddMember(JSON_KEY_EVENT_AREA_ID,ev_ptr->m_area_id, allocator); ev.AddMember(JSON_KEY_EVENT_X,ev_ptr->x, allocator); ev.AddMember(JSON_KEY_EVENT_Y,ev_ptr->y, allocator); ev.AddMember(JSON_KEY_EVENT_LIMIT_VALUE,ev_ptr->m_limit_value, allocator); ev.AddMember(JSON_KEY_EVENT_CUR_VALUE,ev_ptr->m_cur_value, allocator); ev.AddMember(JSON_KEY_EVENT_CUR_TIME,tool_time::to_ms(ev_ptr->m_cur_time), allocator); out_data.PushBack(ev, allocator); } /* * @brief * 构造每个具体告警的数据 * @param * std::shared_ptr ev_ptr //告警对象 * rapidjson::Document::AllocatorType& allocator //json的allocator * rapidjson::Value& out_data //输出的json value对象 * @return * @note * @warning * @bug * */ void event_list::_ev_to_node_v(std::shared_ptr ev_ptr, rapidjson::Document::AllocatorType& allocator, rapidjson::Value& out_data) { rapidjson::Value ev(rapidjson::kObjectType); //ev.AddMember(JSON_KEY_EVENT_EVENT_ID,ev_ptr->m_id, allocator); tool_json::add_member(ev, JSON_KEY_EVENT_EVENT_ID, std::to_string(ev_ptr->m_id), allocator); ev.AddMember(JSON_KEY_EVENT_TYPE_ID,ev_ptr->m_ev_type, allocator); tool_json::add_member(ev, JSON_KEY_EVENT_OBJ_ID, ev_ptr->m_obj_id, allocator); ev.AddMember(JSON_KEY_EVENT_X,ev_ptr->x, allocator); ev.AddMember(JSON_KEY_EVENT_Y,ev_ptr->y, allocator); switch(ev_ptr->m_status){ case 0: ev.AddMember("start_time", tool_time::to_ms(ev_ptr->m_cur_time), allocator); break; case 100: ev.AddMember("end_time", tool_time::to_ms(ev_ptr->m_cur_time), allocator); break; default: break; } out_data.PushBack(ev, allocator); } //template<> std::shared_ptr single_base>::m_instance=std::make_shared();