提交 854d1911 编写于 作者: T tanghai

1.增加TimerComponent,用于buff过期回调

2.回调不能使用delegate,delegate会导致无法reload.使用事件分发同的回调事件,比如BuffTimeout了会分发到BuffTimeoutCallback类中进行回调处理
上级 4171e82f
using Common.Event;
using Model;
using MongoDB.Bson;
namespace Controller
{
[Callback(CallbackType.BuffTimeoutCallback)]
public class BuffTimeoutCallback: IEvent
{
public void Run(Env env)
{
Unit owner = World.Instance.GetComponent<UnitComponent>().Get(env.Get<ObjectId>(EnvKey.OwnerId));
if (owner == null)
{
return;
}
owner.GetComponent<BuffComponent>().RemoveById(env.Get<ObjectId>(EnvKey.BuffId));
}
}
}
......@@ -52,6 +52,8 @@
<Compile Include="ConfigCategory\GlobalCategory.cs" />
<Compile Include="ConfigCategory\NodeCategory.cs" />
<Compile Include="ConfigCategory\UnitCategory.cs" />
<Compile Include="Callback\BuffTimeoutCallback.cs" />
<Compile Include="Event\AfterAddBuff.cs" />
<Compile Include="NodeType.cs" />
<Compile Include="Factory\UnitFactory.cs" />
<Compile Include="UnitType.cs" />
......
using Common.Event;
using Model;
namespace Controller
{
[Event(EventType.AfterAddBuff)]
public class AddBuffToTimer: IEvent
{
public void Run(Env env)
{
}
}
}
using Common.Base;
using Common.Helper;
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
namespace Model
......@@ -8,9 +10,45 @@ namespace Model
[BsonElement]
private int configId { get; set; }
[BsonElement]
private long expiration;
[BsonIgnore]
private ObjectId timerId;
[BsonIgnore]
public long Expiration
{
get
{
return this.expiration;
}
set
{
this.expiration = value;
}
}
[BsonIgnore]
public ObjectId TimerId
{
get
{
return this.timerId;
}
set
{
this.timerId = value;
}
}
public Buff(int configId)
{
this.configId = configId;
if (this.Config.Duration != 0)
{
this.Expiration = TimeHelper.Now() + this.Config.Duration;
}
}
[BsonIgnore]
......
......@@ -12,8 +12,10 @@ namespace Model
[BsonElement]
private HashSet<Buff> buffs;
[BsonIgnore]
private Dictionary<ObjectId, Buff> idBuff;
[BsonIgnore]
private MultiMap<BuffType, Buff> typeBuff;
public BuffComponent()
......@@ -40,9 +42,32 @@ namespace Model
{
this.idBuff.Add(buff.Id, buff);
this.typeBuff.Add(buff.Config.Type, buff);
AddToTimer(this.Owner, buff);
}
}
private static void AddToTimer(Unit owner, Buff buff)
{
if (buff.Expiration == 0)
{
return;
}
Env env = new Env();
env[EnvKey.OwnerId] = owner.Id;
env[EnvKey.BuffId] = buff.Id;
buff.TimerId = World.Instance.GetComponent<TimerComponent>()
.Add(buff.Expiration, CallbackType.BuffTimeoutCallback, env);
}
private static void RemoveFromTimer(Buff buff)
{
if (buff.Expiration == 0)
{
return;
}
World.Instance.GetComponent<TimerComponent>().Remove(buff.TimerId);
}
public void Add(Buff buff)
{
if (this.buffs.Contains(buff))
......@@ -59,13 +84,14 @@ namespace Model
env[EnvKey.Owner] = this.Owner;
env[EnvKey.Buff] = buff;
World.Instance.GetComponent<EventComponent<EventAttribute>>().Trigger(EventType.BeforeAddBuff, env);
World.Instance.GetComponent<EventComponent<EventAttribute>>().Run(EventType.BeforeAddBuff, env);
this.buffs.Add(buff);
this.idBuff.Add(buff.Id, buff);
this.typeBuff.Add(buff.Config.Type, buff);
AddToTimer(this.Owner, buff);
World.Instance.GetComponent<EventComponent<EventAttribute>>().Trigger(EventType.AfterAddBuff, env);
World.Instance.GetComponent<EventComponent<EventAttribute>>().Run(EventType.AfterAddBuff, env);
}
public Buff GetById(ObjectId id)
......@@ -85,35 +111,34 @@ namespace Model
public Buff[] GetByType(BuffType type)
{
return this.typeBuff.GetByKey(type);
return this.typeBuff.GetAll(type);
}
private bool Remove(Buff buff)
private void Remove(Buff buff)
{
if (buff == null)
{
return false;
return;
}
Env env = new Env();
env[EnvKey.Owner] = this.Owner;
env[EnvKey.Buff] = buff;
World.Instance.GetComponent<EventComponent<EventAttribute>>().Trigger(EventType.BeforeRemoveBuff, env);
World.Instance.GetComponent<EventComponent<EventAttribute>>().Run(EventType.BeforeRemoveBuff, env);
this.buffs.Remove(buff);
this.idBuff.Remove(buff.Id);
this.typeBuff.Remove(buff.Config.Type, buff);
RemoveFromTimer(buff);
World.Instance.GetComponent<EventComponent<EventAttribute>>().Trigger(EventType.AfterRemoveBuff, env);
return true;
World.Instance.GetComponent<EventComponent<EventAttribute>>().Run(EventType.AfterRemoveBuff, env);
}
public bool RemoveById(ObjectId id)
public void RemoveById(ObjectId id)
{
Buff buff = this.GetById(id);
return this.Remove(buff);
this.Remove(buff);
}
public void RemoveByType(BuffType type)
......
......@@ -41,7 +41,7 @@ namespace Model
}
}
public void Trigger(int type, Env env)
public void Run(int type, Env env)
{
List<IEvent> iEventDict = null;
if (!this.events.TryGetValue(type, out iEventDict))
......@@ -51,7 +51,7 @@ namespace Model
foreach (var iEvent in iEventDict)
{
iEvent.Trigger(env);
iEvent.Run(env);
}
}
}
......
using System.Collections.Generic;
using Common.Base;
using Common.Event;
using Common.Helper;
using MongoDB.Bson;
namespace Model
{
public class TimerComponent: Component<World>
{
private class Timer
{
public ObjectId Id { get; set; }
public long Time { get; set; }
public int CallbackId { get; set; }
public Env Env { get; set; }
}
private readonly Dictionary<ObjectId, Timer> timers = new Dictionary<ObjectId, Timer>();
/// <summary>
/// key: time, value: timer id
/// </summary>
private readonly MultiMap<long, ObjectId> timeId = new MultiMap<long, ObjectId>();
public ObjectId Add(long time, int callbackId, Env env)
{
Timer timer = new Timer
{
Id = ObjectId.GenerateNewId(),
Time = time,
CallbackId = callbackId,
Env = env
};
this.timers[timer.Id] = timer;
this.timeId.Add(timer.Time, timer.Id);
return timer.Id;
}
public void Remove(ObjectId id)
{
Timer timer;
if (!this.timers.TryGetValue(id, out timer))
{
return;
}
this.timeId.Remove(timer.Time, timer.Id);
}
public void Update()
{
long timeNow = TimeHelper.Now();
List<long> timeoutTimer = new List<long>();
foreach (long time in this.timeId.Keys)
{
if (time > timeNow)
{
break;
}
timeoutTimer.Add(time);
}
foreach (long key in timeoutTimer)
{
List<ObjectId> timeOutId = this.timeId[key];
foreach (ObjectId id in timeOutId)
{
Timer timer;
if (!this.timers.TryGetValue(id, out timer))
{
continue;
}
this.Remove(id);
World.Instance.GetComponent<EventComponent<CallbackAttribute>>().Run(timer.CallbackId, timer.Env);
}
}
}
}
}
......@@ -3,6 +3,8 @@
public static class EnvKey
{
public const string Owner = "Owner";
public const string OwnerId = "OwnerId";
public const string Buff = "Buff";
public const string BuffId = "BuffId";
}
}
......@@ -8,4 +8,11 @@ namespace Model
{
}
}
public class CallbackAttribute : AEventAttribute
{
public CallbackAttribute(int type): base(type)
{
}
}
}
......@@ -7,4 +7,9 @@
public const int BeforeRemoveBuff = 2;
public const int AfterRemoveBuff = 3;
}
public static class CallbackType
{
public const int BuffTimeoutCallback = 0;
}
}
......@@ -56,6 +56,7 @@
<Compile Include="Component\BuffComponent.cs" />
<Compile Include="Component\ConfigComponent.cs" />
<Compile Include="Component\EventComponent.cs" />
<Compile Include="Component\TimerComponent.cs" />
<Compile Include="Config\UnitConfig.cs" />
<Compile Include="Config\BuffConfig.cs" />
<Compile Include="EnvKey.cs" />
......
using System;
using System.Threading;
using Common.Helper;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Model;
......@@ -25,7 +24,9 @@ namespace MongoDBTest
// 加载配置
world.AddComponent<ConfigComponent>();
world.AddComponent<EventComponent<CallbackAttribute>>();
world.AddComponent<EventComponent<EventAttribute>>();
world.AddComponent<TimerComponent>();
world.AddComponent<UnitComponent>();
world.AddComponent<FactoryComponent<Unit>>();
world.AddComponent<BehaviorTreeComponent>();
......@@ -43,10 +44,14 @@ namespace MongoDBTest
Console.WriteLine(MongoHelper.ToJson(player2));
Assert.AreEqual(MongoHelper.ToJson(player1), MongoHelper.ToJson(player2));
Thread.Sleep(20 * 1000);
world.Load();
Unit player3 = player1.Clone();
Assert.AreEqual(MongoHelper.ToJson(player1), MongoHelper.ToJson(player2));
Assert.AreEqual(MongoHelper.ToJson(player1), MongoHelper.ToJson(player3));
//Thread.Sleep(20 * 1000);
//world.Load();
//
//Assert.AreEqual(MongoHelper.ToJson(player1), MongoHelper.ToJson(player2));
}
}
}
......@@ -13,7 +13,7 @@ namespace Common.Base
[BsonIgnore]
public T Owner
{
protected get
get
{
return owner;
}
......
using System;
using System.Collections.Generic;
using System.Linq;
using Common.Helper;
using MongoDB.Bson.Serialization.Attributes;
namespace Common.Base
{
public abstract class Entity<K> : Object where K : Entity<K>
public abstract class Entity<T> : Object where T : Entity<T>
{
[BsonElement]
[BsonIgnoreIfNull]
private HashSet<Component<K>> components;
private HashSet<Component<T>> components;
private Dictionary<Type, Component<K>> componentDict = new Dictionary<Type, Component<K>>();
private Dictionary<Type, Component<T>> componentDict = new Dictionary<Type, Component<T>>();
public T AddComponent<T>() where T : Component<K>, new()
public T Clone()
{
T t = new T { Owner = (K) this };
return MongoHelper.FromBson<T>(MongoHelper.ToBson(this));
}
public K AddComponent<K>() where K : Component<T>, new()
{
K component = new K { Owner = (T) this };
if (this.componentDict.ContainsKey(t.GetComponentType()))
if (this.componentDict.ContainsKey(component.GetComponentType()))
{
throw new Exception(
string.Format("AddComponent, component already exist, id: {0}, component: {1}",
this.Id, typeof(T).Name));
this.Id, typeof(K).Name));
}
if (this.components == null)
{
this.components = new HashSet<Component<K>>();
this.components = new HashSet<Component<T>>();
}
this.components.Add(t);
this.componentDict.Add(t.GetComponentType(), t);
return t;
this.components.Add(component);
this.componentDict.Add(component.GetComponentType(), component);
return component;
}
public void AddComponent(Component<K> component)
public void AddComponent(Component<T> component)
{
if (this.componentDict.ContainsKey(component.GetComponentType()))
{
......@@ -45,24 +51,24 @@ namespace Common.Base
if (this.components == null)
{
this.components = new HashSet<Component<K>>();
this.components = new HashSet<Component<T>>();
}
this.components.Add(component);
this.componentDict.Add(component.GetComponentType(), component);
}
public void RemoveComponent<T>() where T : Component<K>
public void RemoveComponent<K>() where K : Component<T>
{
Component<K> t;
if (!this.componentDict.TryGetValue(typeof (T), out t))
Component<T> component;
if (!this.componentDict.TryGetValue(typeof (K), out component))
{
throw new Exception(
string.Format("RemoveComponent, component not exist, id: {0}, component: {1}",
this.Id, typeof(T).Name));
this.Id, typeof(K).Name));
}
this.components.Remove(t);
this.componentDict.Remove(typeof(T));
this.components.Remove(component);
this.componentDict.Remove(typeof(K));
if (this.components.Count == 0)
{
......@@ -70,17 +76,17 @@ namespace Common.Base
}
}
public T GetComponent<T>() where T : Component<K>
public K GetComponent<K>() where K : Component<T>
{
Component<K> t;
if (!this.componentDict.TryGetValue(typeof (T), out t))
Component<T> component;
if (!this.componentDict.TryGetValue(typeof (K), out component))
{
return default (T);
return default (K);
}
return (T) t;
return (K) component;
}
public Component<K>[] GetComponents()
public Component<T>[] GetComponents()
{
return this.components.ToArray();
}
......@@ -88,8 +94,8 @@ namespace Common.Base
public override void BeginInit()
{
base.BeginInit();
this.components = new HashSet<Component<K>>();
this.componentDict = new Dictionary<Type, Component<K>>();
this.components = new HashSet<Component<T>>();
this.componentDict = new Dictionary<Type, Component<T>>();
}
public override void EndInit()
......@@ -102,7 +108,7 @@ namespace Common.Base
}
foreach (var component in this.components)
{
component.Owner = (K)this;
component.Owner = (T) this;
this.componentDict.Add(component.GetComponentType(), component);
}
}
......
......@@ -56,7 +56,7 @@ namespace Common.Base
/// </summary>
/// <param name="t"></param>
/// <returns></returns>
public K[] GetByKey(T t)
public K[] GetAll(T t)
{
List<K> list;
this.dictionary.TryGetValue(t, out list);
......
......@@ -25,6 +25,22 @@ namespace Common.Base
this.Id = id;
}
public virtual void BeginInit()
{
if (this.values == null)
{
this.values = new Dictionary<string, object>();
}
}
public virtual void EndInit()
{
if (this.values.Count == 0)
{
this.values = null;
}
}
public object this[string key]
{
get
......@@ -101,21 +117,5 @@ namespace Common.Base
{
return this.values.GetEnumerator();
}
public virtual void BeginInit()
{
if (this.values == null)
{
this.values = new Dictionary<string, object>();
}
}
public virtual void EndInit()
{
if (this.values.Count == 0)
{
this.values = null;
}
}
}
}
\ No newline at end of file
......@@ -2,6 +2,6 @@
{
public interface IEvent
{
void Trigger(Env env);
void Run(Env env);
}
}
\ No newline at end of file
......@@ -4,10 +4,10 @@ namespace Common.Helper
{
public static class TimeHelper
{
public static long EpochTimeSecond()
public static long Now()
{
var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
return Convert.ToInt64((DateTime.UtcNow - epoch).TotalSeconds);
return Convert.ToInt64((DateTime.UtcNow - epoch).TotalMilliseconds);
}
}
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册