Просмотр исходного кода

游戏逻辑增加了事件钩子机制,增加一个事件钩子变得非常简单

tanghai 12 лет назад
Родитель
Сommit
c2cb3d68e1

+ 1 - 1
CSharp/App/Modules/Tree/BehaviorTreeView.xaml

@@ -44,7 +44,7 @@
 			</ListBox.ItemsPanel>
 			<ListBox.ItemTemplate>
 				<DataTemplate DataType="BehaviorTree:TreeNodeViewModel">
-					<Canvas MouseDown="ListBoxItem_MouseDown" MouseUp="ListBoxItem_MouseUp" MouseMove="ListBoxItem_MouseMove">
+					<Canvas MouseDown="ListBoxItem_MouseDown" MouseUp="ListBoxItem_MouseUp" MouseMove="ListBoxItem_MouseMove" >
 						<Rectangle Name="rectNode" Width="{Binding Width}" Height="{Binding Height}" Cursor="Hand" StrokeThickness="4"
 								RadiusX="4" RadiusY="4" Stroke="{StaticResource treeNodeBorderBrush}" Fill="{StaticResource treeNodeFillBrush}"/>
 						<Line X1="{Binding ConnectorX1}" Y1="{Binding ConnectorY1}" X2="{Binding ConnectorX2}" Y2="{Binding ConnectorY2}"

+ 0 - 5
CSharp/App/Modules/WCFClient/WCFClient.csproj

@@ -66,11 +66,6 @@
     <Reference Include="System.Xaml">
       <RequiredTargetFramework>4.0</RequiredTargetFramework>
     </Reference>
-    <Reference Include="Telerik.Windows.Controls, Version=2013.3.1016.45, Culture=neutral, PublicKeyToken=5803cfa389c90ce7, processorArchitecture=MSIL" />
-    <Reference Include="Telerik.Windows.Controls.Chart, Version=2013.3.1016.45, Culture=neutral, PublicKeyToken=5803cfa389c90ce7, processorArchitecture=MSIL" />
-    <Reference Include="Telerik.Windows.Controls.DataVisualization, Version=2013.3.1016.45, Culture=neutral, PublicKeyToken=5803cfa389c90ce7, processorArchitecture=MSIL" />
-    <Reference Include="Telerik.Windows.Controls.Navigation, Version=2013.3.1016.45, Culture=neutral, PublicKeyToken=5803cfa389c90ce7, processorArchitecture=MSIL" />
-    <Reference Include="Telerik.Windows.Data, Version=2013.3.1016.45, Culture=neutral, PublicKeyToken=5803cfa389c90ce7, processorArchitecture=MSIL" />
     <Reference Include="UIAutomationProvider" />
     <Reference Include="UIAutomationTypes" />
     <Reference Include="WindowsBase" />

+ 1 - 1
CSharp/App/Modules/WCFClient/WCFClientView.xaml

@@ -3,7 +3,7 @@
 		xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 		xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
 		xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
-		xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation" x:Class="Modules.WCFClient.WCFClientView" 
+		x:Class="Modules.WCFClient.WCFClientView" 
 		mc:Ignorable="d" 
 		d:DesignHeight="300" d:DesignWidth="300">
 	<Grid>

+ 6 - 1
CSharp/Game/Component/Component.csproj

@@ -43,13 +43,18 @@
     <Compile Include="BuffManager.cs" />
     <Compile Include="ConfigAttribute.cs" />
     <Compile Include="ConfigManager.cs" />
+    <Compile Include="EventAttribute.cs" />
+    <Compile Include="EventDefine.cs" />
     <Compile Include="HandlerAttribute.cs" />
     <Compile Include="IConfigInitialize.cs" />
+    <Compile Include="IEvent.cs" />
     <Compile Include="IHandler.cs" />
-    <Compile Include="ILogicEntry.cs" />
+    <Compile Include="ILogic.cs" />
     <Compile Include="IType.cs" />
+    <Compile Include="Message.cs" />
     <Compile Include="MessageEnv.cs" />
     <Compile Include="Object.cs" />
+    <Compile Include="OpcodeDefine.cs" />
   </ItemGroup>
   <ItemGroup>
     <None Include="packages.config" />

+ 2 - 2
CSharp/Game/Component/ConfigAttribute.cs

@@ -7,9 +7,9 @@ namespace Component
 	{
 		public string RelativeDirectory { get; set; }
 
-		public ConfigAttribute(string relativeDirectory = @"..\Config")
+		public ConfigAttribute()
 		{
-			this.RelativeDirectory = relativeDirectory;
+			this.RelativeDirectory = @"..\Config";
 		}
 	}
 }

+ 11 - 0
CSharp/Game/Component/EventAttribute.cs

@@ -0,0 +1,11 @@
+using System;
+
+namespace Component
+{
+	[AttributeUsage(AttributeTargets.Class)]
+	public class EventAttribute : Attribute
+	{
+		public EventType Type { get; set; }
+		public EventNumber Number { get; set; }
+	}
+}

+ 19 - 0
CSharp/Game/Component/EventDefine.cs

@@ -0,0 +1,19 @@
+
+namespace Component
+{
+	// 定义事件类型
+	public enum EventType: short
+	{
+		// 登录world前触发
+		LoginWorldBeforeEvent,
+	}
+
+	public enum EventNumber: short
+	{
+		#region    LoginWorldBeforeEvent
+
+		CheckPlayerEvent,
+
+		#endregion LoginWorldBeforeEvent
+	}
+}

+ 2 - 18
CSharp/Game/Component/HandlerAttribute.cs

@@ -1,26 +1,10 @@
 using System;
 
-namespace Logic
+namespace Component
 {
 	[AttributeUsage(AttributeTargets.Class)]
 	public class HandlerAttribute : Attribute
 	{
-		private short opcode;
-		public HandlerAttribute(short opcode)
-		{
-			this.opcode = opcode;
-		}
-
-		public short Opcode
-		{
-			get
-			{
-				return this.opcode;
-			}
-			set
-			{
-				this.opcode = value;
-			}
-		}
+		public Opcode Opcode { get; set; }
 	}
 }

+ 8 - 0
CSharp/Game/Component/IEvent.cs

@@ -0,0 +1,8 @@
+
+namespace Component
+{
+	public interface IEvent
+	{
+		void Trigger(MessageEnv messageEnv);
+	}
+}

+ 8 - 0
CSharp/Game/Component/ILogic.cs

@@ -0,0 +1,8 @@
+
+namespace Component
+{
+	public interface ILogic
+	{
+		void Handle(Opcode opcode, byte[] content);
+	}
+}

+ 0 - 8
CSharp/Game/Component/ILogicEntry.cs

@@ -1,8 +0,0 @@
-
-namespace Component
-{
-	public interface ILogicEntry
-	{
-		void Enter(MessageEnv messageEnv, short opcode, byte[] content);
-	}
-}

+ 12 - 0
CSharp/Game/Component/Message.cs

@@ -0,0 +1,12 @@
+
+namespace Component
+{
+	public class CChat
+	{
+		public string Content { get; set; }
+	}
+
+	public class CLoginWorld
+	{
+	}
+}

+ 11 - 0
CSharp/Game/Component/OpcodeDefine.cs

@@ -0,0 +1,11 @@
+
+namespace Component
+{
+	public enum Opcode: short
+	{
+		ReloadHandler = 1,
+		ReloadConfig  = 2,
+		Chat          = 3,
+		LoginWorld    = 4,
+	}
+}

+ 14 - 0
CSharp/Game/Logic/Event/LoginWorldBeforeEvent.cs

@@ -0,0 +1,14 @@
+using Component;
+using Log;
+
+namespace Logic
+{
+	[EventAttribute(Type = EventType.LoginWorldBeforeEvent, Number = EventNumber.CheckPlayerEvent)]
+	public class CheckPlayerEvent : IEvent
+	{
+		public void Trigger(MessageEnv messageEnv)
+		{
+			Logger.Trace("check player");
+		}
+	}
+}

+ 5 - 2
CSharp/Game/Logic/Handler/ChatHandler.cs

@@ -5,14 +5,17 @@ using Component;
 
 namespace Logic
 {
-	[HandlerAttribute(3)]
+	[HandlerAttribute(Opcode = Opcode.Chat)]
 	class ChatHandler: IHandler
 	{
 		public void Handle(MessageEnv messageEnv, byte[] content)
 		{
-			var world = messageEnv.Get<World.World>();
+			var chat = MongoHelper.FromBson<CChat>(content);
+
+			var world = World.World.Instance;
 			var globalConfig = world.Config.Get<GlobalConfig>(1);
 			Logger.Debug(MongoHelper.ToJson(globalConfig));
+			Logger.Debug("chat content: {0}", chat.Content);
 		}
 	}
 }

+ 15 - 0
CSharp/Game/Logic/Handler/LoginWorldHandler.cs

@@ -0,0 +1,15 @@
+using Component;
+
+namespace Logic.Handler
+{
+	[Handler(Opcode = Opcode.LoginWorld)]
+	public class LoginWorldHandler: IHandler
+	{
+		public void Handle(MessageEnv messageEnv, byte[] content)
+		{
+			var world = World.World.Instance;
+			// 登录world前触发事件
+			world.Logic.Trigger(messageEnv, EventType.LoginWorldBeforeEvent);
+		}
+	}
+}

+ 6 - 6
CSharp/Game/Logic/Handler/ReloadHandler.cs

@@ -2,23 +2,23 @@
 
 namespace Logic
 {
-	[HandlerAttribute(1)]
+	[HandlerAttribute(Opcode = Opcode.ReloadHandler)]
 	class ReloadHandlerHandler : IHandler
 	{
 		public void Handle(MessageEnv messageEnv, byte[] content)
 		{
-			var world = messageEnv.Get<World.World>();
-			world.ReloadLogic();
+			var world = World.World.Instance;
+			world.Logic.Reload();
 		}
 	}
 
-	[HandlerAttribute(2)]
+	[HandlerAttribute(Opcode = Opcode.ReloadConfig)]
 	class ReloadConfigHandler: IHandler
 	{
 		public void Handle(MessageEnv messageEnv, byte[] content)
 		{
-			var world = messageEnv.Get<World.World>();
-			world.ReloadConfig();
+			var world = World.World.Instance;
+			world.Config.Reload();
 		}
 	}
 }

+ 2 - 0
CSharp/Game/Logic/Logic.csproj

@@ -34,7 +34,9 @@
     <Reference Include="System.Core" />
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="Event\LoginWorldBeforeEvent.cs" />
     <Compile Include="Handler\ChatHandler.cs" />
+    <Compile Include="Handler\LoginWorldHandler.cs" />
     <Compile Include="Handler\ReloadHandler.cs" />
   </ItemGroup>
   <ItemGroup>

+ 120 - 0
CSharp/Game/World/Logic.cs

@@ -0,0 +1,120 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using Component;
+using Helper;
+using Log;
+
+namespace World
+{
+	public class Logic : ILogic
+    {
+		private static readonly Logic instance = new Logic();
+
+		private Dictionary<Opcode, IHandler> handlers;
+
+		private Dictionary<EventType, SortedDictionary<EventNumber, IEvent>> events;
+
+		public static Logic Instance
+		{
+			get
+			{
+				return instance;
+			}
+		}
+
+		private Logic()
+		{
+			this.Load();
+		}
+
+		private void Load()
+		{
+			string dllPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logic.dll");
+			var assembly = LoaderHelper.Load(dllPath);
+			Type[] types = assembly.GetTypes();
+
+			// 加载封包处理器
+			this.handlers = new Dictionary<Opcode, IHandler>();
+			foreach (var type in types)
+			{
+				object[] attrs = type.GetCustomAttributes(typeof(HandlerAttribute), false);
+				if (attrs.Length == 0)
+				{
+					continue;
+				}
+				var handler = (IHandler)Activator.CreateInstance(type);
+				Opcode opcode = ((HandlerAttribute)attrs[0]).Opcode;
+				if (this.handlers.ContainsKey(opcode))
+				{
+					throw new Exception(string.Format(
+						"same handler opcode, opcode: {0}, name: {1}", opcode, type.Name));
+				}
+				this.handlers[opcode] = handler;
+			}
+
+			// 加载事件处理器
+			this.events = new Dictionary<EventType, SortedDictionary<EventNumber, IEvent>>();
+			foreach (var type in types)
+			{
+				object[] attrs = type.GetCustomAttributes(typeof(EventAttribute), false);
+				if (attrs.Length == 0)
+				{
+					continue;
+				}
+				var evt = (IEvent)Activator.CreateInstance(type);
+				var eventType = ((EventAttribute)attrs[0]).Type;
+				var eventNumber = ((EventAttribute)attrs[0]).Number;
+				if (!this.events.ContainsKey(eventType))
+				{
+					this.events[eventType] = new SortedDictionary<EventNumber, IEvent>();
+				}
+				if (this.events[eventType].ContainsKey(eventNumber))
+				{
+					throw new Exception(string.Format(
+						"same event number, type: {0}, number: {1}, name: {2}", 
+						eventType, eventNumber, type.Name));
+				}
+				this.events[eventType][eventNumber] = evt;
+			}
+		}
+
+		public void Reload()
+		{
+			this.Load();
+		}
+
+		public void Handle(Opcode opcode, byte[] content)
+	    {
+		    IHandler handler = null;
+			if (!handlers.TryGetValue(opcode, out handler))
+			{
+				throw new Exception(string.Format("not found handler opcode {0}", opcode));
+			}
+
+			try
+			{
+				var messageEnv = new MessageEnv();
+				handler.Handle(messageEnv, content);
+			}
+			catch (Exception e)
+			{
+				Logger.Trace("message handle error: {0}", e.Message);
+			}
+	    }
+
+		public void Trigger(MessageEnv messageEnv, EventType type)
+		{
+			SortedDictionary<EventNumber, IEvent> iEventDict = null;
+			if (!this.events.TryGetValue(type, out iEventDict))
+			{
+				return;
+			}
+
+			foreach (var iEvent in iEventDict)
+			{
+				iEvent.Value.Trigger(messageEnv);
+			}
+		}
+	}
+}

+ 0 - 74
CSharp/Game/World/LogicEntry.cs

@@ -1,74 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using Component;
-using Helper;
-using Logic;
-
-namespace World
-{
-	public class LogicEntry : ILogicEntry
-    {
-		private static readonly LogicEntry instance = new LogicEntry();
-
-	    private Dictionary<short, IHandler> handlers;
-
-		public static LogicEntry Instance
-		{
-			get
-			{
-				return instance;
-			}
-		}
-
-		public LogicEntry()
-		{
-			this.Load();
-		}
-
-		public void Load()
-		{
-			this.handlers = new Dictionary<short, IHandler>();
-			string dllPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logic.dll");
-			if (!File.Exists(dllPath))
-			{
-				throw new Exception(string.Format("not found logic dll, path: {0}", dllPath));
-			}
-			var assembly = LoaderHelper.Load(dllPath);
-			Type[] types = assembly.GetTypes();
-
-			foreach (var type in types)
-			{
-				object[] attrs = type.GetCustomAttributes(typeof(HandlerAttribute), false);
-				if (attrs.Length == 0)
-				{
-					continue;
-				}
-				var handler = (IHandler)Activator.CreateInstance(type);
-				short opcode = ((HandlerAttribute)attrs[0]).Opcode;
-				if (this.handlers.ContainsKey(opcode))
-				{
-					throw new Exception(string.Format(
-						"same opcode, opcode: {0}, name: {1}", opcode, type.Name));
-				}
-				this.handlers[opcode] = handler;
-			}
-		}
-
-		public void Reload()
-		{
-			this.Load();
-		}
-
-	    public void Enter(MessageEnv messageEnv, short opcode, byte[] content)
-	    {
-		    IHandler handler = null;
-			if (!handlers.TryGetValue(opcode, out handler))
-			{
-				throw new Exception(string.Format("not found handler opcode {0}", opcode));
-			}
-
-			handler.Handle(messageEnv, content);
-	    }
-	}
-}

+ 5 - 24
CSharp/Game/World/World.cs

@@ -1,14 +1,11 @@
-using System;
-using Component;
-using Log;
-
+
 namespace World
 {
 	public class World
 	{
 		private static readonly World instance = new World();
 
-		private readonly LogicEntry logicEntry = LogicEntry.Instance;
+		private readonly Logic logic = Logic.Instance;
 
 		private readonly Config config = Config.Instance;
 
@@ -20,27 +17,11 @@ namespace World
 			}
 		}
 
-		public void ReloadLogic()
-		{
-			this.logicEntry.Reload();
-		}
-
-		public void ReloadConfig()
-		{
-			this.config.Reload();
-		}
-
-		public void Enter(short opcode, byte[] content)
+		public Logic Logic
 		{
-			try
-			{
-				var messageEnv = new MessageEnv();
-				messageEnv.Set(this);
-				this.logicEntry.Enter(messageEnv, opcode, content);
-			}
-			catch (Exception e)
+			get
 			{
-				Logger.Trace("message handle error: {0}", e.Message);
+				return this.logic;
 			}
 		}
 

+ 1 - 1
CSharp/Game/World/World.csproj

@@ -38,7 +38,7 @@
   <ItemGroup>
     <Compile Include="Config.cs" />
     <Compile Include="Config\GlobalConfig.cs" />
-    <Compile Include="LogicEntry.cs" />
+    <Compile Include="Logic.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="World.cs" />
   </ItemGroup>

+ 4 - 3
CSharp/Game/WorldTest/WorldTest.cs

@@ -1,4 +1,5 @@
 using System.Threading;
+using Component;
 using Helper;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 
@@ -11,13 +12,13 @@ namespace WorldTest
 		public void TestReload()
 		{
 			var world = World.World.Instance;
-			world.Enter(3, "tanghai".ToByteArray());
+			world.Logic.Handle(Opcode.LoginWorld, MongoHelper.ToBson(new CLoginWorld()));
 			int count = 2;
 			while (--count != 0)
 			{
-				world.Enter(1, "tanghai".ToByteArray());
+				world.Logic.Handle(Opcode.ReloadHandler, "tanghai".ToByteArray());
 				Thread.Sleep(1);
-				world.ReloadLogic();
+				world.Logic.Reload();
 			}
 		}
 	}

+ 6 - 1
CSharp/Platform/Helper/LoaderHelper.cs

@@ -1,4 +1,5 @@
-using System.IO;
+using System;
+using System.IO;
 using System.Reflection;
 
 namespace Helper
@@ -7,6 +8,10 @@ namespace Helper
 	{
 		public static Assembly Load(string path)
 		{
+			if (!File.Exists(path))
+			{
+				throw new Exception(string.Format("not found path, path: {0}", path));
+			}
 			byte[] buffer = File.ReadAllBytes(path);
 			var assembly = Assembly.Load(buffer);
 			return assembly;