Docs: Add audio module architecture design document

- Add XCEngine音频模块架构设计.md
- Design audio system following Unity-style architecture
- Include AudioSourceComponent, AudioListenerComponent, AudioClip, AudioMixer
- Document DSP effect system (FFT, Reverb, EQ, Compressor)
- Document 3D spatial audio with HRTF support
- Define IAudioBackend abstraction layer with WASAPI/OpenAL backends
- Outline 5-phase implementation priorities
This commit is contained in:
2026-03-20 19:59:06 +08:00
parent 394bec9db6
commit 810b0861c5
11 changed files with 2893 additions and 0 deletions

151
engine/src/Scene/Scene.cpp Normal file
View File

@@ -0,0 +1,151 @@
#include "Scene/Scene.h"
#include "Components/GameObject.h"
namespace XCEngine {
namespace Components {
Scene::Scene()
: m_name("Untitled") {
}
Scene::Scene(const std::string& name)
: m_name(name) {
}
Scene::~Scene() {
m_gameObjects.clear();
}
GameObject* Scene::CreateGameObject(const std::string& name, GameObject* parent) {
auto gameObject = std::make_unique<GameObject>(name);
GameObject* ptr = gameObject.get();
m_gameObjectIDs.insert(ptr->m_id);
m_gameObjects.emplace(ptr->m_id, std::move(gameObject));
if (parent) {
ptr->SetParent(parent);
} else {
m_rootGameObjects.push_back(ptr->m_id);
}
ptr->m_scene = this;
ptr->Awake();
m_onGameObjectCreated.Invoke(ptr);
return ptr;
}
void Scene::DestroyGameObject(GameObject* gameObject) {
if (!gameObject || gameObject->m_scene != this) {
return;
}
for (auto* child : gameObject->GetChildren()) {
DestroyGameObject(child);
}
if (gameObject->m_parent) {
auto& siblings = gameObject->m_parent->m_children;
siblings.erase(std::remove(siblings.begin(), siblings.end(), gameObject), siblings.end());
} else {
m_rootGameObjects.erase(
std::remove(m_rootGameObjects.begin(), m_rootGameObjects.end(), gameObject->m_id),
m_rootGameObjects.end()
);
}
m_onGameObjectDestroyed.Invoke(gameObject);
gameObject->OnDestroy();
m_gameObjectIDs.erase(gameObject->m_id);
m_gameObjects.erase(gameObject->m_id);
}
GameObject* Scene::Find(const std::string& name) const {
for (auto* go : GetRootGameObjects()) {
if (go->GetName() == name) {
return go;
}
GameObject* found = FindInChildren(go, name);
if (found) {
return found;
}
}
return nullptr;
}
GameObject* Scene::FindInChildren(GameObject* parent, const std::string& name) const {
for (size_t i = 0; i < parent->GetChildCount(); ++i) {
GameObject* child = parent->GetChild(i);
if (child->GetName() == name) {
return child;
}
GameObject* found = FindInChildren(child, name);
if (found) {
return found;
}
}
return nullptr;
}
GameObject* Scene::FindGameObjectWithTag(const std::string& tag) const {
for (auto* go : GetRootGameObjects()) {
if (go->GetName() == tag) {
return go;
}
GameObject* found = FindInChildren(go, tag);
if (found) {
return found;
}
}
return nullptr;
}
std::vector<GameObject*> Scene::GetRootGameObjects() const {
std::vector<GameObject*> result;
for (auto id : m_rootGameObjects) {
auto it = m_gameObjects.find(id);
if (it != m_gameObjects.end()) {
result.push_back(it->second.get());
}
}
return result;
}
void Scene::Update(float deltaTime) {
for (auto* go : GetRootGameObjects()) {
if (go->IsActiveInHierarchy()) {
go->Update(deltaTime);
}
}
}
void Scene::FixedUpdate(float fixedDeltaTime) {
for (auto* go : GetRootGameObjects()) {
if (go->IsActiveInHierarchy()) {
go->FixedUpdate();
}
}
}
void Scene::LateUpdate(float deltaTime) {
for (auto* go : GetRootGameObjects()) {
if (go->IsActiveInHierarchy()) {
go->LateUpdate(deltaTime);
}
}
}
void Scene::Load(const std::string& filePath) {
m_gameObjects.clear();
m_rootGameObjects.clear();
}
void Scene::Save(const std::string& filePath) {
}
} // namespace Components
} // namespace XCEngine