void lookahead::CheckLookaheads(const train *t /* optional */, const track_location &pos, std::function<void(unsigned int distance, unsigned int speed)> f, std::function<void(LA_ERROR err, const track_target_ptr &piece)> errfunc) { unsigned int last_distance = UINT_MAX; unsigned int last_speed = UINT_MAX; auto sendresponse = [&](unsigned int distance, unsigned int speed) { if (speed == UINT_MAX) { return; } if (distance < last_distance || speed < last_speed) { f(distance, speed); last_distance = distance; last_speed = speed; } }; for (auto it = l1_list.begin(); it != l1_list.end(); ++it) { for (auto jt = it->l2_list.begin(); jt != it->l2_list.end(); ++jt) { if (current_offset >= jt->start_offset && current_offset <= jt->end_offset) { sendresponse(0, jt->speed); if (jt->flags & lookahead_item::LAI_FLAGS::TRACTION_UNSUITABLE) { errfunc(LA_ERROR::TRACTION_UNSUITABLE, jt->piece); } } else if (current_offset < jt->start_offset) { if (current_offset < jt->sighting_offset && jt->flags & lookahead_item::LAI_FLAGS::HALT_UNLESS_VISIBLE) { sendresponse(jt->start_offset - current_offset, 0); } else if (jt->flags & lookahead_item::LAI_FLAGS::NOT_ALWAYS_PASSABLE && current_offset >= jt->sighting_offset) { if (jt->flags & lookahead_item::LAI_FLAGS::ALLOW_DIFFERENT_CONNECTION_INDEX && jt->connection_index != jt->piece.track->GetCurrentNominalConnectionIndex(jt->piece.direction)) { //points have moved, rescan Init(t, pos, 0); CheckLookaheads(t, pos, f, errfunc); return; } if (jt->piece.track->IsTrackPassable(jt->piece.direction, jt->connection_index)) { if (jt->flags & lookahead_item::LAI_FLAGS::SCAN_BEYOND_IF_PASSABLE) { ScanAppend(t, track_location(jt->piece.track->GetConnectingPiece(jt->piece.direction)), 1, 0); jt->flags &= ~lookahead_item::LAI_FLAGS::SCAN_BEYOND_IF_PASSABLE; } sendresponse(jt->start_offset - current_offset, jt->speed); } else { //track not passable, stop sendresponse(jt->start_offset - current_offset, 0); } } else { sendresponse(jt->start_offset - current_offset, jt->speed); } } } if (current_offset > it->offset) { return; } if (current_offset >= it->sighting_offset && it->gs.IsValid()) { //can see signal bool reinit = false; unsigned int aspect = it->gs.track->GetAspect(); if (it->last_aspect > 0 && it->gs.track->GetAspectNextTarget() != std::next(it)->gs.track) { //signal now points somewhere else //this is bad errfunc(LA_ERROR::SIG_TARGET_CHANGE, it->gs); reinit = true; } if (aspect < it->last_aspect) { //adverse change of aspect //this is also bad errfunc(LA_ERROR::SIG_ASPECT_LESS_THAN_EXPECTED, it->gs); reinit = true; } if (reinit) { while (std::next(it) != l1_list.end()) l1_list.pop_back(); const route *rt = nullptr; generic_signal *gs = FastSignalCast(l1_list.back().gs.track, l1_list.back().gs.direction); if (gs) { rt = gs->GetCurrentForwardRoute(); } ScanAppend(t, track_location(l1_list.back().gs), aspect, rt); } else if (aspect > it->last_aspect) { //need to extend lookahead for (auto jt = std::next(it); jt != l1_list.end(); ++jt) { if (jt->gs.IsValid()) { jt->last_aspect = jt->gs.track->GetAspect(); } } const route *rt = nullptr; generic_signal *gs = FastSignalCast(l1_list.back().gs.track, l1_list.back().gs.direction); if (gs) { rt = gs->GetCurrentForwardRoute(); } ScanAppend(t, track_location(l1_list.back().gs), aspect - it->last_aspect, rt); it->last_aspect = aspect; } if (aspect == 0) { unsigned int distance = it->offset - current_offset; sendresponse(distance, 0); if (distance == 0) { errfunc(LA_ERROR::WAITING_AT_RED_SIG, it->gs); } } } else if (it->gs.IsValid() && it->last_aspect == 0) { sendresponse(it->offset - current_offset, 0); } } }
bool BrowseTableModel::setData(const QModelIndex &index, const QVariant &value, int role) { Q_UNUSED(role); if (!index.isValid()) { return false; } qDebug() << "BrowseTableModel::setData(" << index.data() << ")"; int row = index.row(); int col = index.column(); mixxx::TrackMetadata trackMetadata; // set tagger information trackMetadata.setArtist(this->index(row, COLUMN_ARTIST).data().toString()); trackMetadata.setTitle(this->index(row, COLUMN_TITLE).data().toString()); trackMetadata.setAlbum(this->index(row, COLUMN_ALBUM).data().toString()); trackMetadata.setKey(this->index(row, COLUMN_KEY).data().toString()); trackMetadata.setBpm(mixxx::Bpm(this->index(row, COLUMN_BPM).data().toDouble())); trackMetadata.setComment(this->index(row, COLUMN_COMMENT).data().toString()); trackMetadata.setTrackNumber(this->index(row, COLUMN_TRACK_NUMBER).data().toString()); trackMetadata.setYear(this->index(row, COLUMN_YEAR).data().toString()); trackMetadata.setGenre(this->index(row, COLUMN_GENRE).data().toString()); trackMetadata.setComposer(this->index(row, COLUMN_COMPOSER).data().toString()); trackMetadata.setAlbumArtist(this->index(row, COLUMN_ALBUMARTIST).data().toString()); trackMetadata.setGrouping(this->index(row, COLUMN_GROUPING).data().toString()); // check if one the item were edited if (col == COLUMN_ARTIST) { trackMetadata.setArtist(value.toString()); } else if (col == COLUMN_TITLE) { trackMetadata.setTitle(value.toString()); } else if (col == COLUMN_ALBUM) { trackMetadata.setAlbum(value.toString()); } else if (col == COLUMN_BPM) { trackMetadata.setBpm(mixxx::Bpm(value.toDouble())); } else if (col == COLUMN_KEY) { trackMetadata.setKey(value.toString()); } else if (col == COLUMN_TRACK_NUMBER) { trackMetadata.setTrackNumber(value.toString()); } else if (col == COLUMN_COMMENT) { trackMetadata.setComment(value.toString()); } else if (col == COLUMN_GENRE) { trackMetadata.setGenre(value.toString()); } else if (col == COLUMN_COMPOSER) { trackMetadata.setComposer(value.toString()); } else if (col == COLUMN_YEAR) { trackMetadata.setYear(value.toString()); } else if (col == COLUMN_ALBUMARTIST) { trackMetadata.setAlbumArtist(value.toString()); } else if (col == COLUMN_GROUPING) { trackMetadata.setGrouping(value.toString()); } else { qWarning() << "BrowseTableModel::setData(): no tagger column"; return false; } QStandardItem* item = itemFromIndex(index); QString track_location(getTrackLocation(index)); if (OK == mixxx::taglib::writeTrackMetadataIntoFile(trackMetadata, track_location)) { // Modify underlying interalPointer object item->setText(value.toString()); item->setToolTip(item->text()); return true; } else { // reset to old value in error item->setText(index.data().toString()); item->setToolTip(item->text()); QMessageBox::critical( 0, tr("Mixxx Library"), tr("Could not update file metadata.") + "\n" +track_location); return false; } }
void lookahead::ScanAppend(const train *t /* optional */, const track_location &pos, unsigned int blocklimit, const route *rt) { uint64_t offset; if (! l1_list.empty()) { offset = l1_list.back().offset; } else { offset = current_offset; } l1_list.emplace_back(); lookahead_routing_point *l = &l1_list.back(); auto newsignal = [&](const vartrack_target_ptr<routing_point> &sig) { l->offset = offset; l->gs = sig; l->sighting_offset = offset - sig.track->GetSightingDistance(sig.direction); blocklimit--; l->last_aspect = std::min(blocklimit, sig.track->GetAspect()); }; auto newpiece = [&](const track_target_ptr &piece, unsigned int connection_index) { l->l2_list.emplace_back(); lookahead_item &l2 = l->l2_list.back(); l2.connection_index = connection_index; l2.start_offset = offset; l2.sighting_offset = offset - piece.track->GetSightingDistance(piece.direction); offset += piece.track->GetLength(piece.direction); l2.end_offset = offset; l2.piece = piece; if (t) { const traction_set *ts = piece.track->GetTractionTypes(); if (ts && !ts->CanTrainPass(t)) { l2.speed = 0; l2.flags |= lookahead_item::LAI_FLAGS::TRACTION_UNSUITABLE; return; } } const speed_restriction_set *srs = piece.track->GetSpeedRestrictions(); if (srs) { l2.speed = srs->GetTrainTrackSpeedLimit(t); } else { l2.speed = UINT_MAX; } if (!piece.track->IsTrackAlwaysPassable()) { l2.flags |= lookahead_item::LAI_FLAGS::NOT_ALWAYS_PASSABLE; } }; if (rt) { if (t && !rt->IsRouteTractionSuitable(t)) { l->l2_list.emplace_back(); lookahead_item &l2 = l->l2_list.back(); l2.start_offset = offset; l2.end_offset = offset; l2.sighting_offset = 0; l2.speed = 0; l2.flags |= lookahead_item::LAI_FLAGS::TRACTION_UNSUITABLE; l2.piece = rt->start; } auto it = rt->pieces.begin(); if (pos.GetTrack() != rt->start.track) { for (; it != rt->pieces.end(); ++it) { if (pos.GetTrack() == it->location.track) { offset -= pos.GetTrack()->GetLength(pos.GetDirection()) - pos.GetTrack()->GetRemainingLength(pos.GetDirection(), pos.GetOffset()); break; } } } for (;it != rt->pieces.end(); ++it) { generic_signal *gs = FastSignalCast(it->location.track, it->location.direction); if (gs) { newsignal(vartrack_target_ptr<routing_point>(gs, it->location.direction)); if (blocklimit) { l1_list.emplace_back(); l = &l1_list.back(); } else { return; } } else { newpiece(it->location, it->connection_index); } } newsignal(rt->end); if (blocklimit) { const route *next_rt = nullptr; generic_signal *gs = FastSignalCast(rt->end.track, rt->end.direction); if (gs) { next_rt = gs->GetCurrentForwardRoute(); } ScanAppend(t, track_location(rt->end), blocklimit, next_rt); } } else { offset -= pos.GetTrack()->GetLength(pos.GetDirection()) - pos.GetTrack()->GetRemainingLength(pos.GetDirection(), pos.GetOffset()); track_target_ptr current(pos.GetTrack(), pos.GetDirection()); while (true) { generic_signal *gs = FastSignalCast(current.track, current.direction); if (gs) { newsignal(vartrack_target_ptr<routing_point>(gs, current.direction)); l->last_aspect = 0; return; } if (!current.track->IsTrackAlwaysPassable()) { unsigned int connection_index = current.track->GetCurrentNominalConnectionIndex(current.direction); newpiece(current, connection_index); l->l2_list.back().flags |= lookahead_item::LAI_FLAGS::ALLOW_DIFFERENT_CONNECTION_INDEX | lookahead_item::LAI_FLAGS::HALT_UNLESS_VISIBLE; if (current_offset < l->l2_list.back().sighting_offset) { //can't see beyond this l->l2_list.back().flags |= lookahead_item::LAI_FLAGS::SCAN_BEYOND_IF_PASSABLE; break; } } else { newpiece(current, 0); } track_target_ptr next = current.track->GetConnectingPiece(current.direction); if (next.IsValid()) { current = next; } else { routing_point *rp = FastRoutingpointCast(current.track, current.direction); if (rp) { newsignal(vartrack_target_ptr<routing_point>(rp, current.direction)); } break; } } if (!l->gs.IsValid()) { if (l->l2_list.empty()) { l1_list.pop_back(); } else { l->offset = l->l2_list.back().end_offset; //dummy signal l->gs.Reset(); l->sighting_offset = l->offset; l->last_aspect = 0; } } } }