From ec472bc719df94cdd31de689b4120307b232da76 Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Sat, 28 Dec 2019 02:06:34 -0500 Subject: [PATCH 01/12] Give scripts access to existing file formats Scripts can now call pre-defined map/tileset formats, and can query what map/tileset formats are available. Closes #2696. Still need to write documentation for the new APIs. I wasn't able to get QJSEngine to accept actual ScriptTilesetFormatWrapper return values, so functions that return those use QObject instead. Same applies to ScriptMapFormatWrapper. --- src/tiled/scriptedfileformat.cpp | 16 ++- src/tiled/scriptedfileformat.h | 9 ++ src/tiled/scriptfileformatwrappers.cpp | 135 +++++++++++++++++++++++++ src/tiled/scriptfileformatwrappers.h | 81 +++++++++++++++ src/tiled/scriptmanager.cpp | 3 + src/tiled/scriptmodule.cpp | 81 +++++++++++++++ src/tiled/scriptmodule.h | 11 ++ src/tiled/tiled.pro | 2 + src/tiled/tiled.qbs | 2 + 9 files changed, 337 insertions(+), 3 deletions(-) create mode 100644 src/tiled/scriptfileformatwrappers.cpp create mode 100644 src/tiled/scriptfileformatwrappers.h diff --git a/src/tiled/scriptedfileformat.cpp b/src/tiled/scriptedfileformat.cpp index fa6be10811..84f50ad55b 100644 --- a/src/tiled/scriptedfileformat.cpp +++ b/src/tiled/scriptedfileformat.cpp @@ -61,10 +61,10 @@ QString ScriptedFileFormat::nameFilter() const bool ScriptedFileFormat::supportsFile(const QString &fileName) const { - QString extension = mObject.property(QStringLiteral("extension")).toString(); - extension.prepend(QLatin1Char('.')); + QString ext = extension(); + ext.prepend(QLatin1Char('.')); - return fileName.endsWith(extension); + return fileName.endsWith(ext); } QJSValue ScriptedFileFormat::read(const QString &fileName) @@ -131,6 +131,16 @@ QStringList ScriptedFileFormat::outputFiles(EditableAsset *asset, const QString return QStringList(fileName); } +QString ScriptedFileFormat::name() const +{ + return mObject.property(QStringLiteral("name")).toString(); +} + +QString ScriptedFileFormat::extension() const +{ + return mObject.property(QStringLiteral("extension")).toString(); +} + bool ScriptedFileFormat::validateFileFormatObject(const QJSValue &value) { const QJSValue nameProperty = value.property(QStringLiteral("name")); diff --git a/src/tiled/scriptedfileformat.h b/src/tiled/scriptedfileformat.h index d7ffe3f004..41a99c15ef 100644 --- a/src/tiled/scriptedfileformat.h +++ b/src/tiled/scriptedfileformat.h @@ -44,6 +44,9 @@ class ScriptedFileFormat QStringList outputFiles(EditableAsset *asset, const QString &fileName) const; + QString name() const; + QString extension() const; + static bool validateFileFormatObject(const QJSValue &value); private: @@ -72,6 +75,9 @@ class ScriptedMapFormat final : public MapFormat std::unique_ptr read(const QString &fileName) override; bool write(const Map *map, const QString &fileName, Options options) override; + QString name() const { return mFormat.name(); } + QString extension() const { return mFormat.extension(); } + private: QString mShortName; QString mError; @@ -99,6 +105,9 @@ class ScriptedTilesetFormat final : public TilesetFormat SharedTileset read(const QString &fileName) override; bool write(const Tileset &tileset, const QString &fileName, Options options = Options()) override; + QString name() const { return mFormat.name(); } + QString extension() const { return mFormat.extension(); } + private: QString mShortName; QString mError; diff --git a/src/tiled/scriptfileformatwrappers.cpp b/src/tiled/scriptfileformatwrappers.cpp new file mode 100644 index 0000000000..39f167a2ff --- /dev/null +++ b/src/tiled/scriptfileformatwrappers.cpp @@ -0,0 +1,135 @@ +/* + * scriptfileformatwrappers.h + * Copyright 2019, Thorbjørn Lindeijer + * + * This file is part of Tiled. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#include "scriptfileformatwrappers.h" + +#include "editablemap.h" +#include "editabletileset.h" +#include "mapformat.h" +#include "scriptedfileformat.h" +#include "scriptmanager.h" +#include "tilesetformat.h" + +#include +#include + +namespace Tiled { + +ScriptTilesetFormatWrapper::ScriptTilesetFormatWrapper() +{ + //auto message = QCoreApplication::translate("Script Errors", + // "TilesetFormatWrapper cannot be constructed"); + //ScriptManager::instance().throwError(message); +} + +ScriptTilesetFormatWrapper::ScriptTilesetFormatWrapper(TilesetFormat* format, QObject *parent) + : QObject(parent) + , mFormat(format) +{} + +QString ScriptTilesetFormatWrapper::name() const +{ + if (auto scriptedFormat = qobject_cast(mFormat)) + return scriptedFormat->name(); + else + return mFormat->shortName(); +} + +QString ScriptTilesetFormatWrapper::extension() const +{ + if (auto scriptedFormat = qobject_cast(mFormat)) + return scriptedFormat->extension(); + else + return QString(); +} + +EditableTileset *ScriptTilesetFormatWrapper::read(QString &filename) +{ + auto tileset = mFormat->read(filename); + auto editable = new EditableTileset(tileset.data()); + QQmlEngine::setObjectOwnership(editable, QQmlEngine::JavaScriptOwnership); + return editable; +} + +QString ScriptTilesetFormatWrapper::write(EditableTileset *editable, QString &filename) +{ + auto tileset = editable->tileset(); + if (mFormat->write(*tileset, filename)) + return QString(); + else + return mFormat->errorString(); +} + +bool ScriptTilesetFormatWrapper::supportsFile(QString &filename) const +{ + return mFormat->supportsFile(filename); +} + +ScriptMapFormatWrapper::ScriptMapFormatWrapper() +{ + auto message = QCoreApplication::translate("Script Errors", + "MapFormatWrapper cannot be constructed"); + ScriptManager::instance().throwError(message); +} + +ScriptMapFormatWrapper::ScriptMapFormatWrapper(MapFormat *format, QObject *parent) + : QObject(parent) + , mFormat(format) +{} + +QString ScriptMapFormatWrapper::name() const +{ + if (auto scriptedFormat = qobject_cast(mFormat)) + return scriptedFormat->name(); + else + return mFormat->shortName(); +} + +QString ScriptMapFormatWrapper::extension() const +{ + if (auto scriptedFormat = qobject_cast(mFormat)) + return scriptedFormat->extension(); + else + return QString(); +} + +EditableMap *ScriptMapFormatWrapper::read(QString &filename) +{ + auto map = mFormat->read(filename); + auto editable = new EditableMap(std::move(map)); + QQmlEngine::setObjectOwnership(editable, QQmlEngine::JavaScriptOwnership); + return editable; +} + +QString ScriptMapFormatWrapper::write(EditableMap *editable, QString &filename) +{ + auto map = editable->map(); + if (mFormat->write(map, filename)) + return QString(); + else + return mFormat->errorString(); +} + +bool ScriptMapFormatWrapper::supportsFile(QString &filename) const +{ + return mFormat->supportsFile(filename); +} + +} diff --git a/src/tiled/scriptfileformatwrappers.h b/src/tiled/scriptfileformatwrappers.h new file mode 100644 index 0000000000..106ba43f3a --- /dev/null +++ b/src/tiled/scriptfileformatwrappers.h @@ -0,0 +1,81 @@ +/* + * scriptfileformatwrappers.h + * Copyright 2019, Thorbjørn Lindeijer + * + * This file is part of Tiled. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#pragma once + +#include + +namespace Tiled { + +class EditableTileset; +class EditableMap; +class MapFormat; +class TilesetFormat; + +class ScriptTilesetFormatWrapper : public QObject +{ + Q_OBJECT + + Q_PROPERTY(QString name READ name) + Q_PROPERTY(QString extension READ extension) + +public: + ScriptTilesetFormatWrapper(); + explicit ScriptTilesetFormatWrapper(TilesetFormat *format, QObject *parent = nullptr); + ~ScriptTilesetFormatWrapper() override {} + + QString name() const; + QString extension() const; + + Q_INVOKABLE EditableTileset *read(QString &filename); + Q_INVOKABLE QString write(EditableTileset *tileset, QString &filename); + Q_INVOKABLE bool supportsFile(QString &filename) const; + +private: + TilesetFormat *mFormat; +}; + +class ScriptMapFormatWrapper : public QObject +{ + Q_OBJECT + + Q_PROPERTY(QString name READ name) + Q_PROPERTY(QString extension READ extension) + +public: + Q_INVOKABLE ScriptMapFormatWrapper(); + Q_INVOKABLE explicit ScriptMapFormatWrapper(MapFormat *format, QObject *parent = nullptr); + ~ScriptMapFormatWrapper() override {} + + QString name() const; + QString extension() const; + + Q_INVOKABLE EditableMap *read(QString &filename); + Q_INVOKABLE QString write(EditableMap *map, QString &filename); + Q_INVOKABLE bool supportsFile(QString &filename) const; + +private: + MapFormat *mFormat; +}; + +} // namespace Tiled + +//Q_DECLARE_METATYPE(Tiled::ScriptTilesetFormatWrapper*) +//Q_DECLARE_METATYPE(Tiled::ScriptMapFormatWrapper*) diff --git a/src/tiled/scriptmanager.cpp b/src/tiled/scriptmanager.cpp index 5c32978e03..5da857c61a 100644 --- a/src/tiled/scriptmanager.cpp +++ b/src/tiled/scriptmanager.cpp @@ -37,6 +37,7 @@ #include "scriptedfileformat.h" #include "scriptedtool.h" #include "scriptfile.h" +#include "scriptfileformatwrappers.h" #include "scriptmodule.h" #include "tilecollisiondock.h" #include "tilelayer.h" @@ -104,6 +105,8 @@ ScriptManager::ScriptManager(QObject *parent) qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); + qRegisterMetaType(); + qRegisterMetaType(); connect(&mWatcher, &FileSystemWatcher::filesChanged, this, &ScriptManager::scriptFilesChanged); diff --git a/src/tiled/scriptmodule.cpp b/src/tiled/scriptmodule.cpp index b544d54a69..64ce2144b5 100644 --- a/src/tiled/scriptmodule.cpp +++ b/src/tiled/scriptmodule.cpp @@ -31,6 +31,7 @@ #include "scriptedaction.h" #include "scriptedfileformat.h" #include "scriptedtool.h" +#include "scriptfileformatwrappers.h" #include "scriptmanager.h" #include "tilesetdocument.h" #include "tileseteditor.h" @@ -40,6 +41,7 @@ #include #include #include +#include namespace Tiled { @@ -113,6 +115,28 @@ QStringList ScriptModule::menus() const return idsToNames(ActionManager::menus()); } +QStringList ScriptModule::mapFormats() const +{ + const auto formats = PluginManager::objects(); + QStringList ret; + ret.reserve(formats.length()); + for (auto format : formats) { + ret.append(format->shortName()); + } + return ret; +} + +QStringList ScriptModule::tilesetFormats() const +{ + const auto formats = PluginManager::objects(); + QStringList ret; + ret.reserve(formats.length()); + for (auto format : formats) { + ret.append(format->shortName()); + } + return ret; +} + EditableAsset *ScriptModule::activeAsset() const { auto documentManager = DocumentManager::instance(); @@ -282,6 +306,63 @@ QJSValue ScriptModule::registerTool(const QString &shortName, QJSValue toolObjec return toolObject; } +QObject *ScriptModule::getMapFormat(const QString &shortName) const +{ + auto formats = PluginManager::objects(); + for (auto format : formats) { + if (format->shortName() == shortName) { + auto wrapper = new ScriptMapFormatWrapper(format); + QQmlEngine::setObjectOwnership(wrapper, QQmlEngine::JavaScriptOwnership); + return wrapper; + } + } + + return nullptr; +} + +QObject *ScriptModule::getMapFormatByFile(const QString &fileName) const +{ + auto formats = PluginManager::objects(); + for (auto format : formats) { + if (format->supportsFile(fileName)) { + auto wrapper = new ScriptMapFormatWrapper(format); + QQmlEngine::setObjectOwnership(wrapper, QQmlEngine::JavaScriptOwnership); + return wrapper; + } + } + + return nullptr; +} + +QObject *ScriptModule::getTilesetFormat(const QString &shortName) const +{ + auto formats = PluginManager::objects(); + for (auto format : formats) { + if (format->shortName() == shortName) { + auto wrapper = new ScriptTilesetFormatWrapper(format); + QQmlEngine::setObjectOwnership(wrapper, QQmlEngine::JavaScriptOwnership); + return wrapper; + } + } + + return nullptr; +} + +QObject *ScriptModule::getTilesetFormatByFile(const QString &fileName) const +{ + auto formats = PluginManager::objects(); + for (auto format : formats) { + if (format->supportsFile(fileName)) { + auto wrapper = new ScriptTilesetFormatWrapper(format); + QQmlEngine::setObjectOwnership(wrapper, QQmlEngine::JavaScriptOwnership); + return wrapper; + } + } + + return nullptr; +} + + static QString toString(QJSValue value) { if (value.isString()) diff --git a/src/tiled/scriptmodule.h b/src/tiled/scriptmodule.h index 97976928c3..1b436614c4 100644 --- a/src/tiled/scriptmodule.h +++ b/src/tiled/scriptmodule.h @@ -40,6 +40,8 @@ class MapEditor; class ScriptedAction; class ScriptedMapFormat; class ScriptedTilesetFormat; +class ScriptMapFormatWrapper; +class ScriptTilesetFormatWrapper; class ScriptedTool; class TilesetEditor; @@ -56,6 +58,8 @@ class ScriptModule : public QObject Q_PROPERTY(QStringList actions READ actions) Q_PROPERTY(QStringList menus READ menus) + Q_PROPERTY(QStringList mapFormats READ mapFormats) + Q_PROPERTY(QStringList tilesetFormats READ tilesetFormats) Q_PROPERTY(Tiled::EditableAsset *activeAsset READ activeAsset WRITE setActiveAsset NOTIFY activeAssetChanged) Q_PROPERTY(QList openAssets READ openAssets) @@ -84,6 +88,8 @@ class ScriptModule : public QObject QStringList actions() const; QStringList menus() const; + QStringList mapFormats() const; + QStringList tilesetFormats() const; EditableAsset *activeAsset() const; bool setActiveAsset(EditableAsset *asset) const; @@ -102,6 +108,11 @@ class ScriptModule : public QObject Q_INVOKABLE void registerTilesetFormat(const QString &shortName, QJSValue tilesetFormatObject); Q_INVOKABLE QJSValue registerTool(const QString &shortName, QJSValue toolObject); + Q_INVOKABLE QObject *getMapFormat(const QString &shortName) const; + Q_INVOKABLE QObject *getMapFormatByFile(const QString &fileName) const; + Q_INVOKABLE QObject *getTilesetFormat(const QString &shortName) const; + Q_INVOKABLE QObject *getTilesetFormatByFile(const QString &fileName) const; + Q_INVOKABLE void extendMenu(const QByteArray &idName, QJSValue items); signals: diff --git a/src/tiled/tiled.pro b/src/tiled/tiled.pro index b37d5bb357..132834c5d5 100644 --- a/src/tiled/tiled.pro +++ b/src/tiled/tiled.pro @@ -207,6 +207,7 @@ SOURCES += aboutdialog.cpp \ scriptedfileformat.cpp \ scriptedtool.cpp \ scriptfile.cpp \ + scriptfileformatwrappers.cpp \ scriptmanager.cpp \ scriptmodule.cpp \ selectionrectangle.cpp \ @@ -438,6 +439,7 @@ HEADERS += aboutdialog.h \ scriptedfileformat.h \ scriptedtool.h \ scriptfile.h \ + scriptfileformatwrappers.h \ scriptmanager.h \ scriptmodule.h \ selectionrectangle.h \ diff --git a/src/tiled/tiled.qbs b/src/tiled/tiled.qbs index 03d7c11aa1..3c2772e11d 100644 --- a/src/tiled/tiled.qbs +++ b/src/tiled/tiled.qbs @@ -414,6 +414,8 @@ QtGuiApplication { "scriptedtool.h", "scriptfile.cpp", "scriptfile.h", + "scriptfileformatwrappers.cpp", + "scriptfileformatwrappers.h", "scriptmanager.cpp", "scriptmanager.h", "scriptmodule.cpp", From ab66ba96eac13011ab84148981c7d8ac38c03f3c Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Sat, 28 Dec 2019 23:09:52 -0500 Subject: [PATCH 02/12] Remove some test code --- src/tiled/scriptfileformatwrappers.cpp | 7 ------- src/tiled/scriptfileformatwrappers.h | 6 ++---- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/src/tiled/scriptfileformatwrappers.cpp b/src/tiled/scriptfileformatwrappers.cpp index 39f167a2ff..7133047b96 100644 --- a/src/tiled/scriptfileformatwrappers.cpp +++ b/src/tiled/scriptfileformatwrappers.cpp @@ -32,13 +32,6 @@ namespace Tiled { -ScriptTilesetFormatWrapper::ScriptTilesetFormatWrapper() -{ - //auto message = QCoreApplication::translate("Script Errors", - // "TilesetFormatWrapper cannot be constructed"); - //ScriptManager::instance().throwError(message); -} - ScriptTilesetFormatWrapper::ScriptTilesetFormatWrapper(TilesetFormat* format, QObject *parent) : QObject(parent) , mFormat(format) diff --git a/src/tiled/scriptfileformatwrappers.h b/src/tiled/scriptfileformatwrappers.h index 106ba43f3a..76e8a9a594 100644 --- a/src/tiled/scriptfileformatwrappers.h +++ b/src/tiled/scriptfileformatwrappers.h @@ -37,9 +37,7 @@ class ScriptTilesetFormatWrapper : public QObject Q_PROPERTY(QString extension READ extension) public: - ScriptTilesetFormatWrapper(); explicit ScriptTilesetFormatWrapper(TilesetFormat *format, QObject *parent = nullptr); - ~ScriptTilesetFormatWrapper() override {} QString name() const; QString extension() const; @@ -77,5 +75,5 @@ class ScriptMapFormatWrapper : public QObject } // namespace Tiled -//Q_DECLARE_METATYPE(Tiled::ScriptTilesetFormatWrapper*) -//Q_DECLARE_METATYPE(Tiled::ScriptMapFormatWrapper*) +Q_DECLARE_METATYPE(Tiled::ScriptTilesetFormatWrapper*) +Q_DECLARE_METATYPE(Tiled::ScriptMapFormatWrapper*) From 91203ce72d3efd50a31dc7ba3d1bc714c6703cf4 Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Sun, 29 Dec 2019 18:32:49 -0500 Subject: [PATCH 03/12] Fix scripted return types Qt requires a namespace to resove a class name into a metatype correctly. It seems to do a string comparison at some point in its code against the actual symbol written as the return type for a Q_INVOKABLE function, ignoring how that symbol resoves. --- src/tiled/scriptmodule.cpp | 8 ++++---- src/tiled/scriptmodule.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/tiled/scriptmodule.cpp b/src/tiled/scriptmodule.cpp index 64ce2144b5..03ed8fdb91 100644 --- a/src/tiled/scriptmodule.cpp +++ b/src/tiled/scriptmodule.cpp @@ -306,7 +306,7 @@ QJSValue ScriptModule::registerTool(const QString &shortName, QJSValue toolObjec return toolObject; } -QObject *ScriptModule::getMapFormat(const QString &shortName) const +Tiled::ScriptMapFormatWrapper *ScriptModule::getMapFormat(const QString &shortName) const { auto formats = PluginManager::objects(); for (auto format : formats) { @@ -320,7 +320,7 @@ QObject *ScriptModule::getMapFormat(const QString &shortName) const return nullptr; } -QObject *ScriptModule::getMapFormatByFile(const QString &fileName) const +Tiled::ScriptMapFormatWrapper *ScriptModule::getMapFormatByFile(const QString &fileName) const { auto formats = PluginManager::objects(); for (auto format : formats) { @@ -334,7 +334,7 @@ QObject *ScriptModule::getMapFormatByFile(const QString &fileName) const return nullptr; } -QObject *ScriptModule::getTilesetFormat(const QString &shortName) const +Tiled::ScriptTilesetFormatWrapper *ScriptModule::getTilesetFormat(const QString &shortName) const { auto formats = PluginManager::objects(); for (auto format : formats) { @@ -348,7 +348,7 @@ QObject *ScriptModule::getTilesetFormat(const QString &shortName) const return nullptr; } -QObject *ScriptModule::getTilesetFormatByFile(const QString &fileName) const +Tiled::ScriptTilesetFormatWrapper *ScriptModule::getTilesetFormatByFile(const QString &fileName) const { auto formats = PluginManager::objects(); for (auto format : formats) { diff --git a/src/tiled/scriptmodule.h b/src/tiled/scriptmodule.h index 1b436614c4..466019a6b4 100644 --- a/src/tiled/scriptmodule.h +++ b/src/tiled/scriptmodule.h @@ -108,10 +108,10 @@ class ScriptModule : public QObject Q_INVOKABLE void registerTilesetFormat(const QString &shortName, QJSValue tilesetFormatObject); Q_INVOKABLE QJSValue registerTool(const QString &shortName, QJSValue toolObject); - Q_INVOKABLE QObject *getMapFormat(const QString &shortName) const; - Q_INVOKABLE QObject *getMapFormatByFile(const QString &fileName) const; - Q_INVOKABLE QObject *getTilesetFormat(const QString &shortName) const; - Q_INVOKABLE QObject *getTilesetFormatByFile(const QString &fileName) const; + Q_INVOKABLE Tiled::ScriptMapFormatWrapper *getMapFormat(const QString &shortName) const; + Q_INVOKABLE Tiled::ScriptMapFormatWrapper *getMapFormatByFile(const QString &fileName) const; + Q_INVOKABLE Tiled::ScriptTilesetFormatWrapper *getTilesetFormat(const QString &shortName) const; + Q_INVOKABLE Tiled::ScriptTilesetFormatWrapper *getTilesetFormatByFile(const QString &fileName) const; Q_INVOKABLE void extendMenu(const QByteArray &idName, QJSValue items); From ce63b5933b1f6a3821d9f25e28d82db88582691c Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Mon, 30 Dec 2019 20:36:26 -0500 Subject: [PATCH 04/12] Fix formattting, make requested changes Also fixed a bug making `read` fail (unrecognized return type). --- src/tiled/scriptfileformatwrappers.cpp | 46 +++++++++++++++----------- src/tiled/scriptfileformatwrappers.h | 19 +++++------ src/tiled/scriptmodule.cpp | 16 ++++----- src/tiled/scriptmodule.h | 8 ++--- 4 files changed, 47 insertions(+), 42 deletions(-) diff --git a/src/tiled/scriptfileformatwrappers.cpp b/src/tiled/scriptfileformatwrappers.cpp index 7133047b96..2590e8b9c6 100644 --- a/src/tiled/scriptfileformatwrappers.cpp +++ b/src/tiled/scriptfileformatwrappers.cpp @@ -1,6 +1,7 @@ /* * scriptfileformatwrappers.h - * Copyright 2019, Thorbjørn Lindeijer + * Copyright 2019, Thorbjørn Lindeijer , Phlosioneer + * * * This file is part of Tiled. * @@ -53,15 +54,21 @@ QString ScriptTilesetFormatWrapper::extension() const return QString(); } -EditableTileset *ScriptTilesetFormatWrapper::read(QString &filename) +EditableTileset *ScriptTilesetFormatWrapper::read(const QString &filename) { auto tileset = mFormat->read(filename); - auto editable = new EditableTileset(tileset.data()); - QQmlEngine::setObjectOwnership(editable, QQmlEngine::JavaScriptOwnership); - return editable; + if (tileset) { + auto editable = new EditableTileset(tileset.data()); + QQmlEngine::setObjectOwnership(editable, QQmlEngine::JavaScriptOwnership); + return editable; + } else { + auto message = QCoreApplication::translate("Script Errors", "Error reading tileset"); + ScriptManager::instance().throwError(message); + return nullptr; + } } -QString ScriptTilesetFormatWrapper::write(EditableTileset *editable, QString &filename) +QString ScriptTilesetFormatWrapper::write(const EditableTileset *editable, const QString &filename) { auto tileset = editable->tileset(); if (mFormat->write(*tileset, filename)) @@ -70,18 +77,11 @@ QString ScriptTilesetFormatWrapper::write(EditableTileset *editable, QString &fi return mFormat->errorString(); } -bool ScriptTilesetFormatWrapper::supportsFile(QString &filename) const +bool ScriptTilesetFormatWrapper::supportsFile(const QString &filename) const { return mFormat->supportsFile(filename); } -ScriptMapFormatWrapper::ScriptMapFormatWrapper() -{ - auto message = QCoreApplication::translate("Script Errors", - "MapFormatWrapper cannot be constructed"); - ScriptManager::instance().throwError(message); -} - ScriptMapFormatWrapper::ScriptMapFormatWrapper(MapFormat *format, QObject *parent) : QObject(parent) , mFormat(format) @@ -103,15 +103,21 @@ QString ScriptMapFormatWrapper::extension() const return QString(); } -EditableMap *ScriptMapFormatWrapper::read(QString &filename) +EditableMap *ScriptMapFormatWrapper::read(const QString &filename) { auto map = mFormat->read(filename); - auto editable = new EditableMap(std::move(map)); - QQmlEngine::setObjectOwnership(editable, QQmlEngine::JavaScriptOwnership); - return editable; + if (map) { + auto editable = new EditableMap(std::move(map)); + QQmlEngine::setObjectOwnership(editable, QQmlEngine::JavaScriptOwnership); + return editable; + } else { + auto message = QCoreApplication::translate("Script Errors", "Error reading map"); + ScriptManager::instance().throwError(message); + return nullptr; + } } -QString ScriptMapFormatWrapper::write(EditableMap *editable, QString &filename) +QString ScriptMapFormatWrapper::write(const EditableMap *editable, const QString &filename) { auto map = editable->map(); if (mFormat->write(map, filename)) @@ -120,7 +126,7 @@ QString ScriptMapFormatWrapper::write(EditableMap *editable, QString &filename) return mFormat->errorString(); } -bool ScriptMapFormatWrapper::supportsFile(QString &filename) const +bool ScriptMapFormatWrapper::supportsFile(const QString &filename) const { return mFormat->supportsFile(filename); } diff --git a/src/tiled/scriptfileformatwrappers.h b/src/tiled/scriptfileformatwrappers.h index 76e8a9a594..57ac094914 100644 --- a/src/tiled/scriptfileformatwrappers.h +++ b/src/tiled/scriptfileformatwrappers.h @@ -1,6 +1,7 @@ /* * scriptfileformatwrappers.h - * Copyright 2019, Thorbjørn Lindeijer + * Copyright 2019, Thorbjørn Lindeijer , Phlosioneer + * * * This file is part of Tiled. * @@ -42,9 +43,9 @@ class ScriptTilesetFormatWrapper : public QObject QString name() const; QString extension() const; - Q_INVOKABLE EditableTileset *read(QString &filename); - Q_INVOKABLE QString write(EditableTileset *tileset, QString &filename); - Q_INVOKABLE bool supportsFile(QString &filename) const; + Q_INVOKABLE Tiled::EditableTileset *read(const QString &filename); + Q_INVOKABLE QString write(const EditableTileset *tileset, const QString &filename); + Q_INVOKABLE bool supportsFile(const QString &filename) const; private: TilesetFormat *mFormat; @@ -58,16 +59,14 @@ class ScriptMapFormatWrapper : public QObject Q_PROPERTY(QString extension READ extension) public: - Q_INVOKABLE ScriptMapFormatWrapper(); - Q_INVOKABLE explicit ScriptMapFormatWrapper(MapFormat *format, QObject *parent = nullptr); - ~ScriptMapFormatWrapper() override {} + explicit ScriptMapFormatWrapper(MapFormat *format, QObject *parent = nullptr); QString name() const; QString extension() const; - Q_INVOKABLE EditableMap *read(QString &filename); - Q_INVOKABLE QString write(EditableMap *map, QString &filename); - Q_INVOKABLE bool supportsFile(QString &filename) const; + Q_INVOKABLE Tiled::EditableMap *read(const QString &filename); + Q_INVOKABLE QString write(const EditableMap *map, const QString &filename); + Q_INVOKABLE bool supportsFile(const QString &filename) const; private: MapFormat *mFormat; diff --git a/src/tiled/scriptmodule.cpp b/src/tiled/scriptmodule.cpp index 03ed8fdb91..baa72a2199 100644 --- a/src/tiled/scriptmodule.cpp +++ b/src/tiled/scriptmodule.cpp @@ -306,9 +306,9 @@ QJSValue ScriptModule::registerTool(const QString &shortName, QJSValue toolObjec return toolObject; } -Tiled::ScriptMapFormatWrapper *ScriptModule::getMapFormat(const QString &shortName) const +ScriptMapFormatWrapper *ScriptModule::mapFormat(const QString &shortName) const { - auto formats = PluginManager::objects(); + const auto formats = PluginManager::objects(); for (auto format : formats) { if (format->shortName() == shortName) { auto wrapper = new ScriptMapFormatWrapper(format); @@ -320,9 +320,9 @@ Tiled::ScriptMapFormatWrapper *ScriptModule::getMapFormat(const QString &shortNa return nullptr; } -Tiled::ScriptMapFormatWrapper *ScriptModule::getMapFormatByFile(const QString &fileName) const +ScriptMapFormatWrapper *ScriptModule::mapFormatForFile(const QString &fileName) const { - auto formats = PluginManager::objects(); + const auto formats = PluginManager::objects(); for (auto format : formats) { if (format->supportsFile(fileName)) { auto wrapper = new ScriptMapFormatWrapper(format); @@ -334,9 +334,9 @@ Tiled::ScriptMapFormatWrapper *ScriptModule::getMapFormatByFile(const QString &f return nullptr; } -Tiled::ScriptTilesetFormatWrapper *ScriptModule::getTilesetFormat(const QString &shortName) const +ScriptTilesetFormatWrapper *ScriptModule::tilesetFormat(const QString &shortName) const { - auto formats = PluginManager::objects(); + const auto formats = PluginManager::objects(); for (auto format : formats) { if (format->shortName() == shortName) { auto wrapper = new ScriptTilesetFormatWrapper(format); @@ -348,9 +348,9 @@ Tiled::ScriptTilesetFormatWrapper *ScriptModule::getTilesetFormat(const QString return nullptr; } -Tiled::ScriptTilesetFormatWrapper *ScriptModule::getTilesetFormatByFile(const QString &fileName) const +ScriptTilesetFormatWrapper *ScriptModule::tilesetFormatForFile(const QString &fileName) const { - auto formats = PluginManager::objects(); + const auto formats = PluginManager::objects(); for (auto format : formats) { if (format->supportsFile(fileName)) { auto wrapper = new ScriptTilesetFormatWrapper(format); diff --git a/src/tiled/scriptmodule.h b/src/tiled/scriptmodule.h index 466019a6b4..406ef43360 100644 --- a/src/tiled/scriptmodule.h +++ b/src/tiled/scriptmodule.h @@ -108,10 +108,10 @@ class ScriptModule : public QObject Q_INVOKABLE void registerTilesetFormat(const QString &shortName, QJSValue tilesetFormatObject); Q_INVOKABLE QJSValue registerTool(const QString &shortName, QJSValue toolObject); - Q_INVOKABLE Tiled::ScriptMapFormatWrapper *getMapFormat(const QString &shortName) const; - Q_INVOKABLE Tiled::ScriptMapFormatWrapper *getMapFormatByFile(const QString &fileName) const; - Q_INVOKABLE Tiled::ScriptTilesetFormatWrapper *getTilesetFormat(const QString &shortName) const; - Q_INVOKABLE Tiled::ScriptTilesetFormatWrapper *getTilesetFormatByFile(const QString &fileName) const; + Q_INVOKABLE Tiled::ScriptMapFormatWrapper *mapFormat(const QString &shortName) const; + Q_INVOKABLE Tiled::ScriptMapFormatWrapper *mapFormatForFile(const QString &fileName) const; + Q_INVOKABLE Tiled::ScriptTilesetFormatWrapper *tilesetFormat(const QString &shortName) const; + Q_INVOKABLE Tiled::ScriptTilesetFormatWrapper *tilesetFormatForFile(const QString &fileName) const; Q_INVOKABLE void extendMenu(const QByteArray &idName, QJSValue items); From e7e4a9a8628a3cde2e88ed50e278c28e9f512717 Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Mon, 30 Dec 2019 21:36:21 -0500 Subject: [PATCH 05/12] Write docs for new features --- docs/reference/scripting.rst | 99 ++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/docs/reference/scripting.rst b/docs/reference/scripting.rst index e1fd4ceb6c..0f7ce90750 100644 --- a/docs/reference/scripting.rst +++ b/docs/reference/scripting.rst @@ -129,6 +129,14 @@ Properties **openAssets** : array |ro|, "List of currently opened :ref:`assets `." **mapEditor** : :ref:`script-mapeditor`, "Access the editor used when editing maps." **tilesetEditor** : :ref:`script-tileseteditor`, "Access the editor used when editing tilesets." + **tilesetFormats** : [string] |ro|, "List of tileset format names. Built in + options are `tsx`, `json`, and `lua` (write-only). Use + :ref:`tilesetFormat` to get the corresponding format object + to read and write files. (Since 1.4)" + **mapFormats** : [string] |ro|, "List of map format names. Built in options + are `tmx`, `json`, `js`, `gmx` (write-only), and `lua` (write-only). Use + :ref:`mapFormat` to get the corresponding format object to + read and write files. (Since 1.4)" Functions ~~~~~~~~~ @@ -432,6 +440,33 @@ tiled.extendMenu(id : string, items : array | object) : void The "CustomAction" will need to have been registered before using :ref:`tiled.registerAction() `. + +.. _script-tilesetFormat: + +tiled.tilesetFormat(shortName : string) : TilesetFormatWrapper + Returns the tileset format object with the given name, or `undefined` if + no object was found. Built in options are `tsx`, `json`, and `lua`. See the + `tilesetFormats` property for more info. + +.. _script-tilesetFormatForFile: + +tiled.tilesetFormatForFile(fileName : string) : TilesetFormatWrapper + Returns the tileset format object that can read the given file, or `undefined` + if no object was found. + +.. _script-mapFormat: + +tiled.mapFormat(shortName : string) : MapFormatWrapper + Returns the map format object with the given name, or `undefined` if no object + was found. Built in options are `tsx`, `csv`, `gmx`, `json`, `js`, and `lua`. + See the `mapFormats` property for more info. + +.. _script-mapFormatForFile: + +tiled.mapFormatForFile(fileName : string) : MapFormatWrapper + Returns the map format object that can read the given file, or `undefined` if + no object was found. + .. _script-tiled-signals: Signals @@ -690,6 +725,38 @@ Properties **currentMapView** : :ref:`script-mapview` |ro|, "Access the current map view." **tilesetsView** : :ref:`script-tilesetsview` |ro|, "Access the Tilesets view." +.. _script-mapformatwrapper: + +Map Format Wrapper +^^^^^^^^^^^^^^^^^^ + +This is an object that can read or write map files. (Since 1.4) + +Properties +~~~~~~~~~~ + +.. csv-table:: + :widths: 1, 2 + + **name** : string |ro|, The name of this format. + **extension** : string |ro|, "The file extension of this format, or `undefined` + if not available. Use `supportsFile` instead." + +Functions +~~~~~~~~~ + +MapFormatWrapper.read(fileName : string) : :ref:`script-map` + Read the given file as a map. This function will throw an error if it + is not supported. + +MapFormatWrapper.write(map : :ref:`script-map`, fileName : string) : string + Write the given map to a file. This function will throw an error if it + is not supported. If there is an error writing the file, it will return a + description of the error; otherwise, it will return "". + +MapFormatWrapper.supportsFile(fileName : string) : bool + Returns whether the file is readable by this format. + .. _script-mapview: Map View @@ -1296,6 +1363,38 @@ Properties **collisionEditor** : :ref:`script-tilecollisioneditor`, "Access the collision editor within the tileset editor." +.. _script-tilesetformatwrapper: + +Tileset Format Wrapper +^^^^^^^^^^^^^^^^^^^^^^ + +This is an object that can read or write tileset files. (Since 1.4) + +Properties +~~~~~~~~~~ + +.. csv-table:: + :widths: 1, 2 + + **name** : string |ro|, The name of this format. + **extension** : string |ro|, "The file extension of this format, or `undefined` + if not available. Use `supportsFile` instead." + +Functions +~~~~~~~~~ + +TilesetFormatWrapper.read(fileName : string) : :ref:`script-tileset` + Read the given file as a tileset. This function will throw an error if it + is not supported. + +TilesetFormatWrapper.write(tileset : :ref:`script-tileset`, fileName : string) : string + Write the given tileset to a file. This function will throw an error if it + is not supported. If there is an error writing the file, it will return a + description of the error; otherwise, it will return "". + +TilesetFormatWrapper.supportsFile(fileName : string) : bool + Returns whether the file is readable by this format. + .. _script-tilesetsview: Tilesets View From 941ddab062971d4ae25d197801e7d8658f4d5016 Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Thu, 2 Jan 2020 19:41:12 -0500 Subject: [PATCH 06/12] Refactor duplicate code, add canRead/canWrite Removed `name` and `extension` properties. Added checks for whether a file format is able to read/write. --- src/tiled/scriptfileformatwrappers.cpp | 110 +++++++++++++------------ src/tiled/scriptfileformatwrappers.h | 48 +++++------ 2 files changed, 82 insertions(+), 76 deletions(-) diff --git a/src/tiled/scriptfileformatwrappers.cpp b/src/tiled/scriptfileformatwrappers.cpp index 2590e8b9c6..94ec7f201b 100644 --- a/src/tiled/scriptfileformatwrappers.cpp +++ b/src/tiled/scriptfileformatwrappers.cpp @@ -33,30 +33,54 @@ namespace Tiled { -ScriptTilesetFormatWrapper::ScriptTilesetFormatWrapper(TilesetFormat* format, QObject *parent) - : QObject(parent) - , mFormat(format) +ScriptFileFormatWrapper::ScriptFileFormatWrapper(FileFormat *format, QObject *parent) + : QObject(parent), + mFormat(format) {} -QString ScriptTilesetFormatWrapper::name() const +bool ScriptFileFormatWrapper::supportsFile(const QString &filename) const +{ + return mFormat->supportsFile(filename); +} + +bool ScriptFileFormatWrapper::canRead() const { - if (auto scriptedFormat = qobject_cast(mFormat)) - return scriptedFormat->name(); - else - return mFormat->shortName(); + return mFormat->capabilities() & FileFormat::Read; } -QString ScriptTilesetFormatWrapper::extension() const +bool ScriptFileFormatWrapper::canWrite() const { - if (auto scriptedFormat = qobject_cast(mFormat)) - return scriptedFormat->extension(); - else - return QString(); + return mFormat->capabilities() & FileFormat::Write; } +bool ScriptFileFormatWrapper::assertCanRead() const +{ + if (canRead()) + return true; + auto message = QCoreApplication::translate("Script Errors", "File format doesn't support `read`"); + ScriptManager::instance().throwError(message); + return false; +} + +bool ScriptFileFormatWrapper::assertCanWrite() const +{ + if (canWrite()) + return true; + auto message = QCoreApplication::translate("Script Errors", "File format doesn't support `write`"); + ScriptManager::instance().throwError(message); + return false; +} + +ScriptTilesetFormatWrapper::ScriptTilesetFormatWrapper(TilesetFormat* format, QObject *parent) + : ScriptFileFormatWrapper(format, parent) +{} + EditableTileset *ScriptTilesetFormatWrapper::read(const QString &filename) { - auto tileset = mFormat->read(filename); + if (!assertCanRead()) + return nullptr; + + auto tileset = static_cast(mFormat)->read(filename); if (tileset) { auto editable = new EditableTileset(tileset.data()); QQmlEngine::setObjectOwnership(editable, QQmlEngine::JavaScriptOwnership); @@ -68,44 +92,27 @@ EditableTileset *ScriptTilesetFormatWrapper::read(const QString &filename) } } -QString ScriptTilesetFormatWrapper::write(const EditableTileset *editable, const QString &filename) +void ScriptTilesetFormatWrapper::write(EditableTileset *editable, const QString &filename) { - auto tileset = editable->tileset(); - if (mFormat->write(*tileset, filename)) - return QString(); - else - return mFormat->errorString(); -} + if (!assertCanWrite()) + return; -bool ScriptTilesetFormatWrapper::supportsFile(const QString &filename) const -{ - return mFormat->supportsFile(filename); + auto tileset = editable->tileset(); + auto success = static_cast(mFormat)->write(*tileset, filename); + if (!success) + ScriptManager::instance().throwError(mFormat->errorString()); } ScriptMapFormatWrapper::ScriptMapFormatWrapper(MapFormat *format, QObject *parent) - : QObject(parent) - , mFormat(format) + : ScriptFileFormatWrapper(format, parent) {} -QString ScriptMapFormatWrapper::name() const -{ - if (auto scriptedFormat = qobject_cast(mFormat)) - return scriptedFormat->name(); - else - return mFormat->shortName(); -} - -QString ScriptMapFormatWrapper::extension() const -{ - if (auto scriptedFormat = qobject_cast(mFormat)) - return scriptedFormat->extension(); - else - return QString(); -} - EditableMap *ScriptMapFormatWrapper::read(const QString &filename) { - auto map = mFormat->read(filename); + if (!assertCanRead()) + return nullptr; + + auto map = static_cast(mFormat)->read(filename); if (map) { auto editable = new EditableMap(std::move(map)); QQmlEngine::setObjectOwnership(editable, QQmlEngine::JavaScriptOwnership); @@ -117,18 +124,15 @@ EditableMap *ScriptMapFormatWrapper::read(const QString &filename) } } -QString ScriptMapFormatWrapper::write(const EditableMap *editable, const QString &filename) +void ScriptMapFormatWrapper::write(EditableMap *editable, const QString &filename) { - auto map = editable->map(); - if (mFormat->write(map, filename)) - return QString(); - else - return mFormat->errorString(); -} + if (!assertCanWrite()) + return; -bool ScriptMapFormatWrapper::supportsFile(const QString &filename) const -{ - return mFormat->supportsFile(filename); + auto map = editable->map(); + auto success = static_cast(mFormat)->write(map, filename); + if (!success) + ScriptManager::instance().throwError(mFormat->errorString()); } } diff --git a/src/tiled/scriptfileformatwrappers.h b/src/tiled/scriptfileformatwrappers.h index 57ac094914..223aec9dc1 100644 --- a/src/tiled/scriptfileformatwrappers.h +++ b/src/tiled/scriptfileformatwrappers.h @@ -29,47 +29,49 @@ class EditableTileset; class EditableMap; class MapFormat; class TilesetFormat; +class FileFormat; -class ScriptTilesetFormatWrapper : public QObject +class ScriptFileFormatWrapper : public QObject { Q_OBJECT - Q_PROPERTY(QString name READ name) - Q_PROPERTY(QString extension READ extension) - + Q_PROPERTY(bool canRead READ canRead) + Q_PROPERTY(bool canWrite READ canWrite) public: - explicit ScriptTilesetFormatWrapper(TilesetFormat *format, QObject *parent = nullptr); - - QString name() const; - QString extension() const; + explicit ScriptFileFormatWrapper(FileFormat *format, QObject *parent = nullptr); - Q_INVOKABLE Tiled::EditableTileset *read(const QString &filename); - Q_INVOKABLE QString write(const EditableTileset *tileset, const QString &filename); Q_INVOKABLE bool supportsFile(const QString &filename) const; -private: - TilesetFormat *mFormat; + bool canRead() const; + bool canWrite() const; +protected: + + bool assertCanRead() const; + bool assertCanWrite() const; + + FileFormat *mFormat; }; -class ScriptMapFormatWrapper : public QObject +class ScriptTilesetFormatWrapper : public ScriptFileFormatWrapper { Q_OBJECT - Q_PROPERTY(QString name READ name) - Q_PROPERTY(QString extension READ extension) +public: + explicit ScriptTilesetFormatWrapper(TilesetFormat *format, QObject *parent = nullptr); + + Q_INVOKABLE Tiled::EditableTileset *read(const QString &filename); + Q_INVOKABLE void write(Tiled::EditableTileset *tileset, const QString &filename); +}; + +class ScriptMapFormatWrapper : public ScriptFileFormatWrapper +{ + Q_OBJECT public: explicit ScriptMapFormatWrapper(MapFormat *format, QObject *parent = nullptr); - QString name() const; - QString extension() const; - Q_INVOKABLE Tiled::EditableMap *read(const QString &filename); - Q_INVOKABLE QString write(const EditableMap *map, const QString &filename); - Q_INVOKABLE bool supportsFile(const QString &filename) const; - -private: - MapFormat *mFormat; + Q_INVOKABLE void write(Tiled::EditableMap *map, const QString &filename); }; } // namespace Tiled From 3e0ee40f5e81e2be0a38f99dfdc9e45dcd9e80b7 Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Thu, 2 Jan 2020 19:49:20 -0500 Subject: [PATCH 07/12] Remove explicit js ownership calls --- src/tiled/scriptmodule.cpp | 28 ++++++++-------------------- 1 file changed, 8 insertions(+), 20 deletions(-) diff --git a/src/tiled/scriptmodule.cpp b/src/tiled/scriptmodule.cpp index baa72a2199..6c4984952c 100644 --- a/src/tiled/scriptmodule.cpp +++ b/src/tiled/scriptmodule.cpp @@ -310,11 +310,8 @@ ScriptMapFormatWrapper *ScriptModule::mapFormat(const QString &shortName) const { const auto formats = PluginManager::objects(); for (auto format : formats) { - if (format->shortName() == shortName) { - auto wrapper = new ScriptMapFormatWrapper(format); - QQmlEngine::setObjectOwnership(wrapper, QQmlEngine::JavaScriptOwnership); - return wrapper; - } + if (format->shortName() == shortName) + return new ScriptMapFormatWrapper(format); } return nullptr; @@ -324,11 +321,8 @@ ScriptMapFormatWrapper *ScriptModule::mapFormatForFile(const QString &fileName) { const auto formats = PluginManager::objects(); for (auto format : formats) { - if (format->supportsFile(fileName)) { - auto wrapper = new ScriptMapFormatWrapper(format); - QQmlEngine::setObjectOwnership(wrapper, QQmlEngine::JavaScriptOwnership); - return wrapper; - } + if (format->supportsFile(fileName)) + return new ScriptMapFormatWrapper(format); } return nullptr; @@ -338,11 +332,8 @@ ScriptTilesetFormatWrapper *ScriptModule::tilesetFormat(const QString &shortName { const auto formats = PluginManager::objects(); for (auto format : formats) { - if (format->shortName() == shortName) { - auto wrapper = new ScriptTilesetFormatWrapper(format); - QQmlEngine::setObjectOwnership(wrapper, QQmlEngine::JavaScriptOwnership); - return wrapper; - } + if (format->shortName() == shortName) + return new ScriptTilesetFormatWrapper(format); } return nullptr; @@ -352,11 +343,8 @@ ScriptTilesetFormatWrapper *ScriptModule::tilesetFormatForFile(const QString &fi { const auto formats = PluginManager::objects(); for (auto format : formats) { - if (format->supportsFile(fileName)) { - auto wrapper = new ScriptTilesetFormatWrapper(format); - QQmlEngine::setObjectOwnership(wrapper, QQmlEngine::JavaScriptOwnership); - return wrapper; - } + if (format->supportsFile(fileName)) + return new ScriptTilesetFormatWrapper(format); } return nullptr; From f4371d08e8a0d71541462635eb4d4ea0f08dc75a Mon Sep 17 00:00:00 2001 From: Phlosioneer Date: Thu, 2 Jan 2020 20:07:21 -0500 Subject: [PATCH 08/12] Update docs --- docs/reference/scripting.rst | 72 ++++++++++++++++++------------------ 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/docs/reference/scripting.rst b/docs/reference/scripting.rst index 0f7ce90750..4a48b9e482 100644 --- a/docs/reference/scripting.rst +++ b/docs/reference/scripting.rst @@ -443,27 +443,27 @@ tiled.extendMenu(id : string, items : array | object) : void .. _script-tilesetFormat: -tiled.tilesetFormat(shortName : string) : TilesetFormatWrapper +tiled.tilesetFormat(shortName : string) : TilesetFormat Returns the tileset format object with the given name, or `undefined` if no object was found. Built in options are `tsx`, `json`, and `lua`. See the `tilesetFormats` property for more info. .. _script-tilesetFormatForFile: -tiled.tilesetFormatForFile(fileName : string) : TilesetFormatWrapper +tiled.tilesetFormatForFile(fileName : string) : TilesetFormat Returns the tileset format object that can read the given file, or `undefined` if no object was found. .. _script-mapFormat: -tiled.mapFormat(shortName : string) : MapFormatWrapper +tiled.mapFormat(shortName : string) : MapFormat Returns the map format object with the given name, or `undefined` if no object was found. Built in options are `tsx`, `csv`, `gmx`, `json`, `js`, and `lua`. See the `mapFormats` property for more info. .. _script-mapFormatForFile: -tiled.mapFormatForFile(fileName : string) : MapFormatWrapper +tiled.mapFormatForFile(fileName : string) : MapFormat Returns the map format object that can read the given file, or `undefined` if no object was found. @@ -572,6 +572,28 @@ Asset.macro(text : string, callback : function) : value The returned value is whatever the callback function returned. +.. _script-fileformat: + +File Format +^^^^^^^^^^^ + +Common functionality for file format readers and writers. (Since 1.4) + +Properties +~~~~~~~~~~ + +.. csv-table:: + widths: 1, 2 + + **canRead** : bool |ro|, Whether this format supports reading files. + **canWrite** : bool |ro|, Whether this format supports writing files. + +Functions +~~~~~~~~~ + +FileFormat.supportsFile(fileName : string) : bool + Returns whether the file is readable by this format. + .. _script-grouplayer: GroupLayer @@ -727,36 +749,25 @@ Properties .. _script-mapformatwrapper: -Map Format Wrapper -^^^^^^^^^^^^^^^^^^ +Map Format +^^^^^^^^^^ This is an object that can read or write map files. (Since 1.4) -Properties -~~~~~~~~~~ - -.. csv-table:: - :widths: 1, 2 - - **name** : string |ro|, The name of this format. - **extension** : string |ro|, "The file extension of this format, or `undefined` - if not available. Use `supportsFile` instead." +Inherits :ref:`script-fileformat`. Functions ~~~~~~~~~ -MapFormatWrapper.read(fileName : string) : :ref:`script-map` +MapFormat.read(fileName : string) : :ref:`script-map` Read the given file as a map. This function will throw an error if it is not supported. -MapFormatWrapper.write(map : :ref:`script-map`, fileName : string) : string +MapFormat.write(map : :ref:`script-map`, fileName : string) : string Write the given map to a file. This function will throw an error if it is not supported. If there is an error writing the file, it will return a description of the error; otherwise, it will return "". -MapFormatWrapper.supportsFile(fileName : string) : bool - Returns whether the file is readable by this format. - .. _script-mapview: Map View @@ -1365,36 +1376,25 @@ Properties .. _script-tilesetformatwrapper: -Tileset Format Wrapper -^^^^^^^^^^^^^^^^^^^^^^ +Tileset Format +^^^^^^^^^^^^^^ This is an object that can read or write tileset files. (Since 1.4) -Properties -~~~~~~~~~~ - -.. csv-table:: - :widths: 1, 2 - - **name** : string |ro|, The name of this format. - **extension** : string |ro|, "The file extension of this format, or `undefined` - if not available. Use `supportsFile` instead." +Inherits :ref:`script-fileformat`. Functions ~~~~~~~~~ -TilesetFormatWrapper.read(fileName : string) : :ref:`script-tileset` +TilesetFormat.read(fileName : string) : :ref:`script-tileset` Read the given file as a tileset. This function will throw an error if it is not supported. -TilesetFormatWrapper.write(tileset : :ref:`script-tileset`, fileName : string) : string +TilesetFormat.write(tileset : :ref:`script-tileset`, fileName : string) : string Write the given tileset to a file. This function will throw an error if it is not supported. If there is an error writing the file, it will return a description of the error; otherwise, it will return "". -TilesetFormatWrapper.supportsFile(fileName : string) : bool - Returns whether the file is readable by this format. - .. _script-tilesetsview: Tilesets View From f0a80095c680a86d9c5052e9a308ac9681c7cb66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorbj=C3=B8rn=20Lindeijer?= Date: Tue, 7 Jan 2020 16:50:40 +0100 Subject: [PATCH 09/12] Some formatting tweaks --- docs/reference/scripting.rst | 12 ++++++------ src/tiled/scriptfileformatwrappers.cpp | 23 ++++++++++------------- src/tiled/scriptfileformatwrappers.h | 6 +++--- src/tiled/scriptmodule.cpp | 4 ++-- 4 files changed, 21 insertions(+), 24 deletions(-) diff --git a/docs/reference/scripting.rst b/docs/reference/scripting.rst index 4a48b9e482..a0914164df 100644 --- a/docs/reference/scripting.rst +++ b/docs/reference/scripting.rst @@ -131,11 +131,11 @@ Properties **tilesetEditor** : :ref:`script-tileseteditor`, "Access the editor used when editing tilesets." **tilesetFormats** : [string] |ro|, "List of tileset format names. Built in options are `tsx`, `json`, and `lua` (write-only). Use - :ref:`tilesetFormat` to get the corresponding format object + :ref:`tilesetFormat ` to get the corresponding format object to read and write files. (Since 1.4)" **mapFormats** : [string] |ro|, "List of map format names. Built in options are `tmx`, `json`, `js`, `gmx` (write-only), and `lua` (write-only). Use - :ref:`mapFormat` to get the corresponding format object to + :ref:`mapFormat ` to get the corresponding format object to read and write files. (Since 1.4)" Functions @@ -443,27 +443,27 @@ tiled.extendMenu(id : string, items : array | object) : void .. _script-tilesetFormat: -tiled.tilesetFormat(shortName : string) : TilesetFormat +tiled.tilesetFormat(shortName : string) : :ref:`script-tilesetformatwrapper` Returns the tileset format object with the given name, or `undefined` if no object was found. Built in options are `tsx`, `json`, and `lua`. See the `tilesetFormats` property for more info. .. _script-tilesetFormatForFile: -tiled.tilesetFormatForFile(fileName : string) : TilesetFormat +tiled.tilesetFormatForFile(fileName : string) : :ref:`script-tilesetformatwrapper` Returns the tileset format object that can read the given file, or `undefined` if no object was found. .. _script-mapFormat: -tiled.mapFormat(shortName : string) : MapFormat +tiled.mapFormat(shortName : string) : :ref:`script-mapformatwrapper` Returns the map format object with the given name, or `undefined` if no object was found. Built in options are `tsx`, `csv`, `gmx`, `json`, `js`, and `lua`. See the `mapFormats` property for more info. .. _script-mapFormatForFile: -tiled.mapFormatForFile(fileName : string) : MapFormat +tiled.mapFormatForFile(fileName : string) : :ref:`script-mapformatwrapper` Returns the map format object that can read the given file, or `undefined` if no object was found. diff --git a/src/tiled/scriptfileformatwrappers.cpp b/src/tiled/scriptfileformatwrappers.cpp index 94ec7f201b..84fd05bf3a 100644 --- a/src/tiled/scriptfileformatwrappers.cpp +++ b/src/tiled/scriptfileformatwrappers.cpp @@ -1,7 +1,6 @@ /* * scriptfileformatwrappers.h - * Copyright 2019, Thorbjørn Lindeijer , Phlosioneer - * + * Copyright 2019, Phlosioneer * * This file is part of Tiled. * @@ -71,6 +70,7 @@ bool ScriptFileFormatWrapper::assertCanWrite() const return false; } + ScriptTilesetFormatWrapper::ScriptTilesetFormatWrapper(TilesetFormat* format, QObject *parent) : ScriptFileFormatWrapper(format, parent) {} @@ -81,15 +81,13 @@ EditableTileset *ScriptTilesetFormatWrapper::read(const QString &filename) return nullptr; auto tileset = static_cast(mFormat)->read(filename); - if (tileset) { - auto editable = new EditableTileset(tileset.data()); - QQmlEngine::setObjectOwnership(editable, QQmlEngine::JavaScriptOwnership); - return editable; - } else { + if (!tileset) { auto message = QCoreApplication::translate("Script Errors", "Error reading tileset"); ScriptManager::instance().throwError(message); return nullptr; } + + return new EditableTileset(tileset.data()); } void ScriptTilesetFormatWrapper::write(EditableTileset *editable, const QString &filename) @@ -103,6 +101,7 @@ void ScriptTilesetFormatWrapper::write(EditableTileset *editable, const QString ScriptManager::instance().throwError(mFormat->errorString()); } + ScriptMapFormatWrapper::ScriptMapFormatWrapper(MapFormat *format, QObject *parent) : ScriptFileFormatWrapper(format, parent) {} @@ -113,15 +112,13 @@ EditableMap *ScriptMapFormatWrapper::read(const QString &filename) return nullptr; auto map = static_cast(mFormat)->read(filename); - if (map) { - auto editable = new EditableMap(std::move(map)); - QQmlEngine::setObjectOwnership(editable, QQmlEngine::JavaScriptOwnership); - return editable; - } else { + if (!map) { auto message = QCoreApplication::translate("Script Errors", "Error reading map"); ScriptManager::instance().throwError(message); return nullptr; } + + return new EditableMap(std::move(map)); } void ScriptMapFormatWrapper::write(EditableMap *editable, const QString &filename) @@ -135,4 +132,4 @@ void ScriptMapFormatWrapper::write(EditableMap *editable, const QString &filenam ScriptManager::instance().throwError(mFormat->errorString()); } -} +} // namespace Tiled diff --git a/src/tiled/scriptfileformatwrappers.h b/src/tiled/scriptfileformatwrappers.h index 223aec9dc1..ee43a9df69 100644 --- a/src/tiled/scriptfileformatwrappers.h +++ b/src/tiled/scriptfileformatwrappers.h @@ -1,7 +1,6 @@ /* * scriptfileformatwrappers.h - * Copyright 2019, Thorbjørn Lindeijer , Phlosioneer - * + * Copyright 2019, Phlosioneer * * This file is part of Tiled. * @@ -37,6 +36,7 @@ class ScriptFileFormatWrapper : public QObject Q_PROPERTY(bool canRead READ canRead) Q_PROPERTY(bool canWrite READ canWrite) + public: explicit ScriptFileFormatWrapper(FileFormat *format, QObject *parent = nullptr); @@ -44,8 +44,8 @@ class ScriptFileFormatWrapper : public QObject bool canRead() const; bool canWrite() const; -protected: +protected: bool assertCanRead() const; bool assertCanWrite() const; diff --git a/src/tiled/scriptmodule.cpp b/src/tiled/scriptmodule.cpp index 6c4984952c..91798fd116 100644 --- a/src/tiled/scriptmodule.cpp +++ b/src/tiled/scriptmodule.cpp @@ -120,9 +120,9 @@ QStringList ScriptModule::mapFormats() const const auto formats = PluginManager::objects(); QStringList ret; ret.reserve(formats.length()); - for (auto format : formats) { + for (auto format : formats) ret.append(format->shortName()); - } + return ret; } From a656a9ecb296e123383687ea54dd4dd2c4cf7ff0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorbj=C3=B8rn=20Lindeijer?= Date: Tue, 7 Jan 2020 16:54:23 +0100 Subject: [PATCH 10/12] docs: Removed repeated listing of built-in formats There are really only two built-in formats, which are the 'tmx' and 'tsx' formats. All the others are added by plugins which can be disabled by the user. Regardless, I don't see much value in documenting this list of formats and then having to maintain those lists (which will surely be forgotten). --- docs/reference/scripting.rst | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/docs/reference/scripting.rst b/docs/reference/scripting.rst index a0914164df..62b6f31081 100644 --- a/docs/reference/scripting.rst +++ b/docs/reference/scripting.rst @@ -129,12 +129,10 @@ Properties **openAssets** : array |ro|, "List of currently opened :ref:`assets `." **mapEditor** : :ref:`script-mapeditor`, "Access the editor used when editing maps." **tilesetEditor** : :ref:`script-tileseteditor`, "Access the editor used when editing tilesets." - **tilesetFormats** : [string] |ro|, "List of tileset format names. Built in - options are `tsx`, `json`, and `lua` (write-only). Use + **tilesetFormats** : [string] |ro|, "List of supported tileset format names. Use :ref:`tilesetFormat ` to get the corresponding format object to read and write files. (Since 1.4)" - **mapFormats** : [string] |ro|, "List of map format names. Built in options - are `tmx`, `json`, `js`, `gmx` (write-only), and `lua` (write-only). Use + **mapFormats** : [string] |ro|, "List of supported map format names. Use :ref:`mapFormat ` to get the corresponding format object to read and write files. (Since 1.4)" @@ -445,8 +443,7 @@ tiled.extendMenu(id : string, items : array | object) : void tiled.tilesetFormat(shortName : string) : :ref:`script-tilesetformatwrapper` Returns the tileset format object with the given name, or `undefined` if - no object was found. Built in options are `tsx`, `json`, and `lua`. See the - `tilesetFormats` property for more info. + no object was found. See the `tilesetFormats` property for more info. .. _script-tilesetFormatForFile: @@ -458,8 +455,7 @@ tiled.tilesetFormatForFile(fileName : string) : :ref:`script-tilesetformatwrappe tiled.mapFormat(shortName : string) : :ref:`script-mapformatwrapper` Returns the map format object with the given name, or `undefined` if no object - was found. Built in options are `tsx`, `csv`, `gmx`, `json`, `js`, and `lua`. - See the `mapFormats` property for more info. + was found. See the `mapFormats` property for more info. .. _script-mapFormatForFile: From ab45e80143e8947063e1cdbda03e9025209b61a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorbj=C3=B8rn=20Lindeijer?= Date: Tue, 7 Jan 2020 16:58:36 +0100 Subject: [PATCH 11/12] Removed the unused name/extensions getters --- src/tiled/scriptedfileformat.cpp | 16 +++------------- src/tiled/scriptedfileformat.h | 9 --------- 2 files changed, 3 insertions(+), 22 deletions(-) diff --git a/src/tiled/scriptedfileformat.cpp b/src/tiled/scriptedfileformat.cpp index 84f50ad55b..fa6be10811 100644 --- a/src/tiled/scriptedfileformat.cpp +++ b/src/tiled/scriptedfileformat.cpp @@ -61,10 +61,10 @@ QString ScriptedFileFormat::nameFilter() const bool ScriptedFileFormat::supportsFile(const QString &fileName) const { - QString ext = extension(); - ext.prepend(QLatin1Char('.')); + QString extension = mObject.property(QStringLiteral("extension")).toString(); + extension.prepend(QLatin1Char('.')); - return fileName.endsWith(ext); + return fileName.endsWith(extension); } QJSValue ScriptedFileFormat::read(const QString &fileName) @@ -131,16 +131,6 @@ QStringList ScriptedFileFormat::outputFiles(EditableAsset *asset, const QString return QStringList(fileName); } -QString ScriptedFileFormat::name() const -{ - return mObject.property(QStringLiteral("name")).toString(); -} - -QString ScriptedFileFormat::extension() const -{ - return mObject.property(QStringLiteral("extension")).toString(); -} - bool ScriptedFileFormat::validateFileFormatObject(const QJSValue &value) { const QJSValue nameProperty = value.property(QStringLiteral("name")); diff --git a/src/tiled/scriptedfileformat.h b/src/tiled/scriptedfileformat.h index 41a99c15ef..d7ffe3f004 100644 --- a/src/tiled/scriptedfileformat.h +++ b/src/tiled/scriptedfileformat.h @@ -44,9 +44,6 @@ class ScriptedFileFormat QStringList outputFiles(EditableAsset *asset, const QString &fileName) const; - QString name() const; - QString extension() const; - static bool validateFileFormatObject(const QJSValue &value); private: @@ -75,9 +72,6 @@ class ScriptedMapFormat final : public MapFormat std::unique_ptr read(const QString &fileName) override; bool write(const Map *map, const QString &fileName, Options options) override; - QString name() const { return mFormat.name(); } - QString extension() const { return mFormat.extension(); } - private: QString mShortName; QString mError; @@ -105,9 +99,6 @@ class ScriptedTilesetFormat final : public TilesetFormat SharedTileset read(const QString &fileName) override; bool write(const Tileset &tileset, const QString &fileName, Options options = Options()) override; - QString name() const { return mFormat.name(); } - QString extension() const { return mFormat.extension(); } - private: QString mShortName; QString mError; From 2fded5754827ebb2cf5ae85165030518763c6c49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorbj=C3=B8rn=20Lindeijer?= Date: Tue, 7 Jan 2020 16:59:55 +0100 Subject: [PATCH 12/12] Another small code formatting tweak --- src/tiled/scriptmodule.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tiled/scriptmodule.cpp b/src/tiled/scriptmodule.cpp index 91798fd116..92030406e2 100644 --- a/src/tiled/scriptmodule.cpp +++ b/src/tiled/scriptmodule.cpp @@ -131,9 +131,9 @@ QStringList ScriptModule::tilesetFormats() const const auto formats = PluginManager::objects(); QStringList ret; ret.reserve(formats.length()); - for (auto format : formats) { + for (auto format : formats) ret.append(format->shortName()); - } + return ret; }