void AutomationPattern::processMidiTime( const MidiTime & time ) { if( ! isRecording() ) { if( time >= 0 && hasAutomation() ) { const float val = valueAt( time ); for( objectVector::iterator it = m_objects.begin(); it != m_objects.end(); ++it ) { if( *it ) { ( *it )->setAutomatedValue( val ); } } } } else { if( time >= 0 && ! m_objects.isEmpty() ) { const float value = static_cast<float>( firstObject()->value<float>() ); if( value != m_lastRecordedValue ) { putValue( time, value, true ); m_lastRecordedValue = value; } else if( valueAt( time ) != value ) { removeValue( time, false ); } } } }
void syncRoles() { QJsonObject firstObject(_data.first().toObject()); // TODO it expects certain data structure in all objects, add way to specify roles if (!_roles.count()) { _roles.reserve(firstObject.count()); _roles[SyncedRole] = EnginioString::_synced; // TODO Use a proper name, can we make it an attached property in qml? Does it make sense to try? _roles[CreatedAtRole] = EnginioString::createdAt; _roles[UpdatedAtRole] = EnginioString::updatedAt; _roles[IdRole] = EnginioString::id; _roles[ObjectTypeRole] = EnginioString::objectType; _rolesCounter = LastRole; } // estimate additional dynamic roles: QSet<QString> definedRoles = _roles.values().toSet(); for (QJsonObject::const_iterator i = firstObject.constBegin(); i != firstObject.constEnd(); ++i) { const QString key = i.key(); if (definedRoles.contains(key)) { // we skip predefined keys so we can keep constant id for them if (Q_UNLIKELY(key == EnginioString::_synced)) qWarning("EnginioModel can not be used with objects having \"_synced\" property. The property will be overriden."); } else _roles[_rolesCounter++] = i.key(); } }
LinkedDouble *LinkedDouble::getFirst(void) { LinkedDouble *node; enterLock(); node = firstObject(); leaveLock(); return node; }
void EnginioBaseModelPrivate::syncRoles() { QJsonObject firstObject(_data.first().toObject()); if (!_roles.count()) { _roles.reserve(firstObject.count()); _roles[QtCloudServices::SyncedRole] = QtCloudServicesConstants::_synced; // TODO Use a proper name, can we make it an attached property in qml? Does it make sense to try? _roles[QtCloudServices::CreatedAtRole] = QtCloudServicesConstants::createdAt; _roles[QtCloudServices::UpdatedAtRole] = QtCloudServicesConstants::updatedAt; _roles[QtCloudServices::IdRole] = QtCloudServicesConstants::id; _roles[QtCloudServices::ObjectTypeRole] = QtCloudServicesConstants::objectType; _rolesCounter = QtCloudServices::CustomPropertyRole; } // check if someone does not use custom roles QHash<int, QByteArray> predefinedRoles = q->roleNames(); foreach (int i, predefinedRoles.keys()) { if (i < QtCloudServices::CustomPropertyRole && i >= QtCloudServices::SyncedRole && predefinedRoles[i] != _roles[i].toUtf8()) { qWarning("Can not use custom role index lower then QtCloudServices::CustomPropertyRole, but '%i' was used for '%s'", i, predefinedRoles[i].constData()); continue; } _roles[i] = QString::fromUtf8(predefinedRoles[i].constData()); } // estimate additional dynamic roles: QSet<QString> definedRoles = _roles.values().toSet(); QSet<int> definedRolesIndexes = predefinedRoles.keys().toSet(); for (QJsonObject::const_iterator i = firstObject.constBegin(); i != firstObject.constEnd(); ++i) { const QString key = i.key(); if (definedRoles.contains(key)) { // we skip predefined keys so we can keep constant id for them if (Q_UNLIKELY(key == QtCloudServicesConstants::_synced)) { qWarning("EnginioModel can not be used with objects having \"_synced\" property. The property will be overriden."); } } else { while (definedRolesIndexes.contains(_rolesCounter)) { ++_rolesCounter; } _roles[_rolesCounter++] = i.key(); } } }
void LinkedDouble::insert(LinkedDouble& obj, InsertMode position) { LinkedDouble *node; enterLock(); obj.detach(); switch ( position ) { case modeAtFirst : node = firstObject(); obj.nextObject = node; node->prevObject = &obj; break; case modeBefore : obj.nextObject = this; obj.prevObject = this->prevObject; this->prevObject = &obj; if (obj.prevObject) obj.prevObject->nextObject = &obj; break; case modeAfter : obj.nextObject = this->nextObject; obj.prevObject = this; this->nextObject = &obj; if (obj.nextObject) obj.nextObject->prevObject = &obj; break; case modeAtLast : default : node = lastObject(); obj.nextObject = node->nextObject; obj.prevObject = node; node->nextObject = &obj; if(obj.nextObject) obj.nextObject->prevObject = &obj; break; } leaveLock(); }
void Song::processAutomations(const TrackList &tracklist, MidiTime timeStart, fpp_t) { AutomatedValueMap values; QSet<const AutomatableModel*> recordedModels; TrackContainer* container = this; int tcoNum = -1; switch (m_playMode) { case Mode_PlaySong: break; case Mode_PlayBB: { Q_ASSERT(tracklist.size() == 1); Q_ASSERT(tracklist.at(0)->type() == Track::BBTrack); auto bbTrack = dynamic_cast<BBTrack*>(tracklist.at(0)); auto bbContainer = Engine::getBBTrackContainer(); container = bbContainer; tcoNum = bbTrack->index(); } break; default: return; } values = container->automatedValuesAt(timeStart, tcoNum); TrackList tracks = container->tracks(); Track::tcoVector tcos; for (Track* track : tracks) { if (track->type() == Track::AutomationTrack) { track->getTCOsInRange(tcos, 0, timeStart); } } // Process recording for (TrackContentObject* tco : tcos) { auto p = dynamic_cast<AutomationPattern *>(tco); MidiTime relTime = timeStart - p->startPosition(); if (p->isRecording() && relTime >= 0 && relTime < p->length()) { const AutomatableModel* recordedModel = p->firstObject(); p->recordValue(relTime, recordedModel->value<float>()); recordedModels << recordedModel; } } // Apply values for (auto it = values.begin(); it != values.end(); it++) { if (! recordedModels.contains(it.key())) { it.key()->setAutomatedValue(it.value()); } } }
inline void removeAll() { firstObject()->remove(); remove(); }