222 lines
7.1 KiB
C#
222 lines
7.1 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
|
||
/// <summary>
|
||
/// 谱面运行数据类,负责将谱面数据解析之后生成运行时数据项,与控制层通讯,这些数据项是查询现有数据项的唯一依据
|
||
/// 集合在比较
|
||
/// </summary>
|
||
public class ChartRuntimeModel
|
||
{
|
||
/// <summary>
|
||
/// 负责管理在项目运行时所产生的物件数据,可以生成Chart对象
|
||
/// </summary>
|
||
public SortedSet<RuntimeBaseNoteData> ChartRuntimeSet = new SortedSet<RuntimeBaseNoteData>(new UniversalBaseNoteComparer());
|
||
/// <summary>
|
||
/// 输入搜索的开始与结束时间,返回符合条件的对象视图
|
||
/// </summary>
|
||
public SortedSet<RuntimeBaseNoteData> SearchRange(float startTime, float endTime)
|
||
{
|
||
var view = ChartRuntimeSet.GetViewBetween(new TempBaseNoteComparer(startTime), new TempBaseNoteComparer(endTime));
|
||
return view;
|
||
}
|
||
/// <summary>
|
||
/// 删除指定的数据项
|
||
/// </summary>
|
||
public void DeleteDataItem(RuntimeBaseNoteData obj)
|
||
{
|
||
ChartRuntimeSet.Remove(obj);
|
||
}
|
||
/// <summary>
|
||
/// 获得指定的数据项引用,如果不存在对应的数据项则会返回null
|
||
/// </summary>
|
||
public RuntimeBaseNoteData GetDataItem(RuntimeBaseNoteData obj)
|
||
{
|
||
if (ChartRuntimeSet.TryGetValue(obj, out var Value))
|
||
{
|
||
return Value;
|
||
}
|
||
else
|
||
{
|
||
return null;
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 添加新的数据项
|
||
/// </summary>
|
||
public void AddDataItem(RuntimeBaseNoteData obj)
|
||
{
|
||
ChartRuntimeSet.Add(obj);
|
||
}
|
||
/// <summary>
|
||
/// 遍历所有的数据项,将其转换为持久化谱面数据对象
|
||
/// </summary>
|
||
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<RuntimeBaseNoteData>
|
||
{
|
||
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);
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 用于在运行时传递数据的基类
|
||
/// </summary>
|
||
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;
|
||
}
|
||
}
|