Example #1
0
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);
		}
	}
}
Example #2
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;
    }
}
Example #3
0
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;
			}
		}
	}
}