Files
bluflame/aiwaz/Backup/Aiwaz.Resources/RenderCommandNode.cs
2026-04-18 22:31:51 +02:00

180 lines
5.4 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Aiwaz.Contracts;
using Aiwaz.Core;
using Aiwaz.Resources.Attributes;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
namespace Aiwaz.Resources
{
[AiwazResource("RenderCommand Node", "Node to update and perform other nodes.")]
public class RenderCommandNode : CommandUser, IUpdatable
{
#region IRenderCommandNode Members
private ObservableCollection<IResource> children;
public CommandBuffer CommandBuffer { get; protected set; }
public bool IsDirty { get; protected set;}
public RenderCommandNode ParentRenderCommandNode { get; set; }
public RenderCommandNode()
{
Console.WriteLine(string.Format("Creating RenderCommandNode.."));
children = new ObservableCollection<IResource>();
children.CollectionChanged += new NotifyCollectionChangedEventHandler(children_CollectionChanged);
CommandBuffer = new CommandBuffer();
}
void children_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
List<CommandUser> commandUsers = new List<CommandUser>();
if (e.Action == NotifyCollectionChangedAction.Add)
{
foreach (IResource resource in e.NewItems)
GetCommandUsers(resource, ref commandUsers);
foreach (CommandUser user in commandUsers)
{
user.AssignToRenderCommandNode(this);
var node = user as RenderCommandNode;
if (node != null)
node.ParentRenderCommandNode = this;
}
this.MarkDirty();
}
else if (e.Action == NotifyCollectionChangedAction.Remove)
{
foreach (IResource resource in e.OldItems)
GetCommandUsers(resource, ref commandUsers);
foreach (CommandUser user in commandUsers)
{
var node = user as RenderCommandNode;
if (node != null)
node.ParentRenderCommandNode = null;
user.UnassignFromRenderCommandNode(this);
}
this.MarkDirty();
}
}
public void MarkDirty()
{
IsDirty = true;
if (ParentRenderCommandNode != null)
ParentRenderCommandNode.MarkDirty();
}
public void ProcessCommands()
{
if (IsDirty)
{
this.GenerateDeviceCommands();
CommandBuffer.Optimize();
}
CommandBuffer.Perform(true);
}
public void GenerateDeviceCommands()
{
if (!IsDirty)
return;
IsDirty = false;
CommandBuffer.Clear();
List<CommandUser> commandUsers = new List<CommandUser>();
foreach (var child in children)
GetCommandUsers(child, ref commandUsers);
foreach (CommandUser user in commandUsers)
{
// Add the commands all commands
CommandBuffer.BufferedCommands.AddRange(user.Commands);
// Walk further if we found another RenderCommandNode
var node = user as RenderCommandNode;
if (node != null)
{
node.GenerateDeviceCommands();
// Merge the buffers
CommandBuffer.AddChildCommandBuffer(node.CommandBuffer);
}
}
}
private void GetCommandUsers(IResource resource, ref List<CommandUser> commandUsers)
{
if (resource as CommandUser != null)
commandUsers.Add(resource as CommandUser);
else foreach (var child in resource.Children)
GetCommandUsers(child, ref commandUsers);
}
#endregion
public override CommandExecuteResult ExecuteCommand(byte argCommandType, CommandBuffer argCurrentBuffer, int argCurrentPositon)
{
return CommandExecuteResult.None;
}
#region IUpdatable Members
public void Update(bool forceUpdate)
{
List<CommandUser> commandUsers = new List<CommandUser>();
foreach (var child in children)
GetCommandUsers(child, ref commandUsers);
// Walk through all updatables and update them.
foreach (var user in commandUsers)
{
var updatable = user as IUpdatable;
if (updatable != null && (updatable.WantsUpdate || forceUpdate))
updatable.Update(forceUpdate);
}
}
public bool WantsUpdate
{
get { return true; }
}
#endregion
#region IDisposable Members
public override void Dispose()
{
if (ParentRenderCommandNode != null)
ParentRenderCommandNode.Children.Remove(this);
while (Children.Count > 0)
Children.RemoveAt(0);
base.Dispose();
}
#endregion
public override ICreationParams CreationParams
{
get { return null; }
}
public override ObservableCollection<IResource> Children
{
get { return children; }
}
}
}