/// @fn int s_trnc_state_machine(iow_socket_t *s, app_cfg_t *cfg) /// @brief state machine implementation /// @param[in] s iow_socket_t reference /// @param[in] cfg app_cfg reference /// @return none static int s_trnc_state_machine(iow_socket_t *s, app_cfg_t *cfg) { int retval=-1; int scycles=cfg->cycles; int trn_tx_count=0; int trn_rx_count=0; int trn_tx_bytes=0; int trn_rx_bytes=0; int trn_msg_count=0; int trn_msg_bytes=0; const char *reqstr="REQ\0"; if (NULL!=s) { // initialize variables trn_message_t message; trn_message_t *pmessage = &message; mbtrn_header_t *pheader = &pmessage->data.header; mbtrn_sounding_t *psounding = &pmessage->data.sounding; memset(pmessage,0,sizeof(message)); int hbeat_counter=0; int64_t test=0; byte *pread=NULL; uint32_t readlen=0; trnc_state_t state=ST_INIT; trnc_action_t action=AT_NOP; // state machine entry point while (state != ST_DONE && !g_interrupt) { // check states, assign actions switch (state) { case ST_INIT: memset(&message,0,MBTRN_MAX_MSG_BYTES); action = AT_CONNECT; break; case ST_CONNECTED: action=AT_WR_REQ; break; case ST_REQ_PENDING: case ST_SUBSCRIBED: memset(&message,0,MBTRN_MAX_MSG_BYTES); action=AT_RD_MSG; break; case ST_HBEAT_EXPIRED: action=AT_WR_REQ; break; default: break; }// switch // action: connect if (action == AT_CONNECT) { MMDEBUG(ID_APP,"connecting [%s:%d]\n",cfg->host,cfg->port); if( (test=iow_connect(s))==0 ) { MMDEBUG(ID_APP,"connect OK\n"); state=ST_CONNECTED; }else{ MERROR("connect failed [%"PRId64"]\n",test); } } // action: write request if (action == AT_WR_REQ) { test=iow_sendto(s,NULL,(byte *)reqstr,4,0); MMDEBUG(ID_APP,"sendto REQ ret[%"PRId64"] [%d/%s]\n",test,errno,strerror(errno)); if( test>0 ){ trn_tx_count++; trn_tx_bytes+=test; state=ST_REQ_PENDING; }else{ MMDEBUG(ID_APP,"sendto failed ret[%"PRId64"] [%d/%s]\n",test,errno,strerror(errno)); } } // action: read response if (action == AT_RD_MSG) { pread = (byte *)&message; readlen = MBTRN_MAX_MSG_BYTES; // request message if ((test = iow_recvfrom(s, NULL, pread, readlen))>0) { trn_rx_bytes+=test; trn_rx_count++; // check message type if (pheader->type==MBTRN_MSGTYPE_ACK) { MMDEBUG(ID_APP,"received ACK ret[%"PRId64"] [%08X]\n",test,pheader->type); hbeat_counter=0; state=ST_SUBSCRIBED; }else if (pheader->type==MBTRN_MSGTYPE_MB1) { MMDEBUG(ID_APP,"received MSG ret[%"PRId64"] type[%08X] size[%d] ping[%06d]\n",test,pheader->type,pheader->size,psounding->ping_number); trn_msg_count++; trn_msg_bytes+=test; action=AT_SHOW_MSG; if (state==ST_REQ_PENDING) { state=ST_REQ_PENDING; }else{ state=ST_SUBSCRIBED; } hbeat_counter++; MMDEBUG(ID_APP,"hbeat[%d/%d]\n",hbeat_counter,cfg->hbeat); if ( (hbeat_counter!=0) && (hbeat_counter%cfg->hbeat==0)) { state=ST_HBEAT_EXPIRED; } }else{ // response not recognized MMDEBUG(ID_APP,"invalid message [%08X]\n",pheader->type); } }else{ // read returned error // MMDEBUG(ID_APP,"invalid message [%d]\n",test); switch (errno) { case EWOULDBLOCK: // nothing to read // MMDEBUG(ID_APP,"err - [%d/%s]\n",errno, strerror(errno)); break; case ENOTCONN: case ECONNREFUSED: // host disconnected MMDEBUG(ID_APP,"err - server not connected [%d/%s]\n",errno, strerror(errno)); iow_socket_destroy(&s); s = iow_socket_new(cfg->host, cfg->port, ST_UDP); iow_set_blocking(s,(cfg->blocking==0?false:true)); sleep(5); state=ST_INIT; retval=-1; break; default: MMDEBUG(ID_APP,"err ? [%d/%s]\n",errno, strerror(errno)); break; }//switch } } // action: show message if (action == AT_SHOW_MSG) { MMDEBUG(ID_APP,"\nts[%.3f] ping[%06d] lat[%.4lf] lon[%.4lf]\nsd[%7.2lf] hdg[%6.2lf] nb[%03"PRIu32"]\n", psounding->ts, psounding->ping_number, psounding->lat, psounding->lon, psounding->depth, psounding->hdg, (uint32_t)psounding->nbeams); uint32_t j=0; struct mbtrn_beam_data *bd=psounding->beams; for (j=0; j<psounding->nbeams; j++,bd++){ MMDEBUG(ID_APP,"n[%03"PRIu32"] atrk/X[% 10.3lf] ctrk/Y[% 10.3lf] dpth/Z[% 10.3lf]\n", (uint32_t)bd->beam_num, bd->rhox, bd->rhoy, bd->rhoz); } } // action: quit state machine if (action == AT_QUIT) { break; } // check cycles and signals scycles--; if(scycles==0){ MTRACE(); retval=0; state=ST_DONE; } if(g_interrupt){ MTRACE(); retval=-1; state=ST_DONE; } }// while !ST_DONE }//else invalid arg MMINFO(ID_APP,"tx count/bytes[%d/%d]\n",trn_tx_count,trn_tx_bytes); MMINFO(ID_APP,"rx count/bytes[%d/%d]\n",trn_rx_count,trn_rx_bytes); MMINFO(ID_APP,"trn count/bytes[%d/%d]\n",trn_msg_count,trn_msg_bytes); return retval; }
bool TMXLoader::Private::processMap(XMLElement &m) { if ((XML_SUCCESS != m.QueryIntAttribute("width", &map_size.width)) || (XML_SUCCESS != m.QueryIntAttribute("height", &map_size.height)) || (XML_SUCCESS != m.QueryIntAttribute("tilewidth", &tile_size.width)) || (XML_SUCCESS != m.QueryIntAttribute("tileheight", &tile_size.height))) { MMWARNING("Map element is missing one or more required attributes."); return(false); } /* default scale */ scale.set(1.f, 1.f); /* process properties */ XMLElement *l_properties = m.FirstChildElement(TMXPROPERTIES_NODE); XMLElement *l_property = l_properties ? l_properties->FirstChildElement(TMXPROPERTIES_PROPERTY_NODE) : 0; if (l_property) do { const char *l_pname = l_property->Attribute("name"); if (!l_pname) continue; /* scale property */ if (0 == MMSTRCASECMP(l_pname, "scale")) { const char *l_value = l_property->Attribute("value"); if (!l_value) { MMWARNING("Skipping incomplete scale property."); continue; } if (0 == MMSTRCASECMP(l_value, "screen")) { const Math::Size2f &l_vsize = Graphics::Viewport::Size(); const Math::Size2i &l_wsize = Graphics::Viewport::WindowSize(); /* * calculate pixels per viewport coordinate ratio * scale ratio = vSize (vcoord)) / wSize (pixels) */ scale = l_vsize / l_wsize.cast<float>(); continue; } else if (2 == sscanf(l_value, "%fx%f", &scale.width, &scale.height)) continue; else if (1 == sscanf(l_value, "%f", &scale.width)) { scale.height = scale.width; continue; } MMERROR("Invalid scale value encountered."); continue; } /* * Parse scene background color */ else if (0 == MMSTRCASECMP(l_pname, "bgcolor")) { const char *l_value = l_property->Attribute("value"); if (!l_value) { MMWARNING("Skipping incomplete background color property."); continue; } /* * Valid formats: #RRGGBB, RRGGBB. */ uint16_t l_pxl[3]; if ((sscanf(l_value, "#%2hx%2hx%2hx", &l_pxl[0], &l_pxl[1], &l_pxl[2]) != 3) && (sscanf(l_value, "%2hx%2hx%2hx", &l_pxl[0], &l_pxl[1], &l_pxl[2]) != 3)) { MMWARNING("Skipping invalid background color value."); continue; } /* set background color */ Game::SceneBase &l_scene_base = static_cast<Game::SceneBase &>(scene); l_scene_base.setBackground(PixelToColor(l_pxl)); continue; } } while ((l_property = l_property->NextSiblingElement(TMXPROPERTIES_PROPERTY_NODE))); MMINFO("Map scale size (" << scale.width << "x" << scale.height << ")"); /* calculate half-relative map size (used to offset coordinates) */ hrmap_size.width = scale.width * static_cast<float>(map_size.width * tile_size.width); hrmap_size.height = scale.height * static_cast<float>(map_size.height * tile_size.height); return(true); }