1 /*
2 * editablemanager.cpp
3 * Copyright 2019, Thorbjørn Lindeijer <bjorn@lindeijer.nl>
4 *
5 * This file is part of Tiled.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation; either version 2 of the License, or (at your option)
10 * any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "editablemanager.h"
22
23 #include "editablegrouplayer.h"
24 #include "editableimagelayer.h"
25 #include "editablemap.h"
26 #include "editableobjectgroup.h"
27 #include "editabletile.h"
28 #include "editabletilelayer.h"
29 #include "editabletileset.h"
30 #include "editablewangset.h"
31 #include "scriptmanager.h"
32 #include "wangset.h"
33
34 #include <QQmlEngine>
35
36 namespace Tiled {
37
becomesNullValue(QObject * object)38 static bool becomesNullValue(QObject *object)
39 {
40 return ScriptManager::instance().engine()->newQObject(object).isNull();
41 }
42
43 std::unique_ptr<EditableManager> EditableManager::mInstance;
44
EditableManager(QObject * parent)45 EditableManager::EditableManager(QObject *parent)
46 : QObject(parent)
47 {
48 }
49
instance()50 EditableManager &EditableManager::instance()
51 {
52 if (!mInstance)
53 mInstance.reset(new EditableManager);
54 return *mInstance;
55 }
56
deleteInstance()57 void EditableManager::deleteInstance()
58 {
59 mInstance.reset();
60 }
61
release(Layer * layer)62 void EditableManager::release(Layer *layer)
63 {
64 if (EditableLayer *editable = find(layer))
65 editable->hold();
66 else
67 delete layer;
68 }
69
release(MapObject * mapObject)70 void EditableManager::release(MapObject *mapObject)
71 {
72 if (EditableMapObject *editable = find(mapObject))
73 editable->hold();
74 else
75 delete mapObject;
76 }
77
78 /**
79 * Releases the WangSet by either finding an EditableWangSet instance to take
80 * ownership of it or deleting it.
81 */
release(std::unique_ptr<WangSet> wangSet)82 void EditableManager::release(std::unique_ptr<WangSet> wangSet)
83 {
84 if (EditableWangSet *editable = find(wangSet.get())) {
85 editable->hold();
86 wangSet.release();
87 }
88 }
89
editableLayer(EditableMap * map,Layer * layer)90 EditableLayer *EditableManager::editableLayer(EditableMap *map, Layer *layer)
91 {
92 if (!layer)
93 return nullptr;
94
95 Q_ASSERT(!map || layer->map() == map->map());
96
97 EditableLayer* &editableLayer = mEditableLayers[layer];
98 if (becomesNullValue(editableLayer)) {
99 switch (layer->layerType()) {
100 case Layer::TileLayerType:
101 editableLayer = new EditableTileLayer(map, static_cast<TileLayer*>(layer));
102 break;
103 case Layer::ObjectGroupType:
104 editableLayer = new EditableObjectGroup(map, static_cast<ObjectGroup*>(layer));
105 break;
106 case Layer::ImageLayerType:
107 editableLayer = new EditableImageLayer(map, static_cast<ImageLayer*>(layer));
108 break;
109 case Layer::GroupLayerType:
110 editableLayer = new EditableGroupLayer(map, static_cast<GroupLayer*>(layer));
111 break;
112 }
113 QQmlEngine::setObjectOwnership(editableLayer, QQmlEngine::JavaScriptOwnership);
114 }
115
116 return editableLayer;
117 }
118
editableObjectGroup(EditableAsset * asset,ObjectGroup * objectGroup)119 EditableObjectGroup *EditableManager::editableObjectGroup(EditableAsset *asset, ObjectGroup *objectGroup)
120 {
121 if (!objectGroup)
122 return nullptr;
123
124 EditableLayer* &editableLayer = mEditableLayers[objectGroup];
125 if (becomesNullValue(editableLayer)) {
126 editableLayer = new EditableObjectGroup(asset, objectGroup);
127 QQmlEngine::setObjectOwnership(editableLayer, QQmlEngine::JavaScriptOwnership);
128 }
129
130 return static_cast<EditableObjectGroup*>(editableLayer);
131 }
132
editableMapObject(EditableAsset * asset,MapObject * mapObject)133 EditableMapObject *EditableManager::editableMapObject(EditableAsset *asset, MapObject *mapObject)
134 {
135 if (!mapObject)
136 return nullptr;
137
138 Q_ASSERT(mapObject->objectGroup());
139
140 EditableMapObject* &editableMapObject = mEditableMapObjects[mapObject];
141 if (becomesNullValue(editableMapObject)) {
142 editableMapObject = new EditableMapObject(asset, mapObject);
143 QQmlEngine::setObjectOwnership(editableMapObject, QQmlEngine::JavaScriptOwnership);
144 }
145
146 return editableMapObject;
147 }
148
editableTileset(Tileset * tileset)149 EditableTileset *EditableManager::editableTileset(Tileset *tileset)
150 {
151 if (!tileset)
152 return nullptr;
153
154 EditableTileset* &editableTileset = mEditableTilesets[tileset];
155 if (becomesNullValue(editableTileset)) {
156 editableTileset = new EditableTileset(tileset);
157 QQmlEngine::setObjectOwnership(editableTileset, QQmlEngine::JavaScriptOwnership);
158 }
159
160 return editableTileset;
161 }
162
editableTile(EditableTileset * tileset,Tile * tile)163 EditableTile *EditableManager::editableTile(EditableTileset *tileset, Tile *tile)
164 {
165 if (!tile)
166 return nullptr;
167
168 Q_ASSERT(tile->tileset() == tileset->tileset());
169
170 EditableTile* &editableTile = mEditableTiles[tile];
171 if (becomesNullValue(editableTile)) {
172 editableTile = new EditableTile(tileset, tile);
173 QQmlEngine::setObjectOwnership(editableTile, QQmlEngine::JavaScriptOwnership);
174 }
175
176 return editableTile;
177 }
178
editableWangSet(EditableTileset * tileset,WangSet * wangSet)179 EditableWangSet *EditableManager::editableWangSet(EditableTileset *tileset, WangSet *wangSet)
180 {
181 if (!wangSet)
182 return nullptr;
183
184 Q_ASSERT(wangSet->tileset() == tileset->tileset());
185
186 EditableWangSet* &editableWangSet = mEditableWangSets[wangSet];
187 if (becomesNullValue(editableWangSet)) {
188 editableWangSet = new EditableWangSet(tileset, wangSet);
189 QQmlEngine::setObjectOwnership(editableWangSet, QQmlEngine::JavaScriptOwnership);
190 }
191
192 return editableWangSet;
193 }
194
195 } // namespace Tiled
196
197 #include "moc_editablemanager.cpp"
198