mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-07-10 22:38:34 +02:00
Merge branch 'atp' of github.com:birarda/hifi into atp
This commit is contained in:
commit
2e9ee4f8a7
14 changed files with 743 additions and 456 deletions
|
@ -21,11 +21,12 @@
|
||||||
#include <QtCore/QJsonDocument>
|
#include <QtCore/QJsonDocument>
|
||||||
#include <QtCore/QString>
|
#include <QtCore/QString>
|
||||||
|
|
||||||
|
#include <ServerPathUtils.h>
|
||||||
|
|
||||||
#include "NetworkLogging.h"
|
#include "NetworkLogging.h"
|
||||||
#include "NodeType.h"
|
#include "NodeType.h"
|
||||||
#include "SendAssetTask.h"
|
#include "SendAssetTask.h"
|
||||||
#include "UploadAssetTask.h"
|
#include "UploadAssetTask.h"
|
||||||
#include <ServerPathUtils.h>
|
|
||||||
|
|
||||||
const QString ASSET_SERVER_LOGGING_TARGET_NAME = "asset-server";
|
const QString ASSET_SERVER_LOGGING_TARGET_NAME = "asset-server";
|
||||||
|
|
||||||
|
@ -203,6 +204,10 @@ void AssetServer::handleAssetMappingOperation(QSharedPointer<ReceivedMessage> me
|
||||||
handleDeleteMappingsOperation(*message, senderNode, *replyPacket);
|
handleDeleteMappingsOperation(*message, senderNode, *replyPacket);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case AssetMappingOperationType::Rename: {
|
||||||
|
handleRenameMappingOperation(*message, senderNode, *replyPacket);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto nodeList = DependencyManager::get<NodeList>();
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
|
@ -274,6 +279,21 @@ void AssetServer::handleDeleteMappingsOperation(ReceivedMessage& message, Shared
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AssetServer::handleRenameMappingOperation(ReceivedMessage& message, SharedNodePointer senderNode, NLPacketList& replyPacket) {
|
||||||
|
if (senderNode->getCanRez()) {
|
||||||
|
QString oldPath = message.readString();
|
||||||
|
QString newPath = message.readString();
|
||||||
|
|
||||||
|
if (renameMapping(oldPath, newPath)) {
|
||||||
|
replyPacket.writePrimitive(AssetServerError::NoError);
|
||||||
|
} else {
|
||||||
|
replyPacket.writePrimitive(AssetServerError::MappingOperationFailed);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
replyPacket.writePrimitive(AssetServerError::PermissionDenied);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void AssetServer::handleAssetGetInfo(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode) {
|
void AssetServer::handleAssetGetInfo(QSharedPointer<ReceivedMessage> message, SharedNodePointer senderNode) {
|
||||||
QByteArray assetHash;
|
QByteArray assetHash;
|
||||||
MessageID messageID;
|
MessageID messageID;
|
||||||
|
@ -468,7 +488,7 @@ bool AssetServer::writeMappingsToFile() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AssetServer::setMapping(AssetPath path, AssetHash hash) {
|
bool AssetServer::setMapping(const AssetPath& path, const AssetHash& hash) {
|
||||||
// remember what the old mapping was in case persistence fails
|
// remember what the old mapping was in case persistence fails
|
||||||
auto oldMapping = _fileMappings.value(path).toString();
|
auto oldMapping = _fileMappings.value(path).toString();
|
||||||
|
|
||||||
|
@ -516,3 +536,25 @@ bool AssetServer::deleteMappings(const AssetPathList& paths) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AssetServer::renameMapping(const AssetPath& oldPath, const AssetPath& newPath) {
|
||||||
|
// take the old hash to remove the old mapping
|
||||||
|
auto oldMapping = _fileMappings[oldPath].toString();
|
||||||
|
|
||||||
|
if (!oldMapping.isEmpty()) {
|
||||||
|
_fileMappings[newPath] = oldMapping;
|
||||||
|
|
||||||
|
if (writeMappingsToFile()) {
|
||||||
|
// persisted the renamed mapping, return success
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
// we couldn't persist the renamed mapping, rollback and return failure
|
||||||
|
_fileMappings[oldPath] = oldMapping;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// failed to find a mapping that was to be renamed, return failure
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -12,10 +12,10 @@
|
||||||
#ifndef hifi_AssetServer_h
|
#ifndef hifi_AssetServer_h
|
||||||
#define hifi_AssetServer_h
|
#define hifi_AssetServer_h
|
||||||
|
|
||||||
#include <QDir>
|
#include <QtCore/QDir>
|
||||||
|
#include <QtCore/QThreadPool>
|
||||||
|
|
||||||
#include <ThreadedAssignment.h>
|
#include <ThreadedAssignment.h>
|
||||||
#include <QThreadPool>
|
|
||||||
|
|
||||||
#include "AssetUtils.h"
|
#include "AssetUtils.h"
|
||||||
#include "ReceivedMessage.h"
|
#include "ReceivedMessage.h"
|
||||||
|
@ -45,18 +45,20 @@ private:
|
||||||
void handleGetAllMappingOperation(ReceivedMessage& message, SharedNodePointer senderNode, NLPacketList& replyPacket);
|
void handleGetAllMappingOperation(ReceivedMessage& message, SharedNodePointer senderNode, NLPacketList& replyPacket);
|
||||||
void handleSetMappingOperation(ReceivedMessage& message, SharedNodePointer senderNode, NLPacketList& replyPacket);
|
void handleSetMappingOperation(ReceivedMessage& message, SharedNodePointer senderNode, NLPacketList& replyPacket);
|
||||||
void handleDeleteMappingsOperation(ReceivedMessage& message, SharedNodePointer senderNode, NLPacketList& replyPacket);
|
void handleDeleteMappingsOperation(ReceivedMessage& message, SharedNodePointer senderNode, NLPacketList& replyPacket);
|
||||||
|
void handleRenameMappingOperation(ReceivedMessage& message, SharedNodePointer senderNode, NLPacketList& replyPacket);
|
||||||
|
|
||||||
// Mapping file operations must be called from main assignment thread only
|
// Mapping file operations must be called from main assignment thread only
|
||||||
void loadMappingsFromFile();
|
void loadMappingsFromFile();
|
||||||
bool writeMappingsToFile();
|
bool writeMappingsToFile();
|
||||||
|
|
||||||
/// Set the mapping for path to hash
|
/// Set the mapping for path to hash
|
||||||
bool setMapping(AssetPath path, AssetHash hash);
|
bool setMapping(const AssetPath& path, const AssetHash& hash);
|
||||||
|
|
||||||
/// Delete mapping `path`. Returns `true` if deletion of mappings succeeds, else `false`.
|
/// Delete mapping `path`. Returns `true` if deletion of mappings succeeds, else `false`.
|
||||||
bool deleteMappings(const AssetPathList& paths);
|
bool deleteMappings(const AssetPathList& paths);
|
||||||
|
|
||||||
static void writeError(NLPacketList* packetList, AssetServerError error);
|
/// Rename mapping from `oldPath` to `newPath`. Returns true if successful
|
||||||
|
bool renameMapping(const AssetPath& oldPath, const AssetPath& newPath);
|
||||||
|
|
||||||
void performMappingMigration();
|
void performMappingMigration();
|
||||||
|
|
||||||
|
@ -67,8 +69,4 @@ private:
|
||||||
QThreadPool _taskPool;
|
QThreadPool _taskPool;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline void writeError(NLPacketList* packetList, AssetServerError error) {
|
|
||||||
packetList->writePrimitive(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -56,7 +56,7 @@ void SendAssetTask::run() {
|
||||||
replyPacketList->writePrimitive(messageID);
|
replyPacketList->writePrimitive(messageID);
|
||||||
|
|
||||||
if (end <= start) {
|
if (end <= start) {
|
||||||
writeError(replyPacketList.get(), AssetServerError::InvalidByteRange);
|
replyPacketList->writePrimitive(AssetServerError::InvalidByteRange);
|
||||||
} else {
|
} else {
|
||||||
QString filePath = _resourcesDir.filePath(QString(hexHash));
|
QString filePath = _resourcesDir.filePath(QString(hexHash));
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ void SendAssetTask::run() {
|
||||||
|
|
||||||
if (file.open(QIODevice::ReadOnly)) {
|
if (file.open(QIODevice::ReadOnly)) {
|
||||||
if (file.size() < end) {
|
if (file.size() < end) {
|
||||||
writeError(replyPacketList.get(), AssetServerError::InvalidByteRange);
|
replyPacketList->writePrimitive(AssetServerError::InvalidByteRange);
|
||||||
qCDebug(networking) << "Bad byte range: " << hexHash << " " << start << ":" << end;
|
qCDebug(networking) << "Bad byte range: " << hexHash << " " << start << ":" << end;
|
||||||
} else {
|
} else {
|
||||||
auto size = end - start;
|
auto size = end - start;
|
||||||
|
@ -77,7 +77,7 @@ void SendAssetTask::run() {
|
||||||
file.close();
|
file.close();
|
||||||
} else {
|
} else {
|
||||||
qCDebug(networking) << "Asset not found: " << filePath << "(" << hexHash << ")";
|
qCDebug(networking) << "Asset not found: " << filePath << "(" << hexHash << ")";
|
||||||
writeError(replyPacketList.get(), AssetServerError::AssetNotFound);
|
replyPacketList->writePrimitive(AssetServerError::AssetNotFound);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ Window {
|
||||||
|
|
||||||
property var scripts: ScriptDiscoveryService;
|
property var scripts: ScriptDiscoveryService;
|
||||||
property var scriptsModel: scripts.scriptsModelFilter
|
property var scriptsModel: scripts.scriptsModelFilter
|
||||||
property var currentDirectory: ""
|
property var currentDirectory;
|
||||||
|
|
||||||
Settings {
|
Settings {
|
||||||
category: "Overlay.AssetServer"
|
category: "Overlay.AssetServer"
|
||||||
|
@ -43,29 +43,96 @@ Window {
|
||||||
property alias directory: root.currentDirectory
|
property alias directory: root.currentDirectory
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function reload() {
|
function reload() {
|
||||||
print("reload");
|
print("reload");
|
||||||
}
|
}
|
||||||
|
function addToWorld() {
|
||||||
function goBack() {
|
print("addToWorld");
|
||||||
print("goBack");
|
|
||||||
}
|
}
|
||||||
|
function renameFile() {
|
||||||
|
var path = scriptsModel.data(treeView.currentIndex, 0x100);
|
||||||
|
if (!path) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
function uploadFile(fileUrl, addToScene) {
|
var object = desktop.inputDialog({
|
||||||
print("uploadFile: " + fileUrl + " " + addToScene);
|
label: "Enter new path:",
|
||||||
|
prefilledText: path,
|
||||||
|
placeholderText: "Enter path here"
|
||||||
|
});
|
||||||
|
object.selected.connect(function(destinationPath) {
|
||||||
|
console.log("Renaming " + path + " to " + destinationPath);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function deleteFile() {
|
function deleteFile() {
|
||||||
print("deleteFile");
|
var path = scriptsModel.data(treeView.currentIndex, 0x100);
|
||||||
|
if (!path) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var object = desktop.messageBox({
|
||||||
|
icon: OriginalDialogs.StandardIcon.Question,
|
||||||
|
buttons: OriginalDialogs.StandardButton.Yes | OriginalDialogs.StandardButton.No,
|
||||||
|
defaultButton: OriginalDialogs.StandardButton.No,
|
||||||
|
text: "Deleting",
|
||||||
|
informativeText: "You are about to delete the following file:\n" +
|
||||||
|
path +
|
||||||
|
"\nDo you want to continue?"
|
||||||
|
});
|
||||||
|
object.selected.connect(function(button) {
|
||||||
|
if (button === OriginalDialogs.StandardButton.Yes) {
|
||||||
|
console.log("Deleting " + path);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function chooseClicked() {
|
||||||
|
var browser = desktop.fileDialog({
|
||||||
|
selectDirectory: false,
|
||||||
|
dir: currentDirectory
|
||||||
|
});
|
||||||
|
browser.selectedFile.connect(function(url){
|
||||||
|
fileUrlTextField.text = fileDialogHelper.urlToPath(url);
|
||||||
|
currentDirectory = browser.dir;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function uploadClicked() {
|
||||||
|
var fileUrl = fileUrlTextField.text
|
||||||
|
var addToWorld = addToWorldCheckBox.checked
|
||||||
|
|
||||||
|
var path = scriptsModel.data(treeView.currentIndex, 0x100);
|
||||||
|
var directory = path ? path.slice(0, path.lastIndexOf('/') + 1) : "";
|
||||||
|
var filename = fileUrl.slice(fileUrl.lastIndexOf('/') + 1);
|
||||||
|
|
||||||
|
var object = desktop.inputDialog({
|
||||||
|
label: "Enter asset path:",
|
||||||
|
prefilledText: directory + filename,
|
||||||
|
placeholderText: "Enter path here"
|
||||||
|
});
|
||||||
|
object.selected.connect(function(destinationPath) {
|
||||||
|
console.log("Uploading " + fileUrl + " to " + destinationPath + " (addToWorld: " + addToWorld + ")");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
width: pane.contentWidth
|
width: pane.contentWidth
|
||||||
|
|
||||||
HifiControls.ContentSection {
|
HifiControls.ContentSection {
|
||||||
|
id: assetDirectory
|
||||||
name: "Asset Directory"
|
name: "Asset Directory"
|
||||||
spacing: hifi.dimensions.contentSpacing.y
|
spacing: hifi.dimensions.contentSpacing.y
|
||||||
isFirst: true
|
isFirst: true
|
||||||
|
@ -76,16 +143,6 @@ Window {
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
spacing: hifi.dimensions.contentSpacing.x
|
spacing: hifi.dimensions.contentSpacing.x
|
||||||
|
|
||||||
HifiControls.GlyphButton {
|
|
||||||
glyph: hifi.glyphs.back
|
|
||||||
color: hifi.buttons.white
|
|
||||||
colorScheme: root.colorScheme
|
|
||||||
height: 26
|
|
||||||
width: 26
|
|
||||||
|
|
||||||
onClicked: root.goBack()
|
|
||||||
}
|
|
||||||
|
|
||||||
HifiControls.GlyphButton {
|
HifiControls.GlyphButton {
|
||||||
glyph: hifi.glyphs.reload
|
glyph: hifi.glyphs.reload
|
||||||
color: hifi.buttons.white
|
color: hifi.buttons.white
|
||||||
|
@ -95,23 +152,35 @@ Window {
|
||||||
|
|
||||||
onClicked: root.reload()
|
onClicked: root.reload()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
HifiControls.Button {
|
||||||
// Take the deleteButotn out of the column flow.
|
text: "ADD TO WORLD"
|
||||||
id: deleteButtonContainer
|
color: hifi.buttons.white
|
||||||
anchors.top: buttonRow.top
|
colorScheme: root.colorScheme
|
||||||
anchors.right: parent.right
|
height: 26
|
||||||
|
width: 120
|
||||||
|
|
||||||
|
onClicked: root.addToWorld()
|
||||||
|
}
|
||||||
|
|
||||||
|
HifiControls.Button {
|
||||||
|
text: "RENAME"
|
||||||
|
color: hifi.buttons.white
|
||||||
|
colorScheme: root.colorScheme
|
||||||
|
height: 26
|
||||||
|
width: 80
|
||||||
|
|
||||||
|
onClicked: root.renameFile()
|
||||||
|
}
|
||||||
|
|
||||||
HifiControls.Button {
|
HifiControls.Button {
|
||||||
id: deleteButton
|
id: deleteButton
|
||||||
anchors.right: parent.right
|
|
||||||
|
|
||||||
text: "DELETE SELECTION"
|
text: "DELETE"
|
||||||
color: hifi.buttons.red
|
color: hifi.buttons.red
|
||||||
colorScheme: root.colorScheme
|
colorScheme: root.colorScheme
|
||||||
height: 26
|
height: 26
|
||||||
width: 130
|
width: 80
|
||||||
|
|
||||||
onClicked: root.deleteFile()
|
onClicked: root.deleteFile()
|
||||||
}
|
}
|
||||||
|
@ -119,7 +188,7 @@ Window {
|
||||||
|
|
||||||
HifiControls.Tree {
|
HifiControls.Tree {
|
||||||
id: treeView
|
id: treeView
|
||||||
height: 250
|
height: 400
|
||||||
treeModel: scriptsModel
|
treeModel: scriptsModel
|
||||||
colorScheme: root.colorScheme
|
colorScheme: root.colorScheme
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
|
@ -128,16 +197,12 @@ Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
HifiControls.ContentSection {
|
HifiControls.ContentSection {
|
||||||
|
id: uploadSection
|
||||||
name: ""
|
name: ""
|
||||||
spacing: hifi.dimensions.contentSpacing.y
|
spacing: hifi.dimensions.contentSpacing.y
|
||||||
|
|
||||||
Component {
|
|
||||||
id: fileBrowserBuilder;
|
|
||||||
FileDialog { selectDirectory: true }
|
|
||||||
}
|
|
||||||
|
|
||||||
HifiControls.TextField {
|
HifiControls.TextField {
|
||||||
id: fileUrl
|
id: fileUrlTextField
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.rightMargin: chooseButton.width + hifi.dimensions.contentSpacing.x
|
anchors.rightMargin: chooseButton.width + hifi.dimensions.contentSpacing.x
|
||||||
|
@ -150,7 +215,7 @@ Window {
|
||||||
Item {
|
Item {
|
||||||
// Take the chooseButton out of the column flow.
|
// Take the chooseButton out of the column flow.
|
||||||
id: chooseButtonContainer
|
id: chooseButtonContainer
|
||||||
anchors.top: fileUrl.top
|
anchors.top: fileUrlTextField.top
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
|
|
||||||
HifiControls.Button {
|
HifiControls.Button {
|
||||||
|
@ -164,33 +229,24 @@ Window {
|
||||||
|
|
||||||
width: 100
|
width: 100
|
||||||
|
|
||||||
onClicked: {
|
onClicked: root.chooseClicked()
|
||||||
var browser = fileBrowserBuilder.createObject(desktop, {
|
|
||||||
selectDirectory: true,
|
|
||||||
folder: fileDialogHelper.pathToUrl(currentDirectory)
|
|
||||||
});
|
|
||||||
browser.selectedFile.connect(function(url){
|
|
||||||
console.log(url);
|
|
||||||
fileUrl.text = fileDialogHelper.urlToPath(url);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HifiControls.CheckBox {
|
HifiControls.CheckBox {
|
||||||
id: addToScene
|
id: addToWorldCheckBox
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.rightMargin: uploadButton.width + hifi.dimensions.contentSpacing.x
|
anchors.rightMargin: uploadButton.width + hifi.dimensions.contentSpacing.x
|
||||||
|
|
||||||
text: "Add to scene on upload"
|
text: "Add to world on upload"
|
||||||
checked: false
|
checked: false
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
// Take the uploadButton out of the column flow.
|
// Take the uploadButton out of the column flow.
|
||||||
id: uploadButtonContainer
|
id: uploadButtonContainer
|
||||||
anchors.top: addToScene.top
|
anchors.top: addToWorldCheckBox.top
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
|
|
||||||
HifiControls.Button {
|
HifiControls.Button {
|
||||||
|
@ -203,10 +259,12 @@ Window {
|
||||||
height: 30
|
height: 30
|
||||||
width: 155
|
width: 155
|
||||||
|
|
||||||
enabled: fileUrl.text != ""
|
enabled: fileUrlTextField.text != ""
|
||||||
onClicked: root.uploadFile(fileUrl.text, addToScene.checked)
|
onClicked: root.uploadClicked()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HifiControls.VerticalSpacer {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,6 +39,7 @@ ModalWindow {
|
||||||
|
|
||||||
// For text boxes
|
// For text boxes
|
||||||
property alias placeholderText: textResult.placeholderText
|
property alias placeholderText: textResult.placeholderText
|
||||||
|
property alias prefilledText: textResult.text
|
||||||
|
|
||||||
// For combo boxes
|
// For combo boxes
|
||||||
property bool editable: true;
|
property bool editable: true;
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "AssetRequest.h"
|
#include "AssetRequest.h"
|
||||||
#include "AssetUpload.h"
|
#include "AssetUpload.h"
|
||||||
#include "AssetUtils.h"
|
#include "AssetUtils.h"
|
||||||
|
#include "MappingRequest.h"
|
||||||
#include "NetworkAccessManager.h"
|
#include "NetworkAccessManager.h"
|
||||||
#include "NetworkLogging.h"
|
#include "NetworkLogging.h"
|
||||||
#include "NodeList.h"
|
#include "NodeList.h"
|
||||||
|
@ -30,151 +31,6 @@
|
||||||
|
|
||||||
MessageID AssetClient::_currentID = 0;
|
MessageID AssetClient::_currentID = 0;
|
||||||
|
|
||||||
void MappingRequest::start() {
|
|
||||||
if (QThread::currentThread() != thread()) {
|
|
||||||
QMetaObject::invokeMethod(this, "start", Qt::AutoConnection);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
doStart();
|
|
||||||
};
|
|
||||||
|
|
||||||
GetMappingRequest::GetMappingRequest(const AssetPath& path) : _path(path) {
|
|
||||||
};
|
|
||||||
|
|
||||||
void GetMappingRequest::doStart() {
|
|
||||||
|
|
||||||
auto assetClient = DependencyManager::get<AssetClient>();
|
|
||||||
|
|
||||||
// Check cache
|
|
||||||
auto it = assetClient->_mappingCache.constFind(_path);
|
|
||||||
if (it != assetClient->_mappingCache.constEnd()) {
|
|
||||||
_hash = it.value();
|
|
||||||
emit finished(this);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
assetClient->getAssetMapping(_path, [this, assetClient](bool responseReceived, AssetServerError error, QSharedPointer<ReceivedMessage> message) {
|
|
||||||
if (!responseReceived) {
|
|
||||||
_error = NetworkError;
|
|
||||||
} else {
|
|
||||||
switch (error) {
|
|
||||||
case AssetServerError::NoError:
|
|
||||||
_error = NoError;
|
|
||||||
break;
|
|
||||||
case AssetServerError::AssetNotFound:
|
|
||||||
_error = NotFound;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
_error = UnknownError;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_error) {
|
|
||||||
_hash = message->read(SHA256_HASH_LENGTH).toHex();
|
|
||||||
assetClient->_mappingCache[_path] = _hash;
|
|
||||||
}
|
|
||||||
emit finished(this);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
GetAllMappingsRequest::GetAllMappingsRequest() {
|
|
||||||
};
|
|
||||||
|
|
||||||
void GetAllMappingsRequest::doStart() {
|
|
||||||
auto assetClient = DependencyManager::get<AssetClient>();
|
|
||||||
assetClient->getAllAssetMappings([this, assetClient](bool responseReceived, AssetServerError error, QSharedPointer<ReceivedMessage> message) {
|
|
||||||
if (!responseReceived) {
|
|
||||||
_error = NetworkError;
|
|
||||||
} else {
|
|
||||||
switch (error) {
|
|
||||||
case AssetServerError::NoError:
|
|
||||||
_error = NoError;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
_error = UnknownError;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (!error) {
|
|
||||||
int numberOfMappings;
|
|
||||||
message->readPrimitive(&numberOfMappings);
|
|
||||||
assetClient->_mappingCache.clear();
|
|
||||||
for (auto i = 0; i < numberOfMappings; ++i) {
|
|
||||||
auto path = message->readString();
|
|
||||||
auto hash = message->readString();
|
|
||||||
_mappings[path] = hash;
|
|
||||||
assetClient->_mappingCache[path] = hash;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
emit finished(this);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
SetMappingRequest::SetMappingRequest(const AssetPath& path, const AssetHash& hash) : _path(path), _hash(hash) {
|
|
||||||
};
|
|
||||||
|
|
||||||
void SetMappingRequest::doStart() {
|
|
||||||
auto assetClient = DependencyManager::get<AssetClient>();
|
|
||||||
assetClient->setAssetMapping(_path, _hash, [this, assetClient](bool responseReceived, AssetServerError error, QSharedPointer<ReceivedMessage> message) {
|
|
||||||
if (!responseReceived) {
|
|
||||||
_error = NetworkError;
|
|
||||||
} else {
|
|
||||||
switch (error) {
|
|
||||||
case AssetServerError::NoError:
|
|
||||||
_error = NoError;
|
|
||||||
break;
|
|
||||||
case AssetServerError::PermissionDenied:
|
|
||||||
_error = PermissionDenied;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
_error = UnknownError;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!error) {
|
|
||||||
assetClient->_mappingCache[_path] = _hash;
|
|
||||||
}
|
|
||||||
emit finished(this);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
DeleteMappingsRequest::DeleteMappingsRequest(const AssetPathList& paths) : _paths(paths) {
|
|
||||||
};
|
|
||||||
|
|
||||||
void DeleteMappingsRequest::doStart() {
|
|
||||||
auto assetClient = DependencyManager::get<AssetClient>();
|
|
||||||
assetClient->deleteAssetMappings(_paths, [this, assetClient](bool responseReceived, AssetServerError error, QSharedPointer<ReceivedMessage> message) {
|
|
||||||
if (!responseReceived) {
|
|
||||||
_error = NetworkError;
|
|
||||||
} else {
|
|
||||||
switch (error) {
|
|
||||||
case AssetServerError::NoError:
|
|
||||||
_error = NoError;
|
|
||||||
break;
|
|
||||||
case AssetServerError::PermissionDenied:
|
|
||||||
_error = PermissionDenied;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
_error = UnknownError;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!error) {
|
|
||||||
// enumerate the paths and remove them from the cache
|
|
||||||
for (auto& path : _paths) {
|
|
||||||
assetClient->_mappingCache.remove(path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
emit finished(this);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
AssetClient::AssetClient() {
|
AssetClient::AssetClient() {
|
||||||
|
|
||||||
setCustomDeleter([](Dependency* dependency){
|
setCustomDeleter([](Dependency* dependency){
|
||||||
|
@ -300,6 +156,10 @@ SetMappingRequest* AssetClient::createSetMappingRequest(const AssetPath& path, c
|
||||||
return new SetMappingRequest(path, hash);
|
return new SetMappingRequest(path, hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RenameMappingRequest* AssetClient::createRenameMappingRequest(const AssetPath& oldPath, const AssetPath& newPath) {
|
||||||
|
return new RenameMappingRequest(oldPath, newPath);
|
||||||
|
}
|
||||||
|
|
||||||
AssetRequest* AssetClient::createRequest(const AssetHash& hash) {
|
AssetRequest* AssetClient::createRequest(const AssetHash& hash) {
|
||||||
if (hash.length() != SHA256_HASH_HEX_LENGTH) {
|
if (hash.length() != SHA256_HASH_HEX_LENGTH) {
|
||||||
qCWarning(asset_client) << "Invalid hash size";
|
qCWarning(asset_client) << "Invalid hash size";
|
||||||
|
@ -573,7 +433,7 @@ bool AssetClient::setAssetMapping(const QString& path, const AssetHash& hash, Ma
|
||||||
|
|
||||||
packetList->writePrimitive(AssetMappingOperationType::Set);
|
packetList->writePrimitive(AssetMappingOperationType::Set);
|
||||||
|
|
||||||
packetList->writeString(path.toUtf8());
|
packetList->writeString(path);
|
||||||
packetList->write(QByteArray::fromHex(hash.toUtf8()));
|
packetList->write(QByteArray::fromHex(hash.toUtf8()));
|
||||||
|
|
||||||
nodeList->sendPacketList(std::move(packetList), *assetServer);
|
nodeList->sendPacketList(std::move(packetList), *assetServer);
|
||||||
|
@ -586,6 +446,32 @@ bool AssetClient::setAssetMapping(const QString& path, const AssetHash& hash, Ma
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AssetClient::renameAssetMapping(const AssetPath& oldPath, const AssetPath& newPath, MappingOperationCallback callback) {
|
||||||
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
|
SharedNodePointer assetServer = nodeList->soloNodeOfType(NodeType::AssetServer);
|
||||||
|
|
||||||
|
if (assetServer) {
|
||||||
|
auto packetList = NLPacketList::create(PacketType::AssetMappingOperation, QByteArray(), true, true);
|
||||||
|
|
||||||
|
auto messageID = ++_currentID;
|
||||||
|
packetList->writePrimitive(messageID);
|
||||||
|
|
||||||
|
packetList->writePrimitive(AssetMappingOperationType::Rename);
|
||||||
|
|
||||||
|
packetList->writeString(oldPath);
|
||||||
|
packetList->writeString(newPath);
|
||||||
|
|
||||||
|
nodeList->sendPacketList(std::move(packetList), *assetServer);
|
||||||
|
|
||||||
|
_pendingMappingRequests[assetServer][messageID] = callback;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool AssetClient::uploadAsset(const QByteArray& data, UploadResultCallback callback) {
|
bool AssetClient::uploadAsset(const QByteArray& data, UploadResultCallback callback) {
|
||||||
auto nodeList = DependencyManager::get<NodeList>();
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
SharedNodePointer assetServer = nodeList->soloNodeOfType(NodeType::AssetServer);
|
SharedNodePointer assetServer = nodeList->soloNodeOfType(NodeType::AssetServer);
|
||||||
|
@ -695,140 +581,3 @@ void AssetClient::handleNodeKilled(SharedNodePointer node) {
|
||||||
|
|
||||||
_mappingCache.clear();
|
_mappingCache.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssetScriptingInterface::uploadData(QString data, QScriptValue callback) {
|
|
||||||
QByteArray dataByteArray = data.toUtf8();
|
|
||||||
auto upload = DependencyManager::get<AssetClient>()->createUpload(dataByteArray);
|
|
||||||
if (!upload) {
|
|
||||||
qCWarning(asset_client) << "Error uploading file to asset server";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QObject::connect(upload, &AssetUpload::finished, this, [this, callback](AssetUpload* upload, const QString& hash) mutable {
|
|
||||||
if (callback.isFunction()) {
|
|
||||||
QString url = "atp://" + hash;
|
|
||||||
QScriptValueList args { url };
|
|
||||||
callback.call(_engine->currentContext()->thisObject(), args);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
upload->start();
|
|
||||||
}
|
|
||||||
|
|
||||||
AssetScriptingInterface::AssetScriptingInterface(QScriptEngine* engine) :
|
|
||||||
_engine(engine)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void AssetScriptingInterface::downloadData(QString urlString, QScriptValue callback) {
|
|
||||||
const QString ATP_SCHEME { "atp://" };
|
|
||||||
|
|
||||||
if (!urlString.startsWith(ATP_SCHEME)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make request to atp
|
|
||||||
auto path = urlString.right(urlString.length() - ATP_SCHEME.length());
|
|
||||||
auto parts = path.split(".", QString::SkipEmptyParts);
|
|
||||||
auto hash = parts.length() > 0 ? parts[0] : "";
|
|
||||||
|
|
||||||
if (hash.length() != SHA256_HASH_HEX_LENGTH) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto assetClient = DependencyManager::get<AssetClient>();
|
|
||||||
auto assetRequest = assetClient->createRequest(hash);
|
|
||||||
|
|
||||||
if (!assetRequest) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_pendingRequests << assetRequest;
|
|
||||||
|
|
||||||
connect(assetRequest, &AssetRequest::finished, this, [this, callback](AssetRequest* request) mutable {
|
|
||||||
Q_ASSERT(request->getState() == AssetRequest::Finished);
|
|
||||||
|
|
||||||
if (request->getError() == AssetRequest::Error::NoError) {
|
|
||||||
if (callback.isFunction()) {
|
|
||||||
QString data = QString::fromUtf8(request->getData());
|
|
||||||
QScriptValueList args { data };
|
|
||||||
callback.call(_engine->currentContext()->thisObject(), args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
request->deleteLater();
|
|
||||||
_pendingRequests.remove(request);
|
|
||||||
});
|
|
||||||
|
|
||||||
assetRequest->start();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AssetScriptingInterface::setMapping(QString path, QString hash, QScriptValue callback) {
|
|
||||||
auto assetClient = DependencyManager::get<AssetClient>();
|
|
||||||
auto request = assetClient->createSetMappingRequest(path, hash);
|
|
||||||
|
|
||||||
connect(request, &SetMappingRequest::finished, this, [this, callback](SetMappingRequest* request) mutable {
|
|
||||||
QScriptValueList args { uint8_t(request->getError()) };
|
|
||||||
|
|
||||||
callback.call(_engine->currentContext()->thisObject(), args);
|
|
||||||
|
|
||||||
request->deleteLater();
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
request->start();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AssetScriptingInterface::getMapping(QString path, QScriptValue callback) {
|
|
||||||
auto assetClient = DependencyManager::get<AssetClient>();
|
|
||||||
auto request = assetClient->createGetMappingRequest(path);
|
|
||||||
|
|
||||||
connect(request, &GetMappingRequest::finished, this, [this, callback](GetMappingRequest* request) mutable {
|
|
||||||
QScriptValueList args { uint8_t(request->getError()), request->getHash() };
|
|
||||||
|
|
||||||
callback.call(_engine->currentContext()->thisObject(), args);
|
|
||||||
|
|
||||||
request->deleteLater();
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
request->start();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AssetScriptingInterface::deleteMappings(QStringList paths, QScriptValue callback) {
|
|
||||||
auto assetClient = DependencyManager::get<AssetClient>();
|
|
||||||
auto request = assetClient->createDeleteMappingsRequest(paths);
|
|
||||||
|
|
||||||
connect(request, &DeleteMappingsRequest::finished, this, [this, callback](DeleteMappingsRequest* request) mutable {
|
|
||||||
QScriptValueList args { uint8_t(request->getError()) };
|
|
||||||
|
|
||||||
callback.call(_engine->currentContext()->thisObject(), args);
|
|
||||||
|
|
||||||
request->deleteLater();
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
request->start();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AssetScriptingInterface::getAllMappings(QScriptValue callback) {
|
|
||||||
auto assetClient = DependencyManager::get<AssetClient>();
|
|
||||||
auto request = assetClient->createGetAllMappingsRequest();
|
|
||||||
|
|
||||||
connect(request, &GetAllMappingsRequest::finished, this, [this, callback](GetAllMappingsRequest* request) mutable {
|
|
||||||
auto mappings = request->getMappings();
|
|
||||||
auto map = callback.engine()->newObject();
|
|
||||||
|
|
||||||
for (auto& kv : mappings ) {
|
|
||||||
map.setProperty(kv.first, kv.second);
|
|
||||||
}
|
|
||||||
|
|
||||||
QScriptValueList args { uint8_t(request->getError()), map };
|
|
||||||
|
|
||||||
callback.call(_engine->currentContext()->thisObject(), args);
|
|
||||||
|
|
||||||
request->deleteLater();
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
request->start();
|
|
||||||
}
|
|
||||||
|
|
|
@ -9,12 +9,10 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
||||||
#ifndef hifi_AssetClient_h
|
#ifndef hifi_AssetClient_h
|
||||||
#define hifi_AssetClient_h
|
#define hifi_AssetClient_h
|
||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QScriptValue>
|
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
@ -29,6 +27,9 @@
|
||||||
|
|
||||||
class GetMappingRequest;
|
class GetMappingRequest;
|
||||||
class SetMappingRequest;
|
class SetMappingRequest;
|
||||||
|
class GetAllMappingsRequest;
|
||||||
|
class DeleteMappingsRequest;
|
||||||
|
class RenameMappingRequest;
|
||||||
class AssetRequest;
|
class AssetRequest;
|
||||||
class AssetUpload;
|
class AssetUpload;
|
||||||
|
|
||||||
|
@ -43,92 +44,6 @@ using GetInfoCallback = std::function<void(bool responseReceived, AssetServerErr
|
||||||
using UploadResultCallback = std::function<void(bool responseReceived, AssetServerError serverError, const QString& hash)>;
|
using UploadResultCallback = std::function<void(bool responseReceived, AssetServerError serverError, const QString& hash)>;
|
||||||
using ProgressCallback = std::function<void(qint64 totalReceived, qint64 total)>;
|
using ProgressCallback = std::function<void(qint64 totalReceived, qint64 total)>;
|
||||||
|
|
||||||
class MappingRequest : public QObject {
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
enum Error {
|
|
||||||
NoError,
|
|
||||||
NotFound,
|
|
||||||
NetworkError,
|
|
||||||
PermissionDenied,
|
|
||||||
UnknownError
|
|
||||||
};
|
|
||||||
|
|
||||||
Q_INVOKABLE void start();
|
|
||||||
Error getError() const { return _error; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
Error _error { NoError };
|
|
||||||
|
|
||||||
private:
|
|
||||||
virtual void doStart() = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class GetMappingRequest : public MappingRequest {
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
GetMappingRequest(const AssetPath& path);
|
|
||||||
|
|
||||||
AssetHash getHash() const { return _hash; }
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void finished(GetMappingRequest* thisRequest);
|
|
||||||
|
|
||||||
private:
|
|
||||||
virtual void doStart() override;
|
|
||||||
|
|
||||||
AssetPath _path;
|
|
||||||
AssetHash _hash;
|
|
||||||
};
|
|
||||||
|
|
||||||
class SetMappingRequest : public MappingRequest {
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
SetMappingRequest(const AssetPath& path, const AssetHash& hash);
|
|
||||||
|
|
||||||
AssetHash getHash() const { return _hash; }
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void finished(SetMappingRequest* thisRequest);
|
|
||||||
|
|
||||||
private:
|
|
||||||
virtual void doStart() override;
|
|
||||||
|
|
||||||
AssetPath _path;
|
|
||||||
AssetHash _hash;
|
|
||||||
};
|
|
||||||
|
|
||||||
class DeleteMappingsRequest : public MappingRequest {
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
DeleteMappingsRequest(const AssetPathList& path);
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void finished(DeleteMappingsRequest* thisRequest);
|
|
||||||
|
|
||||||
private:
|
|
||||||
virtual void doStart() override;
|
|
||||||
|
|
||||||
AssetPathList _paths;
|
|
||||||
};
|
|
||||||
|
|
||||||
class GetAllMappingsRequest : public MappingRequest {
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
GetAllMappingsRequest();
|
|
||||||
|
|
||||||
AssetMapping getMappings() const { return _mappings; }
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void finished(GetAllMappingsRequest* thisRequest);
|
|
||||||
|
|
||||||
private:
|
|
||||||
virtual void doStart() override;
|
|
||||||
|
|
||||||
std::map<AssetPath, AssetHash> _mappings;
|
|
||||||
};
|
|
||||||
|
|
||||||
class AssetClient : public QObject, public Dependency {
|
class AssetClient : public QObject, public Dependency {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
@ -138,6 +53,7 @@ public:
|
||||||
Q_INVOKABLE GetAllMappingsRequest* createGetAllMappingsRequest();
|
Q_INVOKABLE GetAllMappingsRequest* createGetAllMappingsRequest();
|
||||||
Q_INVOKABLE DeleteMappingsRequest* createDeleteMappingsRequest(const AssetPathList& paths);
|
Q_INVOKABLE DeleteMappingsRequest* createDeleteMappingsRequest(const AssetPathList& paths);
|
||||||
Q_INVOKABLE SetMappingRequest* createSetMappingRequest(const AssetPath& path, const AssetHash& hash);
|
Q_INVOKABLE SetMappingRequest* createSetMappingRequest(const AssetPath& path, const AssetHash& hash);
|
||||||
|
Q_INVOKABLE RenameMappingRequest* createRenameMappingRequest(const AssetPath& oldPath, const AssetPath& newPath);
|
||||||
Q_INVOKABLE AssetRequest* createRequest(const AssetHash& hash);
|
Q_INVOKABLE AssetRequest* createRequest(const AssetHash& hash);
|
||||||
Q_INVOKABLE AssetUpload* createUpload(const QString& filename);
|
Q_INVOKABLE AssetUpload* createUpload(const QString& filename);
|
||||||
Q_INVOKABLE AssetUpload* createUpload(const QByteArray& data);
|
Q_INVOKABLE AssetUpload* createUpload(const QByteArray& data);
|
||||||
|
@ -161,6 +77,7 @@ private:
|
||||||
bool getAllAssetMappings(MappingOperationCallback callback);
|
bool getAllAssetMappings(MappingOperationCallback callback);
|
||||||
bool setAssetMapping(const QString& path, const AssetHash& hash, MappingOperationCallback callback);
|
bool setAssetMapping(const QString& path, const AssetHash& hash, MappingOperationCallback callback);
|
||||||
bool deleteAssetMappings(const AssetPathList& paths, MappingOperationCallback callback);
|
bool deleteAssetMappings(const AssetPathList& paths, MappingOperationCallback callback);
|
||||||
|
bool renameAssetMapping(const AssetPath& oldPath, const AssetPath& newPath, MappingOperationCallback callback);
|
||||||
|
|
||||||
bool getAssetInfo(const QString& hash, GetInfoCallback callback);
|
bool getAssetInfo(const QString& hash, GetInfoCallback callback);
|
||||||
bool getAsset(const QString& hash, DataOffset start, DataOffset end,
|
bool getAsset(const QString& hash, DataOffset start, DataOffset end,
|
||||||
|
@ -186,24 +103,7 @@ private:
|
||||||
friend class GetAllMappingsRequest;
|
friend class GetAllMappingsRequest;
|
||||||
friend class SetMappingRequest;
|
friend class SetMappingRequest;
|
||||||
friend class DeleteMappingsRequest;
|
friend class DeleteMappingsRequest;
|
||||||
|
friend class RenameMappingRequest;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class AssetScriptingInterface : public QObject {
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
AssetScriptingInterface(QScriptEngine* engine);
|
|
||||||
|
|
||||||
Q_INVOKABLE void uploadData(QString data, QScriptValue callback);
|
|
||||||
Q_INVOKABLE void downloadData(QString url, QScriptValue downloadComplete);
|
|
||||||
Q_INVOKABLE void setMapping(QString path, QString hash, QScriptValue callback);
|
|
||||||
Q_INVOKABLE void getMapping(QString path, QScriptValue callback);
|
|
||||||
Q_INVOKABLE void deleteMappings(QStringList paths, QScriptValue callback);
|
|
||||||
Q_INVOKABLE void getAllMappings(QScriptValue callback);
|
|
||||||
protected:
|
|
||||||
QSet<AssetRequest*> _pendingRequests;
|
|
||||||
QScriptEngine* _engine;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
#include "AssetClient.h"
|
#include "AssetClient.h"
|
||||||
#include "AssetUtils.h"
|
#include "AssetUtils.h"
|
||||||
|
#include "MappingRequest.h"
|
||||||
|
|
||||||
AssetResourceRequest::~AssetResourceRequest() {
|
AssetResourceRequest::~AssetResourceRequest() {
|
||||||
if (_assetMappingRequest) {
|
if (_assetMappingRequest) {
|
||||||
|
|
|
@ -44,7 +44,8 @@ enum AssetMappingOperationType : uint8_t {
|
||||||
Get = 0,
|
Get = 0,
|
||||||
GetAll,
|
GetAll,
|
||||||
Set,
|
Set,
|
||||||
Delete
|
Delete,
|
||||||
|
Rename
|
||||||
};
|
};
|
||||||
|
|
||||||
QUrl getATPUrl(const QString& hash);
|
QUrl getATPUrl(const QString& hash);
|
||||||
|
|
202
libraries/networking/src/MappingRequest.cpp
Normal file
202
libraries/networking/src/MappingRequest.cpp
Normal file
|
@ -0,0 +1,202 @@
|
||||||
|
//
|
||||||
|
// MappingRequest.cpp
|
||||||
|
// libraries/networking/src
|
||||||
|
//
|
||||||
|
// Created by Stephen Birarda on 2016-03-08.
|
||||||
|
// Copyright 2016 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "MappingRequest.h"
|
||||||
|
|
||||||
|
#include <QtCore/QThread>
|
||||||
|
|
||||||
|
#include <DependencyManager.h>
|
||||||
|
|
||||||
|
#include "AssetClient.h"
|
||||||
|
|
||||||
|
void MappingRequest::start() {
|
||||||
|
if (QThread::currentThread() != thread()) {
|
||||||
|
QMetaObject::invokeMethod(this, "start", Qt::AutoConnection);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
doStart();
|
||||||
|
};
|
||||||
|
|
||||||
|
GetMappingRequest::GetMappingRequest(const AssetPath& path) : _path(path) {
|
||||||
|
};
|
||||||
|
|
||||||
|
void GetMappingRequest::doStart() {
|
||||||
|
|
||||||
|
auto assetClient = DependencyManager::get<AssetClient>();
|
||||||
|
|
||||||
|
// Check cache
|
||||||
|
auto it = assetClient->_mappingCache.constFind(_path);
|
||||||
|
if (it != assetClient->_mappingCache.constEnd()) {
|
||||||
|
_hash = it.value();
|
||||||
|
emit finished(this);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
assetClient->getAssetMapping(_path, [this, assetClient](bool responseReceived, AssetServerError error, QSharedPointer<ReceivedMessage> message) {
|
||||||
|
if (!responseReceived) {
|
||||||
|
_error = NetworkError;
|
||||||
|
} else {
|
||||||
|
switch (error) {
|
||||||
|
case AssetServerError::NoError:
|
||||||
|
_error = NoError;
|
||||||
|
break;
|
||||||
|
case AssetServerError::AssetNotFound:
|
||||||
|
_error = NotFound;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
_error = UnknownError;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_error) {
|
||||||
|
_hash = message->read(SHA256_HASH_LENGTH).toHex();
|
||||||
|
assetClient->_mappingCache[_path] = _hash;
|
||||||
|
}
|
||||||
|
emit finished(this);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
GetAllMappingsRequest::GetAllMappingsRequest() {
|
||||||
|
};
|
||||||
|
|
||||||
|
void GetAllMappingsRequest::doStart() {
|
||||||
|
auto assetClient = DependencyManager::get<AssetClient>();
|
||||||
|
assetClient->getAllAssetMappings([this, assetClient](bool responseReceived, AssetServerError error, QSharedPointer<ReceivedMessage> message) {
|
||||||
|
if (!responseReceived) {
|
||||||
|
_error = NetworkError;
|
||||||
|
} else {
|
||||||
|
switch (error) {
|
||||||
|
case AssetServerError::NoError:
|
||||||
|
_error = NoError;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
_error = UnknownError;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (!error) {
|
||||||
|
int numberOfMappings;
|
||||||
|
message->readPrimitive(&numberOfMappings);
|
||||||
|
assetClient->_mappingCache.clear();
|
||||||
|
for (auto i = 0; i < numberOfMappings; ++i) {
|
||||||
|
auto path = message->readString();
|
||||||
|
auto hash = message->readString();
|
||||||
|
_mappings[path] = hash;
|
||||||
|
assetClient->_mappingCache[path] = hash;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
emit finished(this);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
SetMappingRequest::SetMappingRequest(const AssetPath& path, const AssetHash& hash) : _path(path), _hash(hash) {
|
||||||
|
};
|
||||||
|
|
||||||
|
void SetMappingRequest::doStart() {
|
||||||
|
auto assetClient = DependencyManager::get<AssetClient>();
|
||||||
|
assetClient->setAssetMapping(_path, _hash, [this, assetClient](bool responseReceived, AssetServerError error, QSharedPointer<ReceivedMessage> message) {
|
||||||
|
if (!responseReceived) {
|
||||||
|
_error = NetworkError;
|
||||||
|
} else {
|
||||||
|
switch (error) {
|
||||||
|
case AssetServerError::NoError:
|
||||||
|
_error = NoError;
|
||||||
|
break;
|
||||||
|
case AssetServerError::PermissionDenied:
|
||||||
|
_error = PermissionDenied;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
_error = UnknownError;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!error) {
|
||||||
|
assetClient->_mappingCache[_path] = _hash;
|
||||||
|
}
|
||||||
|
emit finished(this);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
DeleteMappingsRequest::DeleteMappingsRequest(const AssetPathList& paths) : _paths(paths) {
|
||||||
|
};
|
||||||
|
|
||||||
|
void DeleteMappingsRequest::doStart() {
|
||||||
|
auto assetClient = DependencyManager::get<AssetClient>();
|
||||||
|
assetClient->deleteAssetMappings(_paths, [this, assetClient](bool responseReceived, AssetServerError error, QSharedPointer<ReceivedMessage> message) {
|
||||||
|
if (!responseReceived) {
|
||||||
|
_error = NetworkError;
|
||||||
|
} else {
|
||||||
|
switch (error) {
|
||||||
|
case AssetServerError::NoError:
|
||||||
|
_error = NoError;
|
||||||
|
break;
|
||||||
|
case AssetServerError::PermissionDenied:
|
||||||
|
_error = PermissionDenied;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
_error = UnknownError;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!error) {
|
||||||
|
// enumerate the paths and remove them from the cache
|
||||||
|
for (auto& path : _paths) {
|
||||||
|
assetClient->_mappingCache.remove(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
emit finished(this);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
RenameMappingRequest::RenameMappingRequest(const AssetPath& oldPath, const AssetPath& newPath) :
|
||||||
|
_oldPath(oldPath),
|
||||||
|
_newPath(newPath)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenameMappingRequest::doStart() {
|
||||||
|
auto assetClient = DependencyManager::get<AssetClient>();
|
||||||
|
assetClient->renameAssetMapping(_oldPath, _newPath, [this, assetClient](bool responseReceived,
|
||||||
|
AssetServerError error,
|
||||||
|
QSharedPointer<ReceivedMessage> message) {
|
||||||
|
if (!responseReceived) {
|
||||||
|
_error = NetworkError;
|
||||||
|
} else {
|
||||||
|
switch (error) {
|
||||||
|
case AssetServerError::NoError:
|
||||||
|
_error = NoError;
|
||||||
|
break;
|
||||||
|
case AssetServerError::PermissionDenied:
|
||||||
|
_error = PermissionDenied;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
_error = UnknownError;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!error) {
|
||||||
|
// take the hash mapped for the old path from the cache
|
||||||
|
auto hash = assetClient->_mappingCache.take(_oldPath);
|
||||||
|
if (!hash.isEmpty()) {
|
||||||
|
// use the hash mapped for the old path for the new path
|
||||||
|
assetClient->_mappingCache[_newPath] = hash;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
emit finished(this);
|
||||||
|
});
|
||||||
|
}
|
123
libraries/networking/src/MappingRequest.h
Normal file
123
libraries/networking/src/MappingRequest.h
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
//
|
||||||
|
// MappingRequest.h
|
||||||
|
// libraries/networking/src
|
||||||
|
//
|
||||||
|
// Created by Stephen Birarda on 2016-03-08.
|
||||||
|
// Copyright 2016 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef hifi_MappingRequest_h
|
||||||
|
#define hifi_MappingRequest_h
|
||||||
|
|
||||||
|
#include <QtCore/QObject>
|
||||||
|
|
||||||
|
#include "AssetUtils.h"
|
||||||
|
|
||||||
|
class MappingRequest : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
enum Error {
|
||||||
|
NoError,
|
||||||
|
NotFound,
|
||||||
|
NetworkError,
|
||||||
|
PermissionDenied,
|
||||||
|
UnknownError
|
||||||
|
};
|
||||||
|
|
||||||
|
Q_INVOKABLE void start();
|
||||||
|
Error getError() const { return _error; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Error _error { NoError };
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual void doStart() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class GetMappingRequest : public MappingRequest {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
GetMappingRequest(const AssetPath& path);
|
||||||
|
|
||||||
|
AssetHash getHash() const { return _hash; }
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void finished(GetMappingRequest* thisRequest);
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual void doStart() override;
|
||||||
|
|
||||||
|
AssetPath _path;
|
||||||
|
AssetHash _hash;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SetMappingRequest : public MappingRequest {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
SetMappingRequest(const AssetPath& path, const AssetHash& hash);
|
||||||
|
|
||||||
|
AssetHash getHash() const { return _hash; }
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void finished(SetMappingRequest* thisRequest);
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual void doStart() override;
|
||||||
|
|
||||||
|
AssetPath _path;
|
||||||
|
AssetHash _hash;
|
||||||
|
};
|
||||||
|
|
||||||
|
class DeleteMappingsRequest : public MappingRequest {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
DeleteMappingsRequest(const AssetPathList& path);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void finished(DeleteMappingsRequest* thisRequest);
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual void doStart() override;
|
||||||
|
|
||||||
|
AssetPathList _paths;
|
||||||
|
};
|
||||||
|
|
||||||
|
class RenameMappingRequest : public MappingRequest {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
RenameMappingRequest(const AssetPath& oldPath, const AssetPath& newPath);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void finished(RenameMappingRequest* thisRequest);
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual void doStart() override;
|
||||||
|
|
||||||
|
AssetPath _oldPath;
|
||||||
|
AssetPath _newPath;
|
||||||
|
};
|
||||||
|
|
||||||
|
class GetAllMappingsRequest : public MappingRequest {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
GetAllMappingsRequest();
|
||||||
|
|
||||||
|
AssetMapping getMappings() const { return _mappings; }
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void finished(GetAllMappingsRequest* thisRequest);
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual void doStart() override;
|
||||||
|
|
||||||
|
std::map<AssetPath, AssetHash> _mappings;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif // hifi_MappingRequest_h
|
173
libraries/script-engine/src/AssetScriptingInterface.cpp
Normal file
173
libraries/script-engine/src/AssetScriptingInterface.cpp
Normal file
|
@ -0,0 +1,173 @@
|
||||||
|
//
|
||||||
|
// AssetScriptingInterface.cpp
|
||||||
|
// libraries/script-engine/src
|
||||||
|
//
|
||||||
|
// Created by Stephen Birarda on 2016-03-08.
|
||||||
|
// Copyright 2016 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "AssetScriptingInterface.h"
|
||||||
|
|
||||||
|
#include <QtScript/QScriptEngine>
|
||||||
|
|
||||||
|
#include <AssetRequest.h>
|
||||||
|
#include <AssetUpload.h>
|
||||||
|
#include <MappingRequest.h>
|
||||||
|
#include <NetworkLogging.h>
|
||||||
|
|
||||||
|
AssetScriptingInterface::AssetScriptingInterface(QScriptEngine* engine) :
|
||||||
|
_engine(engine)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetScriptingInterface::uploadData(QString data, QScriptValue callback) {
|
||||||
|
QByteArray dataByteArray = data.toUtf8();
|
||||||
|
auto upload = DependencyManager::get<AssetClient>()->createUpload(dataByteArray);
|
||||||
|
if (!upload) {
|
||||||
|
qCWarning(asset_client) << "Error uploading file to asset server";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QObject::connect(upload, &AssetUpload::finished, this, [this, callback](AssetUpload* upload, const QString& hash) mutable {
|
||||||
|
if (callback.isFunction()) {
|
||||||
|
QString url = "atp://" + hash;
|
||||||
|
QScriptValueList args { url };
|
||||||
|
callback.call(_engine->currentContext()->thisObject(), args);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
upload->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetScriptingInterface::downloadData(QString urlString, QScriptValue callback) {
|
||||||
|
const QString ATP_SCHEME { "atp://" };
|
||||||
|
|
||||||
|
if (!urlString.startsWith(ATP_SCHEME)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make request to atp
|
||||||
|
auto path = urlString.right(urlString.length() - ATP_SCHEME.length());
|
||||||
|
auto parts = path.split(".", QString::SkipEmptyParts);
|
||||||
|
auto hash = parts.length() > 0 ? parts[0] : "";
|
||||||
|
|
||||||
|
if (hash.length() != SHA256_HASH_HEX_LENGTH) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto assetClient = DependencyManager::get<AssetClient>();
|
||||||
|
auto assetRequest = assetClient->createRequest(hash);
|
||||||
|
|
||||||
|
if (!assetRequest) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_pendingRequests << assetRequest;
|
||||||
|
|
||||||
|
connect(assetRequest, &AssetRequest::finished, this, [this, callback](AssetRequest* request) mutable {
|
||||||
|
Q_ASSERT(request->getState() == AssetRequest::Finished);
|
||||||
|
|
||||||
|
if (request->getError() == AssetRequest::Error::NoError) {
|
||||||
|
if (callback.isFunction()) {
|
||||||
|
QString data = QString::fromUtf8(request->getData());
|
||||||
|
QScriptValueList args { data };
|
||||||
|
callback.call(_engine->currentContext()->thisObject(), args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
request->deleteLater();
|
||||||
|
_pendingRequests.remove(request);
|
||||||
|
});
|
||||||
|
|
||||||
|
assetRequest->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetScriptingInterface::setMapping(QString path, QString hash, QScriptValue callback) {
|
||||||
|
auto assetClient = DependencyManager::get<AssetClient>();
|
||||||
|
auto request = assetClient->createSetMappingRequest(path, hash);
|
||||||
|
|
||||||
|
connect(request, &SetMappingRequest::finished, this, [this, callback](SetMappingRequest* request) mutable {
|
||||||
|
QScriptValueList args { uint8_t(request->getError()) };
|
||||||
|
|
||||||
|
callback.call(_engine->currentContext()->thisObject(), args);
|
||||||
|
|
||||||
|
request->deleteLater();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
request->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetScriptingInterface::getMapping(QString path, QScriptValue callback) {
|
||||||
|
auto assetClient = DependencyManager::get<AssetClient>();
|
||||||
|
auto request = assetClient->createGetMappingRequest(path);
|
||||||
|
|
||||||
|
connect(request, &GetMappingRequest::finished, this, [this, callback](GetMappingRequest* request) mutable {
|
||||||
|
QScriptValueList args { uint8_t(request->getError()), request->getHash() };
|
||||||
|
|
||||||
|
callback.call(_engine->currentContext()->thisObject(), args);
|
||||||
|
|
||||||
|
request->deleteLater();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
request->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetScriptingInterface::deleteMappings(QStringList paths, QScriptValue callback) {
|
||||||
|
auto assetClient = DependencyManager::get<AssetClient>();
|
||||||
|
auto request = assetClient->createDeleteMappingsRequest(paths);
|
||||||
|
|
||||||
|
connect(request, &DeleteMappingsRequest::finished, this, [this, callback](DeleteMappingsRequest* request) mutable {
|
||||||
|
QScriptValueList args { uint8_t(request->getError()) };
|
||||||
|
|
||||||
|
callback.call(_engine->currentContext()->thisObject(), args);
|
||||||
|
|
||||||
|
request->deleteLater();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
request->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetScriptingInterface::getAllMappings(QScriptValue callback) {
|
||||||
|
auto assetClient = DependencyManager::get<AssetClient>();
|
||||||
|
auto request = assetClient->createGetAllMappingsRequest();
|
||||||
|
|
||||||
|
connect(request, &GetAllMappingsRequest::finished, this, [this, callback](GetAllMappingsRequest* request) mutable {
|
||||||
|
auto mappings = request->getMappings();
|
||||||
|
auto map = callback.engine()->newObject();
|
||||||
|
|
||||||
|
for (auto& kv : mappings ) {
|
||||||
|
map.setProperty(kv.first, kv.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
QScriptValueList args { uint8_t(request->getError()), map };
|
||||||
|
|
||||||
|
callback.call(_engine->currentContext()->thisObject(), args);
|
||||||
|
|
||||||
|
request->deleteLater();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
request->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetScriptingInterface::renameMapping(QString oldPath, QString newPath, QScriptValue callback) {
|
||||||
|
auto assetClient = DependencyManager::get<AssetClient>();
|
||||||
|
auto request = assetClient->createRenameMappingRequest(oldPath, newPath);
|
||||||
|
|
||||||
|
connect(request, &RenameMappingRequest::finished, this, [this, callback](RenameMappingRequest* request) mutable {
|
||||||
|
QScriptValueList args { uint8_t(request->getError()) };
|
||||||
|
|
||||||
|
callback.call(_engine->currentContext()->thisObject(), args);
|
||||||
|
|
||||||
|
request->deleteLater();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
request->start();
|
||||||
|
}
|
39
libraries/script-engine/src/AssetScriptingInterface.h
Normal file
39
libraries/script-engine/src/AssetScriptingInterface.h
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
//
|
||||||
|
// AssetScriptingInterface.h
|
||||||
|
// libraries/script-engine/src
|
||||||
|
//
|
||||||
|
// Created by Stephen Birarda on 2016-03-08.
|
||||||
|
// Copyright 2016 High Fidelity, Inc.
|
||||||
|
//
|
||||||
|
// Distributed under the Apache License, Version 2.0.
|
||||||
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef hifi_AssetScriptingInterface_h
|
||||||
|
#define hifi_AssetScriptingInterface_h
|
||||||
|
|
||||||
|
#include <QtCore/QObject>
|
||||||
|
#include <QtScript/QScriptValue>
|
||||||
|
|
||||||
|
#include <AssetClient.h>
|
||||||
|
|
||||||
|
class AssetScriptingInterface : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
AssetScriptingInterface(QScriptEngine* engine);
|
||||||
|
|
||||||
|
Q_INVOKABLE void uploadData(QString data, QScriptValue callback);
|
||||||
|
Q_INVOKABLE void downloadData(QString url, QScriptValue downloadComplete);
|
||||||
|
Q_INVOKABLE void setMapping(QString path, QString hash, QScriptValue callback);
|
||||||
|
Q_INVOKABLE void getMapping(QString path, QScriptValue callback);
|
||||||
|
Q_INVOKABLE void deleteMappings(QStringList paths, QScriptValue callback);
|
||||||
|
Q_INVOKABLE void getAllMappings(QScriptValue callback);
|
||||||
|
Q_INVOKABLE void renameMapping(QString oldPath, QString newPath, QScriptValue callback);
|
||||||
|
protected:
|
||||||
|
QSet<AssetRequest*> _pendingRequests;
|
||||||
|
QScriptEngine* _engine;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // hifi_AssetScriptingInterface_h
|
|
@ -23,7 +23,6 @@
|
||||||
|
|
||||||
#include <AnimationCache.h>
|
#include <AnimationCache.h>
|
||||||
#include <AnimVariant.h>
|
#include <AnimVariant.h>
|
||||||
#include <AssetClient.h>
|
|
||||||
#include <AvatarData.h>
|
#include <AvatarData.h>
|
||||||
#include <AvatarHashMap.h>
|
#include <AvatarHashMap.h>
|
||||||
#include <LimitedNodeList.h>
|
#include <LimitedNodeList.h>
|
||||||
|
@ -32,6 +31,7 @@
|
||||||
|
|
||||||
#include "MouseEvent.h"
|
#include "MouseEvent.h"
|
||||||
#include "ArrayBufferClass.h"
|
#include "ArrayBufferClass.h"
|
||||||
|
#include "AssetScriptingInterface.h"
|
||||||
#include "AudioScriptingInterface.h"
|
#include "AudioScriptingInterface.h"
|
||||||
#include "Quat.h"
|
#include "Quat.h"
|
||||||
#include "ScriptCache.h"
|
#include "ScriptCache.h"
|
||||||
|
|
Loading…
Reference in a new issue