using System;
using System.Collections.Generic;
///
/// 谱面运行数据类,负责将谱面数据解析之后生成运行时数据项,与控制层通讯,这些数据项是查询现有数据项的唯一依据
/// 集合在比较
///
public class ChartRuntimeModel
{
///
/// 负责管理在项目运行时所产生的物件数据,可以生成Chart对象
///
public SortedSet ChartRuntimeSet = new SortedSet(new UniversalBaseNoteComparer());
///
/// 输入搜索的开始与结束时间,返回符合条件的对象视图
///
public SortedSet SearchRange(float startTime, float endTime)
{
var view = ChartRuntimeSet.GetViewBetween(new TempBaseNoteComparer(startTime), new TempBaseNoteComparer(endTime));
return view;
}
///
/// 删除指定的数据项
///
public void DeleteDataItem(RuntimeBaseNoteData obj)
{
ChartRuntimeSet.Remove(obj);
}
///
/// 获得指定的数据项引用,如果不存在对应的数据项则会返回null
///
public RuntimeBaseNoteData GetDataItem(RuntimeBaseNoteData obj)
{
if (ChartRuntimeSet.TryGetValue(obj, out var Value))
{
return Value;
}
else
{
return null;
}
}
///
/// 添加新的数据项
///
public void AddDataItem(RuntimeBaseNoteData obj)
{
ChartRuntimeSet.Add(obj);
}
///
/// 遍历所有的数据项,将其转换为持久化谱面数据对象
///
public void GetChartData(Chart chart)
{
foreach (var item in ChartRuntimeSet)
{
switch (item)
{
case RuntimeNoteData:
{
chart.noteList.Add(new NoteListItem(
item.xPos,
item.yPos,
item.targetTime,
item.bpmGroup.GroupNum));
break;
}
case RuntimeDragData:
{
chart.dragList.Add(new DragListItem(
item.xPos,
item.yPos,
item.targetTime,
item.bpmGroup.GroupNum));
break;
}
case RuntimeFlickData:
{
var flick = item as RuntimeFlickData;
chart.flickList.Add(new FlickListItem(
item.xPos,
item.yPos,
item.targetTime,
item.bpmGroup.GroupNum,
flick.direction
));
break;
}
case RuntimeSnakeData:
{
var snake = item as RuntimeSnakeData;
chart.dataFlowList.Add(new DataFlowListItem(
snake.xPos,
snake.yPos,
snake.endXPos,
snake.endYPos,
snake.targetTime,
snake.endTime,
true,
snake.bpmGroup.GroupNum,
snake.referencePoint
));
break;
}
}
}
}
}
public class UniversalBaseNoteComparer : IComparer
{
public int Compare(RuntimeBaseNoteData x, RuntimeBaseNoteData y)
{
if (x == null && y == null) return 0;
if (x == null) return -1;
if (y == null) return 1;
int timeComparison = x.targetTime.CompareTo(y.targetTime);
if (timeComparison != 0) return timeComparison;
int xComparison = x.xPos.CompareTo(y.xPos);
if (xComparison != 0) return xComparison;
int yComparison = x.yPos.CompareTo(y.yPos);
if (yComparison != 0) return yComparison;
// 如果是蛇节点,比较特有参数
if (x is RuntimeSnakeData xSnake && y is RuntimeSnakeData ySnake)
{
// 比较蛇节点的特有参数
int endXComparison = xSnake.endXPos.CompareTo(ySnake.endXPos);
if (endXComparison != 0) return endXComparison;
int endYComparison = xSnake.endYPos.CompareTo(ySnake.endYPos);
if (endYComparison != 0) return endYComparison;
int endTimeComparison = xSnake.endTime.CompareTo(ySnake.endTime);
if (endTimeComparison != 0) return endTimeComparison;
int referencePointComparison = xSnake.referencePoint.CompareTo(ySnake.referencePoint);
if (referencePointComparison != 0) return referencePointComparison;
}
// 只比较类型
Type xType = x.GetType();
Type yType = y.GetType();
// 如果类型相同,返回 0(表示相等,SortedSet 不会添加重复项)
// 如果类型不同,按类型名称排序
return string.Compare(xType.FullName, yType.FullName, StringComparison.Ordinal);
}
}
///
/// 用于在运行时传递数据的基类
///
public class RuntimeBaseNoteData
{
public float targetTime { get; set; }
public float xPos { get; set; }
public float yPos { get; set; }
public BPMGroup bpmGroup { get; set; }
}
public class TempBaseNoteComparer : RuntimeBaseNoteData
{
public TempBaseNoteComparer(float time)
{
targetTime = time;
}
}
public class RuntimeNoteData : RuntimeBaseNoteData
{
public RuntimeNoteData(float targetTime, float xPos, float yPos, BPMGroup bpmGroup)
{
this.targetTime = targetTime;
this.xPos = xPos;
this.yPos = yPos;
this.bpmGroup = bpmGroup;
}
}
public class RuntimeDragData : RuntimeBaseNoteData
{
public RuntimeDragData(float targetTime, float xPos, float yPos, BPMGroup bpmGroup)
{
this.targetTime = targetTime;
this.xPos = xPos;
this.yPos = yPos;
this.bpmGroup = bpmGroup;
}
}
public class RuntimeFlickData : RuntimeBaseNoteData
{
public FlickDirection direction { get; set; }
public RuntimeFlickData(float targetTime, float xPos, float yPos, FlickDirection direction, BPMGroup bpmGroup)
{
this.targetTime = targetTime;
this.xPos = xPos;
this.yPos = yPos;
this.direction = direction;
this.bpmGroup = bpmGroup;
}
}
public class RuntimeSnakeData : RuntimeBaseNoteData
{
public float endXPos { get; set; }
public float endYPos { get; set; }
public float endTime { get; set; }
public ReferencePointLocation referencePoint { get; set; }
public RuntimeSnakeData(float targetTime, float xPos, float yPos, float endXPos, float endYPos, float endTime, ReferencePointLocation referencePoint, BPMGroup bpmGroup)
{
this.targetTime = targetTime;
this.xPos = xPos;
this.yPos = yPos;
this.endXPos = endXPos;
this.endYPos = endYPos;
this.endTime = endTime;
this.referencePoint = referencePoint;
this.bpmGroup = bpmGroup;
}
}