Photon Editor Library 2.0.0-beta
A physically based renderer.
Loading...
Searching...
No Matches
DesignerScene.h
Go to the documentation of this file.
1#pragma once
2
8
9#include <Common/primitive_type.h>
10#include <Common/logging.h>
11#include <Utility/TUniquePtrVector.h>
12#include <Utility/TSpan.h>
13#include <SDL/Object.h>
14#include <SDL/sdl_interface.h>
15#include <SDL/SceneDescription.h>
16#include <Utility/IMoveOnly.h>
17#include <DataIO/FileSystem/Path.h>
18#include <DataIO/FileSystem/ResourceIdentifier.h>
19#include <Utility/TFunction.h>
20
21#include <vector>
22#include <memory>
23#include <cstddef>
24#include <string>
25#include <string_view>
26#include <functional>
27#include <unordered_map>
28#include <array>
29
30namespace ph { class SdlClass; }
31namespace ph::editor::render { class System; }
32namespace ph::editor::render { class Scene; }
33namespace ph::editor::render { class RealtimeRenderer; }
34namespace ph::editor::render { class OfflineRenderer; }
35
36namespace ph::editor
37{
38
39class Editor;
40class MainThreadUpdateContext;
41class MainThreadRenderUpdateContext;
42class RenderThreadCaller;
43class RenderAgent;
44
46
54
55class DesignerScene final
56 : public Object
57 , private IMoveOnly
58{
59public:
60 // Work type should be kept in sync with `RenderThread::Work`
61 using RenderWorkType = TFunction<void(render::System&)>;
62
63 static const char* defaultSceneName();
64
65public:
66 explicit DesignerScene(Editor* fromEditor);
67 DesignerScene(DesignerScene&& other) noexcept;
68 ~DesignerScene() override;
69
70 void update(const MainThreadUpdateContext& ctx);
73 void beforeUpdateStage();
74 void afterUpdateStage();
75 void beforeRenderStage();
76 void afterRenderStage();
77
83
89
91 TSpanView<DesignerObject*> getSelection() const;
92 void clearSelection();
93
94 void changeObjectVisibility(DesignerObject* obj, bool shouldBeVisible);
95 void changeObjectTick(DesignerObject* obj, bool shouldTick);
96 void changeObjectRenderTick(DesignerObject* obj, bool shouldTick);
97
105
107 template<typename ObjectType>
108 [[nodiscard]]
109 ObjectType* newObject(
110 bool shouldInit = true,
111 bool shouldSetToDefault = true);
112
115 template<typename ObjectType>
116 ObjectType* newRootObject(
117 bool shouldInit = true,
118 bool shouldSetToDefault = true);
119
124 template<typename ObjectType>
125 std::shared_ptr<ObjectType> newSharedRootObject(
126 bool shouldInit = true,
127 bool shouldSetToDefault = true);
129
137
139 [[nodiscard]]
141 const SdlClass* clazz,
142 bool shouldInit = true,
143 bool shouldSetToDefault = true);
144
148 const SdlClass* clazz,
149 bool shouldInit = true,
150 bool shouldSetToDefault = true);
151
154 std::shared_ptr<DesignerObject> newSharedRootObject(
155 const SdlClass* clazz,
156 bool shouldInit = true,
157 bool shouldSetToDefault = true);
159
165 void initObject(DesignerObject* obj);
166
170
171 void deleteObject(
172 DesignerObject* obj,
173 bool shouldDeleteRecursively = true);
174
175 void renderCleanup(RenderThreadCaller& caller);
176 void cleanup();
177
178 Editor& getEditor();
179 const Editor& getEditor() const;
181 const render::Scene& getRendererScene() const;
184 TSpanView<DesignerRendererBinding> getRendererBindings() const;
185
189 const std::string& getName() const;
190
194 SceneDescription& getRenderDescription();
195
199 const SceneDescription& getRenderDescription() const;
200
204 const ResourceIdentifier& getRenderDescriptionLink() const;
205
206 void setRenderDescriptionLink(ResourceIdentifier link);
207 TSpanView<DesignerObject*> getRootObjects() const;
208 std::string getUniqueObjectName(const std::string& intendedName);
209
214 void pause();
215
219 void resume();
220
225 bool isPaused() const;
226
229 template<typename ObjectType = DesignerObject>
230 ObjectType* findObjectByName(std::string_view name) const;
231
236 template<typename ObjectType>
237 void findObjectsByType(std::vector<ObjectType*>& out_objs) const;
238
248 template<typename PerObjectOperation>
249 void forEachUsableObject(PerObjectOperation op) const;
250
252
253 const Path& getWorkingDirectory() const;
254 void setWorkingDirectory(Path directory);
255 void setName(std::string name);
256
257 std::size_t numRootObjects() const;
258 std::size_t numTickingObjects() const;
259 std::size_t numRenderTickingObjects() const;
260 std::size_t numAllocatedObjects() const;
261
263
268 static bool isFullyInitialized(const DesignerObject& obj);
269
274 static bool isInitialized(const DesignerObject& obj);
275
276// Begin Scene Events
277public:
278 template<typename EventType>
280
283// End Scene Events
284
285private:
286 struct SceneAction
287 {
288 using UpdateTask = TFunction<bool(const MainThreadUpdateContext& ctx), 32>;
289 using RenderTask = TFunction<bool(RenderThreadCaller& caller), 32>;
290
291 UpdateTask updateTask;
292 RenderTask renderTask;
293
294 bool isDone() const;
295 };
296
297 struct RenderWork
298 {
299 RenderWorkType work;
300 DesignerObject* obj = nullptr;
301 };
302
303 void enqueueCreateObjectAction(DesignerObject* obj);
304 void enqueueRemoveObjectAction(DesignerObject* obj);
305 void enqueueObjectTickAction(DesignerObject* obj, bool shouldTick);
306 void enqueueObjectRenderTickAction(DesignerObject* obj, bool shouldTick);
307 void enqueueSceneAction(SceneAction action);
308
309 template<typename ObjectType, typename... DeducedArgs>
310 ObjectType* makeObjectFromStorage(DeducedArgs&&... args);
311
312 bool removeObjectFromStorage(DesignerObject* obj);
313
314 void ensureOwnedByThisScene(const DesignerObject* obj) const;
315
316 // TODO: rethink more specific use case other than for retargeting object parent
317 static bool isOrphan(const DesignerObject& obj);
318
319private:
320 // Working directory is only set when it can be determined (e.g., during loading).
321 // Not saved as working directory can be different on each load.
322 Path m_workingDirectory;
323
324 TUniquePtrVector<DesignerObject> m_objStorage;
325 std::vector<uint64> m_freeObjStorageIndices;
326 std::vector<DesignerObject*> m_rootObjs;
327 std::vector<DesignerObject*> m_tickingObjs;
328 std::vector<DesignerObject*> m_renderTickingObjs;
329 std::vector<DesignerObject*> m_selectedObjs;
330 std::vector<SceneAction> m_sceneActionQueue;
331 std::vector<RenderWork> m_renderWorkQueue;
332 std::size_t m_numSceneActionsToProcess;
333
334 Editor* m_editor;
335 render::Scene* m_rendererScene;
336 std::vector<DesignerRendererBinding> m_rendererBindings;
337 SceneDescription m_renderDescription;
338 ViewportCamera m_mainCamera;
339 uint32 m_isPaused : 1;
340
341 // SDL-binded fields:
342 std::string m_name;
343 ResourceIdentifier m_renderDescriptionLink;
344
348private:
349 using DynamicObjectMaker = std::function<DesignerObject*(DesignerScene& scene)>;
350 static std::unordered_map<const SdlClass*, DynamicObjectMaker> classToObjMaker;
351
352public:
353 template<typename ObjectType>
354 static void registerObjectType();
355
356 static std::vector<const SdlClass*> getAllObjectClasses();
358
359public:
360 PH_DEFINE_SDL_CLASS(TSdlOwnerClass<DesignerScene>)
361 {
362 ClassType clazz("dscene");
363 clazz.docName("Designer Scene");
364 clazz.description("Designer scene. The main container of designer objects.");
365
366 // Creation and removal should be handled by editor
367 clazz.allowCreateFromClass(false);
368
369 clazz.baseOn<Object>();
370
371 TSdlString<OwnerType> name("name", &OwnerType::m_name);
372 name.description("Name of the designer scene.");
373 name.defaultTo(defaultSceneName());
374 clazz.addField(name);
375
376 TSdlResourceIdentifier<OwnerType> renderDescriptionLink("render-description-link", &OwnerType::m_renderDescriptionLink);
377 renderDescriptionLink.description("Storage location of the associated scene description.");
378 renderDescriptionLink.defaultTo(ResourceIdentifier());
379 clazz.addField(renderDescriptionLink);
380
381 return clazz;
382 }
383};
384
385}// end namespace ph::editor
386
Definition DesignerObject.h:31
Definition DesignerScene.h:48
render::OfflineRenderer * offlineRenderer
Definition DesignerScene.h:52
render::RealtimeRenderer * realtimeRenderer
Definition DesignerScene.h:51
RenderAgent * agent
Definition DesignerScene.h:50
Definition DesignerScene.h:58
void beforeRenderStage()
Definition DesignerScene.cpp:205
std::string getUniqueObjectName(const std::string &intendedName)
Definition DesignerScene.cpp:702
static std::vector< const SdlClass * > getAllObjectClasses()
Definition DesignerScene.cpp:771
DesignerScene(DesignerScene &&other) noexcept
void findObjectsByType(std::vector< ObjectType * > &out_objs) const
Find usable objects of a matching type.
Definition DesignerScene.ipp:333
void clearSelection()
Definition DesignerScene.cpp:257
Editor & getEditor()
Definition DesignerScene.ipp:203
static bool isInitialized(const DesignerObject &obj)
Definition DesignerScene.ipp:189
void removeRendererBinding(RenderAgent *agent)
Definition DesignerScene.cpp:692
static void registerObjectType()
Definition DesignerScene.ipp:128
void setRenderDescriptionLink(ResourceIdentifier link)
Definition DesignerScene.ipp:278
const ResourceIdentifier & getRenderDescriptionLink() const
Definition DesignerScene.ipp:273
DesignerObject * getPrimarySelectedObject() const
Definition DesignerScene.ipp:233
DesignerScene & operator=(DesignerScene &&rhs) noexcept
void createRenderCommands(RenderThreadCaller &caller)
Definition DesignerScene.cpp:134
void renderUpdate(const MainThreadRenderUpdateContext &ctx)
Definition DesignerScene.cpp:121
std::size_t numRenderTickingObjects() const
Definition DesignerScene.ipp:410
ObjectType * newObject(bool shouldInit=true, bool shouldSetToDefault=true)
Create a new object.
Definition DesignerScene.ipp:47
TSpanView< DesignerRendererBinding > getRendererBindings() const
Definition DesignerScene.ipp:253
ObjectType * findObjectByName(std::string_view name) const
Find a usable object with the specified name.
Definition DesignerScene.ipp:294
void pause()
Temporarily stop the update of scene. When paused, most scene states should not be changed,...
Definition DesignerScene.cpp:736
void renderCleanup(RenderThreadCaller &caller)
Definition DesignerScene.cpp:611
render::Scene & getRendererScene()
Definition DesignerScene.ipp:215
void cleanup()
Definition DesignerScene.cpp:646
const Path & getWorkingDirectory() const
Definition DesignerScene.ipp:248
bool selectObject(DesignerObject *obj)
Definition DesignerScene.cpp:211
static const char * defaultSceneName()
Definition DesignerScene.ipp:41
std::size_t numAllocatedObjects() const
Definition DesignerScene.ipp:415
std::shared_ptr< ObjectType > newSharedRootObject(bool shouldInit=true, bool shouldSetToDefault=true)
Create root object with automatic lifetime management. The root object will delete itself once the sh...
Definition DesignerScene.ipp:75
TSceneEventDispatcher< DesignerObjectRemovalEvent > onObjectRemoval
Definition DesignerScene.h:282
TSpanView< DesignerObject * > getSelection() const
Definition DesignerScene.ipp:238
void initObject(DesignerObject *obj)
Initialize the object. By default this is called automatically when creating new object....
Definition DesignerScene.cpp:363
TSceneEventDispatcher< DesignerObjectAddedEvent > onObjectAdded
Definition DesignerScene.h:281
bool isPaused() const
Whether the scene is pausing. When the scene is pausing, object and scene states should not be modifi...
Definition DesignerScene.ipp:288
void changeObjectRenderTick(DesignerObject *obj, bool shouldTick)
Definition DesignerScene.cpp:290
DesignerScene(Editor *fromEditor)
Definition DesignerScene.cpp:39
void update(const MainThreadUpdateContext &ctx)
Definition DesignerScene.cpp:77
void addRendererBinding(DesignerRendererBinding binding)
Definition DesignerScene.cpp:682
std::size_t numTickingObjects() const
Definition DesignerScene.ipp:405
void beforeUpdateStage()
Definition DesignerScene.cpp:199
TFunction< void(render::System &)> RenderWorkType
Definition DesignerScene.h:61
void afterRenderStage()
Definition DesignerScene.cpp:208
void setObjectToDefault(DesignerObject *obj)
Set object data to SDL-defined default values.
Definition DesignerScene.cpp:383
void enqueueObjectRenderWork(DesignerObject *obj, RenderWorkType work)
Definition DesignerScene.cpp:639
void setName(std::string name)
Definition DesignerScene.cpp:751
void afterUpdateStage()
Definition DesignerScene.cpp:202
static bool isFullyInitialized(const DesignerObject &obj)
Definition DesignerScene.ipp:183
void changeObjectTick(DesignerObject *obj, bool shouldTick)
Definition DesignerScene.cpp:285
TSpanView< DesignerObject * > getRootObjects() const
Definition DesignerScene.ipp:283
bool deselectObject(DesignerObject *obj)
Definition DesignerScene.cpp:231
void forEachUsableObject(PerObjectOperation op) const
Definition DesignerScene.ipp:364
void resume()
Continue the update of scene. Resuming an already-resumed scene has no effect.
Definition DesignerScene.cpp:741
~DesignerScene() override
Definition DesignerScene.cpp:69
void changeObjectVisibility(DesignerObject *obj, bool shouldBeVisible)
Definition DesignerScene.cpp:266
std::size_t numRootObjects() const
Definition DesignerScene.ipp:400
ObjectType * newRootObject(bool shouldInit=true, bool shouldSetToDefault=true)
Create a new root object.
Definition DesignerScene.ipp:61
void setWorkingDirectory(Path directory)
Definition DesignerScene.cpp:746
SceneDescription & getRenderDescription()
Definition DesignerScene.ipp:263
PH_DEFINE_SDL_CLASS(TSdlOwnerClass< DesignerScene >)
Definition DesignerScene.h:360
const std::string & getName() const
Definition DesignerScene.ipp:258
void deleteObject(DesignerObject *obj, bool shouldDeleteRecursively=true)
Definition DesignerScene.cpp:394
Definition Editor.h:45
Definition MainThreadRenderUpdateContext.h:11
Definition MainThreadUpdateContext.h:11
Definition RenderAgent.h:16
Thin wrapper for render thread interactions from another thread. Mainly to hide unrelated render thre...
Definition RenderThreadCaller.h:16
Definition TClassEventDispatcher.h:13
Definition OfflineRenderer.h:27
Definition RealtimeRenderer.h:9
A scene for the editor renderer only.
Definition Scene.h:34
Definition System.h:26
Definition DesignerObject.h:19
Definition ph_editor.h:10
PH_DECLARE_LOG_GROUP(DesignerScene)
Definition ph_editor.h:5