mirror of
https://github.com/overte-org/overte.git
synced 2025-08-06 10:43:45 +02:00
Merge pull request #2832 from ey6es/master
After uploading new models, refresh locally cached versions so that the change is immediately apparent.
This commit is contained in:
commit
5a0f4e99a5
12 changed files with 157 additions and 50 deletions
|
@ -49,7 +49,7 @@ static const QString TRANSLATION_Z_FIELD = "tz";
|
||||||
static const QString JOINT_FIELD = "joint";
|
static const QString JOINT_FIELD = "joint";
|
||||||
static const QString FREE_JOINT_FIELD = "freeJoint";
|
static const QString FREE_JOINT_FIELD = "freeJoint";
|
||||||
|
|
||||||
static const QString S3_URL = "http://highfidelity-public.s3-us-west-1.amazonaws.com";
|
static const QString S3_URL = "http://public.highfidelity.io";
|
||||||
static const QString DATA_SERVER_URL = "https://data-web.highfidelity.io";
|
static const QString DATA_SERVER_URL = "https://data-web.highfidelity.io";
|
||||||
static const QString MODEL_URL = "/api/v1/models";
|
static const QString MODEL_URL = "/api/v1/models";
|
||||||
|
|
||||||
|
@ -201,12 +201,15 @@ bool ModelUploader::zip() {
|
||||||
mapping = properties.getMapping();
|
mapping = properties.getMapping();
|
||||||
|
|
||||||
QByteArray nameField = mapping.value(NAME_FIELD).toByteArray();
|
QByteArray nameField = mapping.value(NAME_FIELD).toByteArray();
|
||||||
|
QString urlBase;
|
||||||
if (!nameField.isEmpty()) {
|
if (!nameField.isEmpty()) {
|
||||||
QHttpPart textPart;
|
QHttpPart textPart;
|
||||||
textPart.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data; name=\"model_name\"");
|
textPart.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data; name=\"model_name\"");
|
||||||
textPart.setBody(nameField);
|
textPart.setBody(nameField);
|
||||||
_dataMultiPart->append(textPart);
|
_dataMultiPart->append(textPart);
|
||||||
_url = S3_URL + "/models/" + MODEL_TYPE_NAMES[_modelType] + "/" + nameField + ".fst";
|
urlBase = S3_URL + "/models/" + MODEL_TYPE_NAMES[_modelType] + "/" + nameField;
|
||||||
|
_url = urlBase + ".fst";
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
QMessageBox::warning(NULL,
|
QMessageBox::warning(NULL,
|
||||||
QString("ModelUploader::zip()"),
|
QString("ModelUploader::zip()"),
|
||||||
|
@ -218,6 +221,7 @@ bool ModelUploader::zip() {
|
||||||
|
|
||||||
QByteArray texdirField = mapping.value(TEXDIR_FIELD).toByteArray();
|
QByteArray texdirField = mapping.value(TEXDIR_FIELD).toByteArray();
|
||||||
QString texDir;
|
QString texDir;
|
||||||
|
_textureBase = urlBase + "/textures/";
|
||||||
if (!texdirField.isEmpty()) {
|
if (!texdirField.isEmpty()) {
|
||||||
texDir = basePath + "/" + texdirField;
|
texDir = basePath + "/" + texdirField;
|
||||||
QFileInfo texInfo(texDir);
|
QFileInfo texInfo(texDir);
|
||||||
|
@ -407,6 +411,10 @@ void ModelUploader::processCheck() {
|
||||||
QString("ModelUploader::processCheck()"),
|
QString("ModelUploader::processCheck()"),
|
||||||
QString("Your model is now available in the browser."),
|
QString("Your model is now available in the browser."),
|
||||||
QMessageBox::Ok);
|
QMessageBox::Ok);
|
||||||
|
Application::getInstance()->getGeometryCache()->refresh(_url);
|
||||||
|
foreach (const QByteArray& filename, _textureFilenames) {
|
||||||
|
Application::getInstance()->getTextureCache()->refresh(_textureBase + filename);
|
||||||
|
}
|
||||||
deleteLater();
|
deleteLater();
|
||||||
break;
|
break;
|
||||||
case QNetworkReply::ContentNotFoundError:
|
case QNetworkReply::ContentNotFoundError:
|
||||||
|
@ -428,32 +436,31 @@ void ModelUploader::processCheck() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ModelUploader::addTextures(const QString& texdir, const FBXGeometry& geometry) {
|
bool ModelUploader::addTextures(const QString& texdir, const FBXGeometry& geometry) {
|
||||||
QSet<QByteArray> added;
|
|
||||||
foreach (FBXMesh mesh, geometry.meshes) {
|
foreach (FBXMesh mesh, geometry.meshes) {
|
||||||
foreach (FBXMeshPart part, mesh.parts) {
|
foreach (FBXMeshPart part, mesh.parts) {
|
||||||
if (!part.diffuseTexture.filename.isEmpty() && part.diffuseTexture.content.isEmpty() &&
|
if (!part.diffuseTexture.filename.isEmpty() && part.diffuseTexture.content.isEmpty() &&
|
||||||
!added.contains(part.diffuseTexture.filename)) {
|
!_textureFilenames.contains(part.diffuseTexture.filename)) {
|
||||||
if (!addPart(texdir + "/" + part.diffuseTexture.filename,
|
if (!addPart(texdir + "/" + part.diffuseTexture.filename,
|
||||||
QString("texture%1").arg(++_texturesCount), true)) {
|
QString("texture%1").arg(++_texturesCount), true)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
added.insert(part.diffuseTexture.filename);
|
_textureFilenames.insert(part.diffuseTexture.filename);
|
||||||
}
|
}
|
||||||
if (!part.normalTexture.filename.isEmpty() && part.normalTexture.content.isEmpty() &&
|
if (!part.normalTexture.filename.isEmpty() && part.normalTexture.content.isEmpty() &&
|
||||||
!added.contains(part.normalTexture.filename)) {
|
!_textureFilenames.contains(part.normalTexture.filename)) {
|
||||||
if (!addPart(texdir + "/" + part.normalTexture.filename,
|
if (!addPart(texdir + "/" + part.normalTexture.filename,
|
||||||
QString("texture%1").arg(++_texturesCount), true)) {
|
QString("texture%1").arg(++_texturesCount), true)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
added.insert(part.normalTexture.filename);
|
_textureFilenames.insert(part.normalTexture.filename);
|
||||||
}
|
}
|
||||||
if (!part.specularTexture.filename.isEmpty() && part.specularTexture.content.isEmpty() &&
|
if (!part.specularTexture.filename.isEmpty() && part.specularTexture.content.isEmpty() &&
|
||||||
!added.contains(part.specularTexture.filename)) {
|
!_textureFilenames.contains(part.specularTexture.filename)) {
|
||||||
if (!addPart(texdir + "/" + part.specularTexture.filename,
|
if (!addPart(texdir + "/" + part.specularTexture.filename,
|
||||||
QString("texture%1").arg(++_texturesCount), true)) {
|
QString("texture%1").arg(++_texturesCount), true)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
added.insert(part.specularTexture.filename);
|
_textureFilenames.insert(part.specularTexture.filename);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,8 @@ private slots:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString _url;
|
QString _url;
|
||||||
|
QString _textureBase;
|
||||||
|
QSet<QByteArray> _textureFilenames;
|
||||||
int _lodCount;
|
int _lodCount;
|
||||||
int _texturesCount;
|
int _texturesCount;
|
||||||
int _totalSize;
|
int _totalSize;
|
||||||
|
|
|
@ -520,8 +520,9 @@ void MyAvatar::saveAttachmentData(const AttachmentData& attachment) const {
|
||||||
settings->beginGroup("savedAttachmentData");
|
settings->beginGroup("savedAttachmentData");
|
||||||
settings->beginGroup(_skeletonModel.getURL().toString());
|
settings->beginGroup(_skeletonModel.getURL().toString());
|
||||||
settings->beginGroup(attachment.modelURL.toString());
|
settings->beginGroup(attachment.modelURL.toString());
|
||||||
|
|
||||||
settings->setValue("jointName", attachment.jointName);
|
settings->setValue("jointName", attachment.jointName);
|
||||||
|
|
||||||
|
settings->beginGroup(attachment.jointName);
|
||||||
settings->setValue("translation_x", attachment.translation.x);
|
settings->setValue("translation_x", attachment.translation.x);
|
||||||
settings->setValue("translation_y", attachment.translation.y);
|
settings->setValue("translation_y", attachment.translation.y);
|
||||||
settings->setValue("translation_z", attachment.translation.z);
|
settings->setValue("translation_z", attachment.translation.z);
|
||||||
|
@ -534,10 +535,11 @@ void MyAvatar::saveAttachmentData(const AttachmentData& attachment) const {
|
||||||
settings->endGroup();
|
settings->endGroup();
|
||||||
settings->endGroup();
|
settings->endGroup();
|
||||||
settings->endGroup();
|
settings->endGroup();
|
||||||
|
settings->endGroup();
|
||||||
Application::getInstance()->unlockSettings();
|
Application::getInstance()->unlockSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
AttachmentData MyAvatar::loadAttachmentData(const QUrl& modelURL) const {
|
AttachmentData MyAvatar::loadAttachmentData(const QUrl& modelURL, const QString& jointName) const {
|
||||||
QSettings* settings = Application::getInstance()->lockSettings();
|
QSettings* settings = Application::getInstance()->lockSettings();
|
||||||
settings->beginGroup("savedAttachmentData");
|
settings->beginGroup("savedAttachmentData");
|
||||||
settings->beginGroup(_skeletonModel.getURL().toString());
|
settings->beginGroup(_skeletonModel.getURL().toString());
|
||||||
|
@ -545,20 +547,30 @@ AttachmentData MyAvatar::loadAttachmentData(const QUrl& modelURL) const {
|
||||||
|
|
||||||
AttachmentData attachment;
|
AttachmentData attachment;
|
||||||
attachment.modelURL = modelURL;
|
attachment.modelURL = modelURL;
|
||||||
attachment.jointName = settings->value("jointName").toString();
|
if (jointName.isEmpty()) {
|
||||||
attachment.translation.x = loadSetting(settings, "translation_x", 0.0f);
|
attachment.jointName = settings->value("jointName").toString();
|
||||||
attachment.translation.y = loadSetting(settings, "translation_y", 0.0f);
|
} else {
|
||||||
attachment.translation.z = loadSetting(settings, "translation_z", 0.0f);
|
attachment.jointName = jointName;
|
||||||
glm::vec3 eulers;
|
}
|
||||||
eulers.x = loadSetting(settings, "rotation_x", 0.0f);
|
settings->beginGroup(attachment.jointName);
|
||||||
eulers.y = loadSetting(settings, "rotation_y", 0.0f);
|
if (settings->contains("translation_x")) {
|
||||||
eulers.z = loadSetting(settings, "rotation_z", 0.0f);
|
attachment.translation.x = loadSetting(settings, "translation_x", 0.0f);
|
||||||
attachment.rotation = glm::quat(eulers);
|
attachment.translation.y = loadSetting(settings, "translation_y", 0.0f);
|
||||||
attachment.scale = loadSetting(settings, "scale", 1.0f);
|
attachment.translation.z = loadSetting(settings, "translation_z", 0.0f);
|
||||||
|
glm::vec3 eulers;
|
||||||
|
eulers.x = loadSetting(settings, "rotation_x", 0.0f);
|
||||||
|
eulers.y = loadSetting(settings, "rotation_y", 0.0f);
|
||||||
|
eulers.z = loadSetting(settings, "rotation_z", 0.0f);
|
||||||
|
attachment.rotation = glm::quat(eulers);
|
||||||
|
attachment.scale = loadSetting(settings, "scale", 1.0f);
|
||||||
|
} else {
|
||||||
|
attachment = AttachmentData();
|
||||||
|
}
|
||||||
|
|
||||||
settings->endGroup();
|
settings->endGroup();
|
||||||
settings->endGroup();
|
settings->endGroup();
|
||||||
settings->endGroup();
|
settings->endGroup();
|
||||||
|
settings->endGroup();
|
||||||
Application::getInstance()->unlockSettings();
|
Application::getInstance()->unlockSettings();
|
||||||
|
|
||||||
return attachment;
|
return attachment;
|
||||||
|
@ -650,8 +662,8 @@ void MyAvatar::attach(const QString& modelURL, const QString& jointName, const g
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (useSaved) {
|
if (useSaved) {
|
||||||
AttachmentData attachment = loadAttachmentData(modelURL);
|
AttachmentData attachment = loadAttachmentData(modelURL, jointName);
|
||||||
if (!attachment.jointName.isEmpty()) {
|
if (attachment.isValid()) {
|
||||||
Avatar::attach(modelURL, attachment.jointName, attachment.translation,
|
Avatar::attach(modelURL, attachment.jointName, attachment.translation,
|
||||||
attachment.rotation, attachment.scale, allowDuplicates, useSaved);
|
attachment.rotation, attachment.scale, allowDuplicates, useSaved);
|
||||||
return;
|
return;
|
||||||
|
@ -1490,7 +1502,7 @@ void MyAvatar::updateMotionBehaviorsFromMenu() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyAvatar::renderAttachments(RenderMode renderMode) {
|
void MyAvatar::renderAttachments(RenderMode renderMode) {
|
||||||
if (!Application::getInstance()->getCamera()->getMode() == CAMERA_MODE_FIRST_PERSON || renderMode == MIRROR_RENDER_MODE) {
|
if (Application::getInstance()->getCamera()->getMode() != CAMERA_MODE_FIRST_PERSON || renderMode == MIRROR_RENDER_MODE) {
|
||||||
Avatar::renderAttachments(renderMode);
|
Avatar::renderAttachments(renderMode);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,7 +67,7 @@ public:
|
||||||
void loadData(QSettings* settings);
|
void loadData(QSettings* settings);
|
||||||
|
|
||||||
void saveAttachmentData(const AttachmentData& attachment) const;
|
void saveAttachmentData(const AttachmentData& attachment) const;
|
||||||
AttachmentData loadAttachmentData(const QUrl& modelURL) const;
|
AttachmentData loadAttachmentData(const QUrl& modelURL, const QString& jointName = QString()) const;
|
||||||
|
|
||||||
// Set what driving keys are being pressed to control thrust levels
|
// Set what driving keys are being pressed to control thrust levels
|
||||||
void setDriveKeys(int key, float val) { _driveKeys[key] = val; };
|
void setDriveKeys(int key, float val) { _driveKeys[key] = val; };
|
||||||
|
|
|
@ -506,6 +506,15 @@ void GeometryReader::run() {
|
||||||
_reply->deleteLater();
|
_reply->deleteLater();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NetworkGeometry::init() {
|
||||||
|
_mapping = QVariantHash();
|
||||||
|
_geometry = FBXGeometry();
|
||||||
|
_meshes.clear();
|
||||||
|
_lods.clear();
|
||||||
|
_request.setUrl(_url);
|
||||||
|
Resource::init();
|
||||||
|
}
|
||||||
|
|
||||||
void NetworkGeometry::downloadFinished(QNetworkReply* reply) {
|
void NetworkGeometry::downloadFinished(QNetworkReply* reply) {
|
||||||
QUrl url = reply->url();
|
QUrl url = reply->url();
|
||||||
if (url.path().toLower().endsWith(".fst")) {
|
if (url.path().toLower().endsWith(".fst")) {
|
||||||
|
|
|
@ -96,6 +96,7 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
virtual void init();
|
||||||
virtual void downloadFinished(QNetworkReply* reply);
|
virtual void downloadFinished(QNetworkReply* reply);
|
||||||
virtual void reinsert();
|
virtual void reinsert();
|
||||||
|
|
||||||
|
|
|
@ -319,6 +319,9 @@ bool Model::updateGeometry() {
|
||||||
_jointStates = createJointStates(fbxGeometry);
|
_jointStates = createJointStates(fbxGeometry);
|
||||||
needToRebuild = true;
|
needToRebuild = true;
|
||||||
}
|
}
|
||||||
|
} else if (!geometry->isLoaded()) {
|
||||||
|
deleteGeometry();
|
||||||
|
_dilatedTextures.clear();
|
||||||
}
|
}
|
||||||
_geometry->setLoadPriority(this, -_lodDistance);
|
_geometry->setLoadPriority(this, -_lodDistance);
|
||||||
_geometry->ensureLoading();
|
_geometry->ensureLoading();
|
||||||
|
|
|
@ -97,7 +97,8 @@ static QDoubleSpinBox* createRotationBox(AttachmentPanel* panel, float value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
AttachmentPanel::AttachmentPanel(AttachmentsDialog* dialog, const AttachmentData& data) :
|
AttachmentPanel::AttachmentPanel(AttachmentsDialog* dialog, const AttachmentData& data) :
|
||||||
_dialog(dialog) {
|
_dialog(dialog),
|
||||||
|
_applying(false) {
|
||||||
setFrameStyle(QFrame::StyledPanel);
|
setFrameStyle(QFrame::StyledPanel);
|
||||||
|
|
||||||
QFormLayout* layout = new QFormLayout();
|
QFormLayout* layout = new QFormLayout();
|
||||||
|
@ -121,7 +122,7 @@ AttachmentPanel::AttachmentPanel(AttachmentsDialog* dialog, const AttachmentData
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_jointName->setCurrentText(data.jointName);
|
_jointName->setCurrentText(data.jointName);
|
||||||
connect(_jointName, SIGNAL(currentIndexChanged(int)), SLOT(updateAttachmentData()));
|
connect(_jointName, SIGNAL(currentIndexChanged(int)), SLOT(jointNameChanged()));
|
||||||
|
|
||||||
QHBoxLayout* translationBox = new QHBoxLayout();
|
QHBoxLayout* translationBox = new QHBoxLayout();
|
||||||
translationBox->addWidget(_translationX = createTranslationBox(this, data.translation.x));
|
translationBox->addWidget(_translationX = createTranslationBox(this, data.translation.x));
|
||||||
|
@ -171,25 +172,57 @@ void AttachmentPanel::setModelURL(const QString& url) {
|
||||||
|
|
||||||
void AttachmentPanel::modelURLChanged() {
|
void AttachmentPanel::modelURLChanged() {
|
||||||
// check for saved attachment data
|
// check for saved attachment data
|
||||||
|
if (_modelURL->text().isEmpty()) {
|
||||||
|
_dialog->updateAttachmentData();
|
||||||
|
return;
|
||||||
|
}
|
||||||
AttachmentData attachment = Application::getInstance()->getAvatar()->loadAttachmentData(_modelURL->text());
|
AttachmentData attachment = Application::getInstance()->getAvatar()->loadAttachmentData(_modelURL->text());
|
||||||
if (!attachment.jointName.isEmpty()) {
|
if (attachment.isValid()) {
|
||||||
|
_applying = true;
|
||||||
_jointName->setCurrentText(attachment.jointName);
|
_jointName->setCurrentText(attachment.jointName);
|
||||||
_translationX->setValue(attachment.translation.x);
|
applyAttachmentData(attachment);
|
||||||
_translationY->setValue(attachment.translation.y);
|
|
||||||
_translationZ->setValue(attachment.translation.z);
|
|
||||||
glm::vec3 eulers = glm::degrees(safeEulerAngles(attachment.rotation));
|
|
||||||
_rotationX->setValue(eulers.x);
|
|
||||||
_rotationY->setValue(eulers.y);
|
|
||||||
_rotationZ->setValue(eulers.z);
|
|
||||||
_scale->setValue(attachment.scale);
|
|
||||||
}
|
}
|
||||||
_dialog->updateAttachmentData();
|
_dialog->updateAttachmentData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AttachmentPanel::jointNameChanged() {
|
||||||
|
if (_applying) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// check for saved attachment data specific to this joint
|
||||||
|
if (_modelURL->text().isEmpty()) {
|
||||||
|
_dialog->updateAttachmentData();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
AttachmentData attachment = Application::getInstance()->getAvatar()->loadAttachmentData(
|
||||||
|
_modelURL->text(), _jointName->currentText());
|
||||||
|
if (attachment.isValid()) {
|
||||||
|
applyAttachmentData(attachment);
|
||||||
|
}
|
||||||
|
updateAttachmentData();
|
||||||
|
}
|
||||||
|
|
||||||
void AttachmentPanel::updateAttachmentData() {
|
void AttachmentPanel::updateAttachmentData() {
|
||||||
|
if (_applying) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
// save the attachment data under the model URL (if any)
|
// save the attachment data under the model URL (if any)
|
||||||
if (!_modelURL->text().isEmpty()) {
|
if (!_modelURL->text().isEmpty()) {
|
||||||
Application::getInstance()->getAvatar()->saveAttachmentData(getAttachmentData());
|
Application::getInstance()->getAvatar()->saveAttachmentData(getAttachmentData());
|
||||||
}
|
}
|
||||||
_dialog->updateAttachmentData();
|
_dialog->updateAttachmentData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AttachmentPanel::applyAttachmentData(const AttachmentData& attachment) {
|
||||||
|
_applying = true;
|
||||||
|
_translationX->setValue(attachment.translation.x);
|
||||||
|
_translationY->setValue(attachment.translation.y);
|
||||||
|
_translationZ->setValue(attachment.translation.z);
|
||||||
|
glm::vec3 eulers = glm::degrees(safeEulerAngles(attachment.rotation));
|
||||||
|
_rotationX->setValue(eulers.x);
|
||||||
|
_rotationY->setValue(eulers.y);
|
||||||
|
_rotationZ->setValue(eulers.z);
|
||||||
|
_scale->setValue(attachment.scale);
|
||||||
|
_applying = false;
|
||||||
|
_dialog->updateAttachmentData();
|
||||||
|
}
|
||||||
|
|
|
@ -61,10 +61,13 @@ private slots:
|
||||||
void chooseModelURL();
|
void chooseModelURL();
|
||||||
void setModelURL(const QString& url);
|
void setModelURL(const QString& url);
|
||||||
void modelURLChanged();
|
void modelURLChanged();
|
||||||
|
void jointNameChanged();
|
||||||
void updateAttachmentData();
|
void updateAttachmentData();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
void applyAttachmentData(const AttachmentData& attachment);
|
||||||
|
|
||||||
AttachmentsDialog* _dialog;
|
AttachmentsDialog* _dialog;
|
||||||
QLineEdit* _modelURL;
|
QLineEdit* _modelURL;
|
||||||
QComboBox* _jointName;
|
QComboBox* _jointName;
|
||||||
|
@ -75,6 +78,7 @@ private:
|
||||||
QDoubleSpinBox* _rotationY;
|
QDoubleSpinBox* _rotationY;
|
||||||
QDoubleSpinBox* _rotationZ;
|
QDoubleSpinBox* _rotationZ;
|
||||||
QDoubleSpinBox* _scale;
|
QDoubleSpinBox* _scale;
|
||||||
|
bool _applying;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_AttachmentsDialog_h
|
#endif // hifi_AttachmentsDialog_h
|
||||||
|
|
|
@ -352,6 +352,8 @@ public:
|
||||||
|
|
||||||
AttachmentData();
|
AttachmentData();
|
||||||
|
|
||||||
|
bool isValid() const { return modelURL.isValid(); }
|
||||||
|
|
||||||
bool operator==(const AttachmentData& other) const;
|
bool operator==(const AttachmentData& other) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,13 @@ ResourceCache::~ResourceCache() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ResourceCache::refresh(const QUrl& url) {
|
||||||
|
QSharedPointer<Resource> resource = _resources.value(url);
|
||||||
|
if (!resource.isNull()) {
|
||||||
|
resource->refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QSharedPointer<Resource> ResourceCache::getResource(const QUrl& url, const QUrl& fallback, bool delayLoad, void* extra) {
|
QSharedPointer<Resource> ResourceCache::getResource(const QUrl& url, const QUrl& fallback, bool delayLoad, void* extra) {
|
||||||
if (!url.isValid() && !url.isEmpty() && fallback.isValid()) {
|
if (!url.isValid() && !url.isEmpty() && fallback.isValid()) {
|
||||||
return getResource(fallback, QUrl(), delayLoad);
|
return getResource(fallback, QUrl(), delayLoad);
|
||||||
|
@ -107,25 +114,15 @@ QList<Resource*> ResourceCache::_loadingRequests;
|
||||||
Resource::Resource(const QUrl& url, bool delayLoad) :
|
Resource::Resource(const QUrl& url, bool delayLoad) :
|
||||||
_url(url),
|
_url(url),
|
||||||
_request(url),
|
_request(url),
|
||||||
_startedLoading(false),
|
|
||||||
_failedToLoad(false),
|
|
||||||
_loaded(false),
|
|
||||||
_lruKey(0),
|
_lruKey(0),
|
||||||
_reply(NULL),
|
_reply(NULL) {
|
||||||
_attempts(0) {
|
|
||||||
|
init();
|
||||||
|
|
||||||
if (url.isEmpty()) {
|
|
||||||
_startedLoading = _loaded = true;
|
|
||||||
return;
|
|
||||||
|
|
||||||
} else if (!(url.isValid() && ResourceCache::getNetworkAccessManager())) {
|
|
||||||
_startedLoading = _failedToLoad = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
_request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache);
|
_request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache);
|
||||||
|
|
||||||
// start loading immediately unless instructed otherwise
|
// start loading immediately unless instructed otherwise
|
||||||
if (!delayLoad) {
|
if (!(_startedLoading || delayLoad)) {
|
||||||
attemptRequest();
|
attemptRequest();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -178,6 +175,22 @@ float Resource::getLoadPriority() {
|
||||||
return highestPriority;
|
return highestPriority;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Resource::refresh() {
|
||||||
|
if (_reply == NULL && !(_loaded || _failedToLoad)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (_reply) {
|
||||||
|
ResourceCache::requestCompleted(this);
|
||||||
|
delete _reply;
|
||||||
|
_reply = NULL;
|
||||||
|
}
|
||||||
|
init();
|
||||||
|
_request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::AlwaysNetwork);
|
||||||
|
if (!_startedLoading) {
|
||||||
|
attemptRequest();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Resource::allReferencesCleared() {
|
void Resource::allReferencesCleared() {
|
||||||
if (QThread::currentThread() != thread()) {
|
if (QThread::currentThread() != thread()) {
|
||||||
QMetaObject::invokeMethod(this, "allReferencesCleared");
|
QMetaObject::invokeMethod(this, "allReferencesCleared");
|
||||||
|
@ -197,6 +210,20 @@ void Resource::allReferencesCleared() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Resource::init() {
|
||||||
|
_startedLoading = false;
|
||||||
|
_failedToLoad = false;
|
||||||
|
_loaded = false;
|
||||||
|
_attempts = 0;
|
||||||
|
|
||||||
|
if (_url.isEmpty()) {
|
||||||
|
_startedLoading = _loaded = true;
|
||||||
|
|
||||||
|
} else if (!(_url.isValid() && ResourceCache::getNetworkAccessManager())) {
|
||||||
|
_startedLoading = _failedToLoad = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Resource::attemptRequest() {
|
void Resource::attemptRequest() {
|
||||||
_startedLoading = true;
|
_startedLoading = true;
|
||||||
ResourceCache::attemptRequest(this);
|
ResourceCache::attemptRequest(this);
|
||||||
|
|
|
@ -47,6 +47,8 @@ public:
|
||||||
ResourceCache(QObject* parent = NULL);
|
ResourceCache(QObject* parent = NULL);
|
||||||
virtual ~ResourceCache();
|
virtual ~ResourceCache();
|
||||||
|
|
||||||
|
void refresh(const QUrl& url);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
QMap<int, QSharedPointer<Resource> > _unusedResources;
|
QMap<int, QSharedPointer<Resource> > _unusedResources;
|
||||||
|
@ -119,6 +121,9 @@ public:
|
||||||
/// For loading resources, returns the load progress.
|
/// For loading resources, returns the load progress.
|
||||||
float getProgress() const { return (_bytesTotal == 0) ? 0.0f : (float)_bytesReceived / _bytesTotal; }
|
float getProgress() const { return (_bytesTotal == 0) ? 0.0f : (float)_bytesReceived / _bytesTotal; }
|
||||||
|
|
||||||
|
/// Refreshes the resource.
|
||||||
|
void refresh();
|
||||||
|
|
||||||
void setSelf(const QWeakPointer<Resource>& self) { _self = self; }
|
void setSelf(const QWeakPointer<Resource>& self) { _self = self; }
|
||||||
|
|
||||||
void setCache(ResourceCache* cache) { _cache = cache; }
|
void setCache(ResourceCache* cache) { _cache = cache; }
|
||||||
|
@ -131,6 +136,8 @@ protected slots:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
virtual void init();
|
||||||
|
|
||||||
/// Called when the download has finished. The recipient should delete the reply when done with it.
|
/// Called when the download has finished. The recipient should delete the reply when done with it.
|
||||||
virtual void downloadFinished(QNetworkReply* reply) = 0;
|
virtual void downloadFinished(QNetworkReply* reply) = 0;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue