Implement effect.
This commit is contained in:
@@ -44,6 +44,7 @@ namespace Cryville.Crtr {
|
|||||||
EventBus nbus;
|
EventBus nbus;
|
||||||
InputProxy inputProxy;
|
InputProxy inputProxy;
|
||||||
Judge judge;
|
Judge judge;
|
||||||
|
public static EffectManager effectManager;
|
||||||
bool started = false;
|
bool started = false;
|
||||||
|
|
||||||
static bool initialized;
|
static bool initialized;
|
||||||
@@ -160,6 +161,8 @@ namespace Cryville.Crtr {
|
|||||||
tbus.ForwardStepByTime(renderDist, step);
|
tbus.ForwardStepByTime(renderDist, step);
|
||||||
tbus.EndGraphicalUpdate();
|
tbus.EndGraphicalUpdate();
|
||||||
UnityEngine.Profiling.Profiler.EndSample();
|
UnityEngine.Profiling.Profiler.EndSample();
|
||||||
|
|
||||||
|
effectManager.Tick(cbus.Time);
|
||||||
}
|
}
|
||||||
catch (Exception ex) {
|
catch (Exception ex) {
|
||||||
Game.LogException("Game", "An error occured while playing", ex);
|
Game.LogException("Game", "An error occured while playing", ex);
|
||||||
@@ -496,6 +499,8 @@ namespace Cryville.Crtr {
|
|||||||
if (tbus != null) { tbus.Dispose(); tbus = null; }
|
if (tbus != null) { tbus.Dispose(); tbus = null; }
|
||||||
if (bbus != null) { bbus.Dispose(); bbus = null; }
|
if (bbus != null) { bbus.Dispose(); bbus = null; }
|
||||||
if (cbus != null) { cbus.Dispose(); cbus.DisposeAll(); cbus = null; }
|
if (cbus != null) { cbus.Dispose(); cbus.DisposeAll(); cbus = null; }
|
||||||
|
effectManager.Dispose();
|
||||||
|
effectManager = null;
|
||||||
etor = null;
|
etor = null;
|
||||||
Logger.Log("main", 1, "Game", "Stopped");
|
Logger.Log("main", 1, "Game", "Stopped");
|
||||||
}
|
}
|
||||||
@@ -638,6 +643,7 @@ namespace Cryville.Crtr {
|
|||||||
skin.LoadPdt(dir);
|
skin.LoadPdt(dir);
|
||||||
pskin = skin.Root;
|
pskin = skin.Root;
|
||||||
pskin.Optimize(etor);
|
pskin.Optimize(etor);
|
||||||
|
effectManager = new EffectManager(pskin);
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
59
Assets/Cryville/Crtr/EffectGroup.cs
Normal file
59
Assets/Cryville/Crtr/EffectGroup.cs
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
using Cryville.Common.Buffers;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Cryville.Crtr {
|
||||||
|
public class EffectGroup {
|
||||||
|
public EffectDefinition Definition { get; private set; }
|
||||||
|
readonly EffectPool _pool;
|
||||||
|
class EffectPool : ObjectPool<EffectInstance> {
|
||||||
|
readonly List<EffectInstance> _instances
|
||||||
|
= new List<EffectInstance>();
|
||||||
|
readonly EffectGroup _group;
|
||||||
|
public EffectPool(EffectGroup group) : base(256) {
|
||||||
|
_group = group;
|
||||||
|
}
|
||||||
|
protected override EffectInstance Construct() {
|
||||||
|
var result = new EffectInstance(_group.Definition);
|
||||||
|
_instances.Add(result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
public void DisposeAll() {
|
||||||
|
foreach (var i in _instances) i.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
readonly Dictionary<float, EffectInstance> _instances
|
||||||
|
= new Dictionary<float, EffectInstance>();
|
||||||
|
readonly List<EffectInstance> _endQueue
|
||||||
|
= new List<EffectInstance>();
|
||||||
|
public EffectGroup(EffectDefinition def) {
|
||||||
|
Definition = def;
|
||||||
|
_pool = new EffectPool(this);
|
||||||
|
}
|
||||||
|
double _time;
|
||||||
|
public void Tick(double time) {
|
||||||
|
_time = time;
|
||||||
|
while (_endQueue.Count > 0) {
|
||||||
|
var item = _endQueue[0];
|
||||||
|
if (item.EndTime > _time) break;
|
||||||
|
item.OnDone();
|
||||||
|
_instances.Remove(item.Index);
|
||||||
|
_pool.Return(item);
|
||||||
|
_endQueue.RemoveAt(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void Emit(float index) {
|
||||||
|
EffectInstance instance;
|
||||||
|
if (!_instances.TryGetValue(index, out instance)) {
|
||||||
|
_instances.Add(index, instance = _pool.Rent());
|
||||||
|
}
|
||||||
|
instance.Index = index;
|
||||||
|
instance.OnEmit(_time);
|
||||||
|
var i = _endQueue.BinarySearch(instance);
|
||||||
|
if (i < 0) i = ~i;
|
||||||
|
_endQueue.Insert(i, instance);
|
||||||
|
}
|
||||||
|
public void Dispose() {
|
||||||
|
_pool.DisposeAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
Assets/Cryville/Crtr/EffectGroup.cs.meta
Normal file
11
Assets/Cryville/Crtr/EffectGroup.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: d0d27f9b4383b3445a2a27bfe94173a5
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
66
Assets/Cryville/Crtr/EffectInstance.cs
Normal file
66
Assets/Cryville/Crtr/EffectInstance.cs
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
using Cryville.Common;
|
||||||
|
using Cryville.Crtr.Components;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace Cryville.Crtr {
|
||||||
|
public class EffectInstance : ISkinnableGroup, IComparable<EffectInstance> {
|
||||||
|
readonly EffectDefinition _def;
|
||||||
|
readonly SkinContainer _skinContainer;
|
||||||
|
public Transform RootTransform { get; private set; }
|
||||||
|
public EffectInstance(EffectDefinition def) {
|
||||||
|
_def = def;
|
||||||
|
_skinContainer = new SkinContainer(_def.elements);
|
||||||
|
RootTransform = new GameObject("effect:" + GetHashCode().ToString(CultureInfo.InvariantCulture)).transform;
|
||||||
|
SkinContext = new SkinContext(RootTransform);
|
||||||
|
ChartPlayer.etor.ContextCascadeInsertBlock();
|
||||||
|
_skinContainer.MatchStatic(this);
|
||||||
|
ChartPlayer.etor.ContextCascadeDiscardBlock();
|
||||||
|
foreach (var i in RootTransform.GetComponentsInChildren<SkinComponent>())
|
||||||
|
i.Init();
|
||||||
|
_indexSrc = new PropSrc.Float(() => Index);
|
||||||
|
_durationOp = new PropOp.Float(v => _duration = v);
|
||||||
|
}
|
||||||
|
public float Index { get; set; }
|
||||||
|
static readonly int _var_index = IdentifierManager.SharedInstance.Request("index");
|
||||||
|
readonly PropSrc _indexSrc;
|
||||||
|
double _startTime;
|
||||||
|
float _duration;
|
||||||
|
readonly PropOp _durationOp;
|
||||||
|
public double EndTime { get { return _startTime + _duration; } }
|
||||||
|
public void OnEmit(double time) {
|
||||||
|
_startTime = time;
|
||||||
|
RootTransform.gameObject.SetActive(true);
|
||||||
|
ChartPlayer.etor.ContextCascadeInsert();
|
||||||
|
ChartPlayer.etor.ContextCascadeUpdate(_var_index, _indexSrc);
|
||||||
|
ChartPlayer.etor.Evaluate(_durationOp, _def.duration);
|
||||||
|
_skinContainer.MatchDynamic(this, 0);
|
||||||
|
ChartPlayer.etor.ContextCascadeDiscard();
|
||||||
|
}
|
||||||
|
public void OnDone() {
|
||||||
|
RootTransform.gameObject.SetActive(false);
|
||||||
|
}
|
||||||
|
public void Dispose() {
|
||||||
|
GameObject.Destroy(RootTransform.gameObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
public string TypeName { get { throw new InvalidOperationException("Type name undefined"); } }
|
||||||
|
public SkinContext SkinContext { get; private set; }
|
||||||
|
public Anchor OpenedAnchor { get { throw new InvalidOperationException("Anchor not supported"); } }
|
||||||
|
public void PushAnchorEvent(double time, int name) {
|
||||||
|
throw new InvalidOperationException("Anchor not supported");
|
||||||
|
}
|
||||||
|
public void RegisterAnchor(int name) {
|
||||||
|
throw new InvalidOperationException("Anchor not supported");
|
||||||
|
}
|
||||||
|
public bool TryGetAnchorsByName(int name, out IReadOnlyCollection<Anchor> result) {
|
||||||
|
throw new InvalidOperationException("Anchor not supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
public int CompareTo(EffectInstance other) {
|
||||||
|
return EndTime.CompareTo(other.EndTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
Assets/Cryville/Crtr/EffectInstance.cs.meta
Normal file
11
Assets/Cryville/Crtr/EffectInstance.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f442db34239c47046ba1b6fdae8e1216
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
22
Assets/Cryville/Crtr/EffectManager.cs
Normal file
22
Assets/Cryville/Crtr/EffectManager.cs
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace Cryville.Crtr {
|
||||||
|
public class EffectManager {
|
||||||
|
readonly Dictionary<int, EffectGroup> _groups
|
||||||
|
= new Dictionary<int, EffectGroup>();
|
||||||
|
public EffectManager(PdtSkin skin) {
|
||||||
|
foreach (var e in skin.effects) {
|
||||||
|
_groups.Add(e.Key.Key, new EffectGroup(e.Value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public void Tick(double time) {
|
||||||
|
foreach (var g in _groups) g.Value.Tick(time);
|
||||||
|
}
|
||||||
|
public void Emit(int id, float index) {
|
||||||
|
_groups[id].Emit(index);
|
||||||
|
}
|
||||||
|
public void Dispose() {
|
||||||
|
foreach (var g in _groups) g.Value.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
11
Assets/Cryville/Crtr/EffectManager.cs.meta
Normal file
11
Assets/Cryville/Crtr/EffectManager.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 980c0f18a6f491d44a866a85910cb458
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@@ -59,9 +59,6 @@ namespace Cryville.Crtr {
|
|||||||
foreach (var e in effects) {
|
foreach (var e in effects) {
|
||||||
var effect = e.Value;
|
var effect = e.Value;
|
||||||
etor.ContextCascadeInsert();
|
etor.ContextCascadeInsert();
|
||||||
if (effect.args != null) foreach (var i in effect.args) {
|
|
||||||
etor.ContextCascadeUpdate(i.Key, PropSrc.Error);
|
|
||||||
}
|
|
||||||
etor.Optimize(effect.duration);
|
etor.Optimize(effect.duration);
|
||||||
effect.elements.Optimize(etor);
|
effect.elements.Optimize(etor);
|
||||||
etor.ContextCascadeDiscard();
|
etor.ContextCascadeDiscard();
|
||||||
@@ -101,7 +98,6 @@ namespace Cryville.Crtr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public class EffectDefinition {
|
public class EffectDefinition {
|
||||||
public Identifier[] args;
|
|
||||||
public PdtExpression duration;
|
public PdtExpression duration;
|
||||||
public SkinElement elements;
|
public SkinElement elements;
|
||||||
}
|
}
|
||||||
|
@@ -98,16 +98,21 @@ namespace Cryville.Crtr {
|
|||||||
}
|
}
|
||||||
public class EmitEffect : SkinPropertyKey {
|
public class EmitEffect : SkinPropertyKey {
|
||||||
public int Name { get; set; }
|
public int Name { get; set; }
|
||||||
public EmitEffect() { }
|
public EmitEffect() {
|
||||||
|
_op = new PropOp.Float(v => _index = v);
|
||||||
|
}
|
||||||
public override string ToString() {
|
public override string ToString() {
|
||||||
return string.Format("@emit {0}", IdentifierManager.SharedInstance.Retrieve(Name));
|
return string.Format("@emit {0}", IdentifierManager.SharedInstance.Retrieve(Name));
|
||||||
}
|
}
|
||||||
public override bool IsValueRequired { get { return true; } }
|
public override bool IsValueRequired { get { return true; } }
|
||||||
public override void ExecuteStatic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp) {
|
public override void ExecuteStatic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp) {
|
||||||
// TODO
|
throw new InvalidOperationException("Emitting effect in static context is not allowed");
|
||||||
}
|
}
|
||||||
|
float _index;
|
||||||
|
readonly PropOp _op;
|
||||||
public override void ExecuteDynamic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, int dl) {
|
public override void ExecuteDynamic(ISkinnableGroup group, RuntimeSkinContext ctx, PdtExpression exp, int dl) {
|
||||||
// TODO
|
ChartPlayer.etor.Evaluate(_op, exp);
|
||||||
|
ChartPlayer.effectManager.Emit(Name, _index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user