#include "stdafx.h" #include #include "../Commands/CommandBuffer.h" #include "IResourceFactory.h" #include "RenderCommandNode.h" RenderCommandNode::RenderCommandNode(IEngine& argEngine) : m_Engine(argEngine) , m_Dirty(true) , m_ParentNode(NULL) , m_CommandBuffer(NULL) { } RenderCommandNode::~RenderCommandNode() { if (m_ParentNode != NULL) m_ParentNode->RemoveCommandUser(*this); while (!m_CommandUsers.empty()) RemoveCommandUser(**m_CommandUsers.begin()); delete m_CommandBuffer; m_Engine.get_ResourceFactory().DeleteRenderCommandNode(*const_cast(this), true); } const std::vector RenderCommandNode::get_CommandUsers() const { return m_CommandUsers; } void RenderCommandNode::set_Parent(IRenderCommandNode* ar_Node_) { m_ParentNode = ar_Node_; } IRenderCommandNode* RenderCommandNode::get_Parent() const { return m_ParentNode; } bool RenderCommandNode::IsDirty() const { return m_Dirty; } void RenderCommandNode::MarkDirty() { m_Dirty = true; if (m_ParentNode != NULL) m_ParentNode->MarkDirty(); } void RenderCommandNode::AddCommandUser(ICommandUser& argCommandUser) { argCommandUser.AssignToRenderCommandNode(*const_cast(this)); m_CommandUsers.push_back(&argCommandUser); IRenderCommandNode* node = dynamic_cast(&argCommandUser); if (node != NULL) node->set_Parent(this); this->MarkDirty(); } void RenderCommandNode::RemoveCommandUser(ICommandUser& argCommandUser) { std::vector::iterator found = std::find(m_CommandUsers.begin(), m_CommandUsers.end(), &argCommandUser); if (found != m_CommandUsers.end()) { IRenderCommandNode* node = dynamic_cast(&argCommandUser); if (node != NULL) node->set_Parent(NULL); m_CommandUsers.erase(found); argCommandUser.UnassignFromRenderCommandNode(*const_cast(this)); this->MarkDirty(); } } void RenderCommandNode::ReplaceCommandUser(ICommandUser& argWhatCommandUser, ICommandUser& argWhithCommandUser) { std::vector::iterator found = std::find(m_CommandUsers.begin(), m_CommandUsers.end(), &argWhatCommandUser); if (found != m_CommandUsers.end()) { IRenderCommandNode* node = dynamic_cast(&argWhatCommandUser); if (node != NULL) node->set_Parent(NULL); m_CommandUsers.insert(found, &argWhithCommandUser); m_CommandUsers.erase(found); argWhatCommandUser.UnassignFromRenderCommandNode(*const_cast(this)); argWhithCommandUser.AssignToRenderCommandNode(*const_cast(this)); node = dynamic_cast(&argWhithCommandUser); if (node != NULL) node->set_Parent(this); this->MarkDirty(); } } void RenderCommandNode::ProcessCommands() { if (m_Dirty) { this->GenerateDeviceCommands(); m_CommandBuffer->Optimize(); } m_CommandBuffer->Perform(true); } void RenderCommandNode::Update(bool argForceUpdate) { // Walk through all updatables and update them. for (uint32 i = 0; i < m_CommandUsers.size(); ++i) { IUpdatable* updatable = dynamic_cast(m_CommandUsers[i]); if (updatable != NULL && (updatable->get_WantsUpdate() || argForceUpdate)) updatable->Update(argForceUpdate); } } bool RenderCommandNode::get_WantsUpdate() const { return true; } CommandExecuteResult::Enumeration RenderCommandNode::ExecuteCommand(unsigned char argCommandType, ICommandBuffer& argCurrentBuffer, uint32 argCurrentPositon) { return CommandExecuteResult::None; } void RenderCommandNode::GenerateDeviceCommands() { if (!m_Dirty) return; m_Dirty = false; if (m_CommandBuffer == NULL) m_CommandBuffer = new CommandBuffer(false, false); else m_CommandBuffer->Clear(); for (uint32 i = 0; i < m_CommandUsers.size(); ++i) { // Add the commands all commands const std::vector& commands = m_CommandUsers[i]->GetCommands(); for (uint32 k = 0; k < commands.size(); ++k) m_CommandBuffer->AddCommand(*commands[k]); // Walk further if we found another RenderCommandNode IRenderCommandNodeInternal* nodeInternal = dynamic_cast(m_CommandUsers[i]); if (nodeInternal != NULL) { nodeInternal->GenerateDeviceCommands(); // Merge the buffers ICommandBuffer* otherBuffer = nodeInternal->get_CommandBuffer(); if (otherBuffer != NULL) m_CommandBuffer->AddChildCommandBuffer(*otherBuffer); } } } ICommandBuffer* RenderCommandNode::get_CommandBuffer() const { return m_CommandBuffer; }