초기커밋
This commit is contained in:
302
ServerCore/Pattern/HeirerchyNode.cs
Normal file
302
ServerCore/Pattern/HeirerchyNode.cs
Normal file
@@ -0,0 +1,302 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
|
||||
namespace ServerCore;
|
||||
|
||||
//=============================================================================================
|
||||
// 계층적으로 노드를 관리할 수 있는 기능을 제공하는 제네릭 클래스 이다.
|
||||
//
|
||||
// author : kangms
|
||||
//
|
||||
//=============================================================================================
|
||||
|
||||
public interface IHeirerchy<T>
|
||||
{
|
||||
// 찾으려고 하는 값의 IHeirerchy<T> 를 찾는다.
|
||||
IHeirerchy<T>? findHeirerchy(T toFind);
|
||||
|
||||
// DepthNo 0 일경우 Root 이고 자식 계층이 추가될 경우 1 증가 된다.
|
||||
Int32 getDepthNo();
|
||||
|
||||
// 부모 계층을 수동으로 설정 한다.
|
||||
void setParent(IHeirerchy<T> parent);
|
||||
IHeirerchy<T>? getParent();
|
||||
|
||||
// 현재의 계층에 자식 노드을 추가 한다.
|
||||
IHeirerchy<T> addChildNode(IHeirerchy<T> child);
|
||||
// 현재의 계층에 자식 노드 목록을 반환 한다.
|
||||
List<IHeirerchy<T>> getChilds();
|
||||
|
||||
// 현재 노드에 값을 설정 한다.
|
||||
void setValue(T value);
|
||||
// 현재 노드의 값을 반환 한다.
|
||||
T getValue();
|
||||
|
||||
// 현재 계층 부터 부모의 Root 계층 까지 해당 T 타입인지 체크 한다.
|
||||
bool isUpperHeirerchy(T toCheck);
|
||||
|
||||
// 현재 계층 부터 자식의 Leaf 계층 까지 해당 T 타입인지 체크 한다.
|
||||
bool isLowerHeirerchy(T toCheck);
|
||||
|
||||
// 현재 노드가 Root 인가?
|
||||
bool isRoot();
|
||||
// 현재 노드가 최하위 노드 인가?
|
||||
bool isLeaf();
|
||||
|
||||
bool isEqual(T value);
|
||||
|
||||
// 현재 노드에서 자식 노드 계층의 모든 노드값의 체크해서 성공 & 실패 노드 목록을 반환 한다.
|
||||
bool onCheckValue(ref HashSet<T> successedNodes, ref List<IHeirerchy<T>> failedNodes);
|
||||
// 하위 노드 목록을 채워준다.
|
||||
void fillupLowers(ref List<T> lowers);
|
||||
}
|
||||
|
||||
public class HeirerchyNode<T> : IHeirerchy<T>
|
||||
{
|
||||
private T m_value;
|
||||
private IHeirerchy<T>? m_parent;
|
||||
private List<IHeirerchy<T>> m_childs = new();
|
||||
private Int32 m_depth_no = 0;
|
||||
|
||||
public HeirerchyNode(T value)
|
||||
{
|
||||
m_value = value;
|
||||
}
|
||||
|
||||
public HeirerchyNode(T value, IHeirerchy<T> parent)
|
||||
{
|
||||
m_value = value;
|
||||
|
||||
setParent(parent);
|
||||
}
|
||||
|
||||
public virtual bool onCheckValue(ref HashSet<T> successedNodes
|
||||
, ref List<IHeirerchy<T>> failedNodes)
|
||||
{
|
||||
var is_success = true;
|
||||
|
||||
foreach (var heirerchy_node in getChilds())
|
||||
{
|
||||
var value = heirerchy_node.getValue();
|
||||
if (true == successedNodes.Contains(value))
|
||||
{
|
||||
failedNodes.Add(heirerchy_node);
|
||||
is_success = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
successedNodes.Add(value);
|
||||
|
||||
if (false == heirerchy_node.onCheckValue(ref successedNodes, ref failedNodes))
|
||||
{
|
||||
failedNodes.Add(heirerchy_node);
|
||||
is_success = false;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return is_success;
|
||||
}
|
||||
|
||||
public static IHeirerchy<T>? findByTraveral(IHeirerchy<T> root, T toFind)
|
||||
{
|
||||
if (true == root.isEqual(toFind))
|
||||
{
|
||||
return root;
|
||||
}
|
||||
|
||||
foreach (var heirerchy_node in root.getChilds())
|
||||
{
|
||||
var found_heirerchy = heirerchy_node.findHeirerchy(toFind);
|
||||
if (null != found_heirerchy)
|
||||
{
|
||||
return found_heirerchy;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public IHeirerchy<T>? findHeirerchy(T toFind)
|
||||
{
|
||||
if (true == isEqual(toFind))
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
foreach (var heirerchy_node in getChilds())
|
||||
{
|
||||
var found_heirerchy = heirerchy_node.findHeirerchy(toFind);
|
||||
if (null != found_heirerchy)
|
||||
{
|
||||
return found_heirerchy;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public IHeirerchy<T> newAndAddChildNode<THeirerchy>(T childValue) where THeirerchy : IHeirerchy<T>, new()
|
||||
{
|
||||
if (m_childs == null)
|
||||
{
|
||||
m_childs = new List<IHeirerchy<T>>();
|
||||
}
|
||||
|
||||
var to_add_child_node = new THeirerchy();
|
||||
to_add_child_node.setValue(childValue);
|
||||
|
||||
return addChildNode(to_add_child_node);
|
||||
}
|
||||
|
||||
public IHeirerchy<T> addChildNode(IHeirerchy<T> childNode)
|
||||
{
|
||||
if (m_childs == null)
|
||||
{
|
||||
m_childs = new List<IHeirerchy<T>>();
|
||||
}
|
||||
|
||||
m_childs.Add(childNode);
|
||||
childNode.setParent(this);
|
||||
|
||||
return childNode;
|
||||
}
|
||||
|
||||
public static IHeirerchy<T>? newAndAddChildNodeOfParent<THeirerchy>(IHeirerchy<T> root, T parentValue, T toAddChildValue) where THeirerchy : IHeirerchy<T>, new()
|
||||
{
|
||||
var found_parent_heirerchy = findByTraveral(root, parentValue);
|
||||
if (null == found_parent_heirerchy)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var found_node = found_parent_heirerchy as HeirerchyNode<T>;
|
||||
if (null == found_node)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return found_node.newAndAddChildNode<THeirerchy>(toAddChildValue);
|
||||
}
|
||||
|
||||
public List<IHeirerchy<T>> getChilds()
|
||||
{
|
||||
return m_childs == null ? (new List<IHeirerchy<T>>()) : m_childs;
|
||||
}
|
||||
|
||||
public IHeirerchy<T> getFirstChildNode()
|
||||
{
|
||||
return m_childs.First();
|
||||
}
|
||||
|
||||
public IHeirerchy<T> getLastChildNode()
|
||||
{
|
||||
return m_childs.Last();
|
||||
}
|
||||
|
||||
public IHeirerchy<T>? getChildNodeByIndex(Int32 index)
|
||||
{
|
||||
if (m_childs.Count <= index)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return m_childs[index];
|
||||
}
|
||||
|
||||
public virtual bool isUpperHeirerchy(T toCheck)
|
||||
{
|
||||
if (true == isEqual(toCheck))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var parent = getParent();
|
||||
if (null != parent)
|
||||
{
|
||||
if (true == parent.isUpperHeirerchy(toCheck))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual bool isLowerHeirerchy(T toCheck)
|
||||
{
|
||||
if (true == isEqual(toCheck))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
foreach (var child_node in getChilds())
|
||||
{
|
||||
if (true == child_node.isLowerHeirerchy(toCheck))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
// 하위 노드들 얻기
|
||||
public virtual void fillupLowers(ref List<T> lowers)
|
||||
{
|
||||
foreach (var child_node in getChilds())
|
||||
{
|
||||
lowers.Add(child_node.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
public bool isRoot()
|
||||
{
|
||||
return getParent() == null;
|
||||
}
|
||||
|
||||
public bool isLeaf()
|
||||
{
|
||||
return getChilds().Count <= 0;
|
||||
}
|
||||
|
||||
public void setValue(T value)
|
||||
{
|
||||
m_value = value;
|
||||
}
|
||||
|
||||
public T getValue()
|
||||
{
|
||||
return m_value;
|
||||
}
|
||||
|
||||
public bool isEqual(T value)
|
||||
{
|
||||
return m_value?.Equals(value) ?? false;
|
||||
}
|
||||
|
||||
public void setDepthNo(Int32 depthNo)
|
||||
{
|
||||
m_depth_no = depthNo;
|
||||
}
|
||||
|
||||
public Int32 getDepthNo()
|
||||
{
|
||||
return m_depth_no;
|
||||
}
|
||||
|
||||
public void setParent(IHeirerchy<T> parent)
|
||||
{
|
||||
m_parent = parent;
|
||||
|
||||
var depth_no = parent.getDepthNo() + 1;
|
||||
setDepthNo(depth_no);
|
||||
}
|
||||
|
||||
public IHeirerchy<T>? getParent()
|
||||
{
|
||||
return m_parent;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user