// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
#pragma once
// Enables locking scenes during scene query execution can provide some safety when using scene queries from other threads but may provide stalls on a main thread
#define SCENE_QUERIES_WITH_LOCK 1
#include "Level.h"
#include "Scene/Scene.h"
#if SCENE_QUERIES_WITH_LOCK
#include "Engine/Threading/Threading.h"
#endif
///
/// Helper class to perform scene actions and queries
///
class FLAXENGINE_API SceneQuery
{
public:
///
/// Try to find actor hit by the given ray.
///
/// Ray to test
/// Hit actor or nothing
static Actor* RaycastScene(const Ray& ray);
public:
///
/// Gets all scene objects from the actor into linear list. Appends them (without the given actor).
///
/// The root actor.
/// The objects output.
static void GetAllSceneObjects(Actor* root, Array& objects);
///
/// Gets all scene objects (for serialization) from the actor into linear list. Appends them (including the given actor).
///
/// The root actor.
/// The objects output.
static void GetAllSerializableSceneObjects(Actor* root, Array& objects);
///
/// Gets all actors from the actor into linear list. Appends them (without the given actor).
///
/// The root actor.
/// The actors output.
static void GetAllActors(Actor* root, Array& actors);
///
/// Gets all actors from the loaded scenes into linear list (without scene actors).
///
/// The actors output.
static void GetAllActors(Array& actors);
public:
///
/// Execute custom action on actors tree.
///
/// Actor to call on every actor in the tree. Returns true if keep calling deeper.
/// Custom arguments for the function
template
static void TreeExecute(Function& action, Params... args)
{
#if SCENE_QUERIES_WITH_LOCK
ScopeLock lock(Level::ScenesLock);
#endif
for (int32 i = 0; i < Level::Scenes.Count(); i++)
Level::Scenes.Get()[i]->TreeExecute(action, args...);
}
};