提交 a5e84881 编写于 作者: T tanghai

改成Excel来配置启动项,编译通过

上级 2a7b1c56
......@@ -39,8 +39,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MongoDB.Driver.Core", "Serv
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MongoDB.Driver.GridFS", "Server\ThirdParty\MongoDBDriver\MongoDB.Driver.GridFS\MongoDB.Driver.GridFS.csproj", "{2ACC29FB-55CD-4307-B1D1-CC3922BC2CE7}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Proto2CS", "Tools\Proto2CS\Proto2CS.csproj", "{B4CC4BDA-F753-4005-87D1-EA9DA6C59706}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
......@@ -207,18 +205,6 @@ Global
{2ACC29FB-55CD-4307-B1D1-CC3922BC2CE7}.Release|x64.Build.0 = Release|Any CPU
{2ACC29FB-55CD-4307-B1D1-CC3922BC2CE7}.Release|x86.ActiveCfg = Release|Any CPU
{2ACC29FB-55CD-4307-B1D1-CC3922BC2CE7}.Release|x86.Build.0 = Release|Any CPU
{B4CC4BDA-F753-4005-87D1-EA9DA6C59706}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B4CC4BDA-F753-4005-87D1-EA9DA6C59706}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B4CC4BDA-F753-4005-87D1-EA9DA6C59706}.Debug|x64.ActiveCfg = Debug|Any CPU
{B4CC4BDA-F753-4005-87D1-EA9DA6C59706}.Debug|x64.Build.0 = Debug|Any CPU
{B4CC4BDA-F753-4005-87D1-EA9DA6C59706}.Debug|x86.ActiveCfg = Debug|Any CPU
{B4CC4BDA-F753-4005-87D1-EA9DA6C59706}.Debug|x86.Build.0 = Debug|Any CPU
{B4CC4BDA-F753-4005-87D1-EA9DA6C59706}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B4CC4BDA-F753-4005-87D1-EA9DA6C59706}.Release|Any CPU.Build.0 = Release|Any CPU
{B4CC4BDA-F753-4005-87D1-EA9DA6C59706}.Release|x64.ActiveCfg = Release|Any CPU
{B4CC4BDA-F753-4005-87D1-EA9DA6C59706}.Release|x64.Build.0 = Release|Any CPU
{B4CC4BDA-F753-4005-87D1-EA9DA6C59706}.Release|x86.ActiveCfg = Release|Any CPU
{B4CC4BDA-F753-4005-87D1-EA9DA6C59706}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
......@@ -239,7 +225,6 @@ Global
{B91E7D43-CCF1-49FC-ACF5-1C88A1C81FA7} = {14963D84-2A63-48CF-AE13-DCF71F1E13A0}
{AAF14EDB-BB72-42A9-80AA-3E0E113AC4CA} = {14963D84-2A63-48CF-AE13-DCF71F1E13A0}
{2ACC29FB-55CD-4307-B1D1-CC3922BC2CE7} = {14963D84-2A63-48CF-AE13-DCF71F1E13A0}
{B4CC4BDA-F753-4005-87D1-EA9DA6C59706} = {4BC66C3C-D55F-4FAA-A2F5-29E8EB1797AE}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {EABC01E3-3EB5-47EF-B46E-AAD8BB3585F1}
......
{"_id":1,"InnerIP":"127.0.0.1","InnerPort":"20001","OuterIP":"127.0.0.1"}
{"_id":2,"InnerIP":"127.0.0.2","InnerPort":"20002","OuterIP":"127.0.0.2"}
{"_id":1,"Process":1,"Zone":1,"SceneType":"Realm","Name":"Realm","OuterPort":10002}
{"_id":2,"Process":1,"Zone":1,"SceneType":"Gate","Name":"Gate1","OuterPort":10003}
{"_id":3,"Process":1,"Zone":1,"SceneType":"Gate","Name":"Gate2","OuterPort":10004}
{"_id":4,"Process":1,"Zone":1,"SceneType":"Location","Name":"Location"}
{"_id":5,"Process":1,"Zone":1,"SceneType":"Map","Name":"Map"}
{"_id":1,"DBConnection":"mongdb://127.0.0.1","DBName":"ET1"}
{"_id":2,"DBConnection":"mongdb://127.0.0.1","DBName":"ET2"}
......@@ -16,68 +16,25 @@ namespace ETModel
try
{
Game.EventSystem.Add(DLLType.Model, typeof(Game).Assembly);
Game.EventSystem.Add(DLLType.Hotfix, DllHelper.GetHotfixAssembly());
Game.EventSystem.Add(typeof(Game).Assembly);
Game.EventSystem.Add(DllHelper.GetHotfixAssembly());
MongoHelper.Init();
// 命令行参数
Options options = null;
Parser.Default.ParseArguments<Options>(args)
.WithNotParsed(error => throw new Exception($"命令行格式错误!"))
.WithParsed(o => { Game.Options = o; });
IdGenerater.AppId = Game.Options.Id;
.WithParsed(o => { options = o; });
// 启动配置
StartConfig allConfig = MongoHelper.FromJson<StartConfig>(File.ReadAllText(Path.Combine("../Config/StartConfig/", Game.Options.Config)));
StartConfig startConfig = allConfig.Get(Game.Options.Id);
Game.Scene = EntityFactory.CreateScene(0, "Process", SceneType.Process);
Game.Scene.AddComponent(options);
IdGenerater.Process = (byte) options.Process;
LogManager.Configuration.Variables["appIdFormat"] = $"{Game.Scene.Id:0000}";
Game.Scene.AddComponent<StartConfigComponent, StartConfig, long>(allConfig, startConfig.Id);
Log.Info($"server start........................ {Game.Scene.Id}");
Game.Scene.AddComponent<TimerComponent>();
Game.Scene.AddComponent<OpcodeTypeComponent>();
Game.Scene.AddComponent<MessageDispatcherComponent>();
Game.Scene.AddComponent<ConfigComponent>();
Game.Scene.AddComponent<CoroutineLockComponent>();
// 发送普通actor消息
Game.Scene.AddComponent<ActorMessageSenderComponent>();
// 发送location actor消息
Game.Scene.AddComponent<ActorLocationSenderComponent>();
// 访问location server的组件
Game.Scene.AddComponent<LocationProxyComponent>();
Game.Scene.AddComponent<ActorMessageDispatcherComponent>();
// 数值订阅组件
Game.Scene.AddComponent<NumericWatcherComponent>();
// 控制台组件
Game.Scene.AddComponent<ConsoleComponent>();
OuterConfig outerConfig = startConfig.GetComponent<OuterConfig>();
if (outerConfig != null)
{
// 外网消息组件
Game.Scene.AddComponent<NetOuterComponent, string>(outerConfig.Address);
}
InnerConfig innerConfig = startConfig.GetComponent<InnerConfig>();
if (innerConfig != null)
{
// 内网消息组件
Game.Scene.AddComponent<NetInnerComponent, string>(innerConfig.Address);
}
DBConfig dbConfig = startConfig.GetComponent<DBConfig>();
if (dbConfig != null)
{
Game.Scene.AddComponent<DBComponent, DBConfig>(dbConfig);
}
// 先加这里,后面删掉
Game.EventSystem.Run(EventIdType.AfterScenesAdd);
......
......@@ -10,7 +10,7 @@ namespace ETHotfix
{
Player player = session.GetComponent<SessionPlayerComponent>().Player;
// 在map服务器上创建战斗Unit
long mapInstanceId = StartConfigComponent.Instance.GetByName("Map1").SceneInstanceId;
long mapInstanceId = StartSceneConfigCategory.Instance.GetBySceneName(session.DomainZone(), "Map").SceneId;
M2G_CreateUnit createUnit = (M2G_CreateUnit)await ActorMessageSenderComponent.Instance.Call(
mapInstanceId, new G2M_CreateUnit() { PlayerId = player.Id, GateSessionId = session.InstanceId });
player.UnitId = createUnit.UnitId;
......
......@@ -10,16 +10,14 @@ namespace ETHotfix
protected override async ETTask Run(Session session, C2R_Login request, R2C_Login response, Action reply)
{
// 随机分配一个Gate
StartConfig config = RealmGateAddressHelper.GetGate();
StartSceneConfig config = RealmGateAddressHelper.GetGate(session.DomainZone());
//Log.Debug($"gate address: {MongoHelper.ToJson(config)}");
// 向gate请求一个key,客户端可以拿着这个key连接gate
G2R_GetLoginKey g2RGetLoginKey = (G2R_GetLoginKey) await ActorMessageSenderComponent.Instance.Call(
config.SceneInstanceId, new R2G_GetLoginKey() {Account = request.Account});
config.SceneId, new R2G_GetLoginKey() {Account = request.Account});
string outerAddress = config.GetParent<StartConfig>().GetComponent<OuterConfig>().Address2;
response.Address = outerAddress;
response.Address = config.OuterAddress;
response.Key = g2RGetLoginKey.Key;
response.GateId = g2RGetLoginKey.GateId;
reply();
......
using ETModel;
using System.Collections.Generic;
using ETModel;
namespace ETHotfix
{
public static class RealmGateAddressHelper
{
public static StartConfig GetGate()
public static StartSceneConfig GetGate(int zone)
{
int count = StartConfigComponent.Instance.Gates.Count;
List<StartSceneConfig> zoneGates = StartSceneConfigCategory.Instance.Gates[zone];
int n = RandomHelper.RandomNumber(0, zoneGates.Count);
int n = RandomHelper.RandomNumber(0, count);
return StartConfigComponent.Instance.Gates[n];
return zoneGates[n];
}
}
}
......@@ -8,7 +8,7 @@ namespace ETHotfix
{
protected override async ETTask Run(Session session, M2A_Reload request, A2M_Reload response, Action reply)
{
Game.EventSystem.Add(DLLType.Hotfix, DllHelper.GetHotfixAssembly());
Game.EventSystem.Add(DllHelper.GetHotfixAssembly());
reply();
await ETTask.CompletedTask;
}
......
......@@ -57,59 +57,48 @@ namespace ETHotfix
{
throw new Exception($"actor id is 0: {MongoHelper.ToJson(message)}");
}
string address = StartConfigComponent.Instance.GetProcessInnerAddress(IdGenerater.GetProcessId(actorId));
int process = IdGenerater.GetProcess(actorId);
string address = StartProcessConfigCategory.Instance.Get(process).InnerAddress;
Session session = NetInnerComponent.Instance.Get(address);
message.ActorId = actorId;
session.Send(message);
}
public static ETTask<IActorResponse> Call(this ActorMessageSenderComponent self, long actorId, IActorRequest message)
public static ETTask<IActorResponse> Call(this ActorMessageSenderComponent self, long actorId, IActorRequest message, bool exception = true)
{
if (actorId == 0)
{
throw new Exception($"actor id is 0: {MongoHelper.ToJson(message)}");
}
var tcs = new ETTaskCompletionSource<IActorResponse>();
string address = StartConfigComponent.Instance.GetProcessInnerAddress(IdGenerater.GetProcessId(actorId));
int process = IdGenerater.GetProcess(actorId);
string address = StartProcessConfigCategory.Instance.Get(process).InnerAddress;
Session session = NetInnerComponent.Instance.Get(address);
message.ActorId = actorId & IdGenerater.HeadMask | IdGenerater.Head;
InstanceIdStruct instanceIdStruct = new InstanceIdStruct(actorId);
instanceIdStruct.Process = IdGenerater.Process;
message.ActorId = instanceIdStruct.ToLong();
message.RpcId = ++self.RpcId;
var tcs = new ETTaskCompletionSource<IActorResponse>();
self.requestCallback.Add(message.RpcId, new ActorMessageSender((response) =>
{
if (ErrorCode.IsRpcNeedThrowException(response.Error))
if (exception && ErrorCode.IsRpcNeedThrowException(response.Error))
{
tcs.SetException(new Exception($"Rpc error: {MongoHelper.ToJson(response)}"));
return;
}
tcs.SetResult(response);
}));
session.Send(message);
return tcs.Task;
}
public static ETTask<IActorResponse> CallWithoutException(this ActorMessageSenderComponent self, long actorId, IActorRequest message)
public static async ETTask<IActorResponse> CallWithoutException(this ActorMessageSenderComponent self, long actorId, IActorRequest message)
{
if (actorId == 0)
{
throw new Exception($"actor id is 0: {MongoHelper.ToJson(message)}");
}
string address = StartConfigComponent.Instance.GetProcessInnerAddress(IdGenerater.GetProcessId(actorId));
Session session = NetInnerComponent.Instance.Get(address);
message.ActorId = actorId & IdGenerater.HeadMask | IdGenerater.Head;
message.RpcId = ++self.RpcId;
var tcs = new ETTaskCompletionSource<IActorResponse>();
self.requestCallback.Add(message.RpcId, new ActorMessageSender((response) =>
{
tcs.SetResult(response);
}));
session.Send(message);
return tcs.Task;
return await self.Call(actorId, message, false);
}
public static void RunMessage(this ActorMessageSenderComponent self, IActorResponse response)
......
......@@ -22,28 +22,28 @@ namespace ETHotfix
public static async ETTask Add(this LocationProxyComponent self, long key, long instanceId)
{
await MessageHelper.CallActor(
StartConfigComponent.Instance.GetInstanceId(SceneType.Location),
StartSceneConfigCategory.Instance.LocationConfig.SceneId,
new ObjectAddRequest() { Key = key, InstanceId = instanceId });
}
public static async ETTask Lock(this LocationProxyComponent self, long key, long instanceId, int time = 1000)
{
await MessageHelper.CallActor(
StartConfigComponent.Instance.GetInstanceId(SceneType.Location),
StartSceneConfigCategory.Instance.LocationConfig.SceneId,
new ObjectLockRequest() { Key = key, InstanceId = instanceId, Time = time });
}
public static async ETTask UnLock(this LocationProxyComponent self, long key, long oldInstanceId, long instanceId)
{
await MessageHelper.CallActor(
StartConfigComponent.Instance.GetInstanceId(SceneType.Location),
StartSceneConfigCategory.Instance.LocationConfig.SceneId,
new ObjectUnLockRequest() { Key = key, OldInstanceId = oldInstanceId, InstanceId = instanceId });
}
public static async ETTask Remove(this LocationProxyComponent self, long key)
{
await MessageHelper.CallActor(
StartConfigComponent.Instance.GetInstanceId(SceneType.Location),
StartSceneConfigCategory.Instance.LocationConfig.SceneId,
new ObjectRemoveRequest() { Key = key });
}
......@@ -55,7 +55,7 @@ namespace ETHotfix
}
ObjectGetResponse response =
(ObjectGetResponse)await MessageHelper.CallActor(
StartConfigComponent.Instance.GetInstanceId(SceneType.Location),
StartSceneConfigCategory.Instance.LocationConfig.SceneId,
new ObjectGetRequest() { Key = key });
return response.InstanceId;
}
......
......@@ -9,6 +9,7 @@ namespace ETHotfix
{
public override void Awake(ConfigComponent self)
{
ConfigComponent.Instance = self;
self.Awake();
}
}
......@@ -22,7 +23,16 @@ namespace ETHotfix
}
}
public static class ConfigComponentHelper
[ObjectSystem]
public class ConfigDestroySystem : DestroySystem<ConfigComponent>
{
public override void Destroy(ConfigComponent self)
{
ConfigComponent.Instance = null;
}
}
public static class ConfigComponentSystem
{
public static void Awake(this ConfigComponent self)
{
......@@ -49,53 +59,5 @@ namespace ETHotfix
self.AllConfig[iCategory.ConfigType] = iCategory;
}
}
public static IConfig GetOne(this ConfigComponent self, Type type)
{
ACategory configCategory;
if (!self.AllConfig.TryGetValue(type, out configCategory))
{
throw new Exception($"ConfigComponent not found key: {type.FullName}");
}
return configCategory.GetOne();
}
public static IConfig Get(this ConfigComponent self, Type type, int id)
{
ACategory configCategory;
if (!self.AllConfig.TryGetValue(type, out configCategory))
{
throw new Exception($"ConfigComponent not found key: {type.FullName}");
}
return configCategory.TryGet(id);
}
public static IConfig TryGet(this ConfigComponent self, Type type, int id)
{
ACategory configCategory;
if (!self.AllConfig.TryGetValue(type, out configCategory))
{
return null;
}
return configCategory.TryGet(id);
}
public static IConfig[] GetAll(this ConfigComponent self, Type type)
{
ACategory configCategory;
if (!self.AllConfig.TryGetValue(type, out configCategory))
{
throw new Exception($"ConfigComponent not found key: {type.FullName}");
}
return configCategory.GetAll();
}
public static ACategory GetCategory(this ConfigComponent self, Type type)
{
ACategory configCategory;
bool ret = self.AllConfig.TryGetValue(type, out configCategory);
return ret ? configCategory : null;
}
}
}
\ No newline at end of file
......@@ -6,14 +6,12 @@ using MongoDB.Driver;
namespace ETModel
{
[ObjectSystem]
public class DBComponentAwakeSystem : AwakeSystem<DBComponent, DBConfig>
public class DBComponentAwakeSystem : AwakeSystem<DBComponent, string, string>
{
public override void Awake(DBComponent self, DBConfig dbConfig)
public override void Awake(DBComponent self, string dbConnection, string dbName)
{
string connectionString = dbConfig.ConnectionString;
self.mongoClient = new MongoClient(connectionString);
self.database = self.mongoClient.GetDatabase(dbConfig.DBName);
self.mongoClient = new MongoClient(dbConnection);
self.database = self.mongoClient.GetDatabase(dbName);
self.Transfers.Clear();
foreach (Type type in Game.EventSystem.GetTypes())
......
using System.Net;
using ETModel;
using System.Threading.Tasks;
namespace ETHotfix
{
[HttpHandler(AppType.Gate, "/")]
public class HttpTest : AHttpHandler
{
[Get] // url-> /Login?name=11&age=1111
public string Login(string name, int age, HttpListenerRequest req, HttpListenerResponse resp)
{
Log.Info(name);
Log.Info($"{age}");
return "ok";
}
[Get("t")] // url-> /t
public int Test()
{
System.Console.WriteLine("");
return 1;
}
[Post] // url-> /Test1
public int Test1(HttpListenerRequest req)
{
return 1;
}
[Get] // url-> /Test2
public int Test2(HttpListenerResponse resp)
{
return 1;
}
[Get] // url-> /GetRechargeRecord
public async ETTask<HttpResult> GetRechargeRecord(long id)
{
// var db = Game.Scene.GetComponent<DBProxyComponent>();
// var info = await db.Query<RechargeRecord>(id);
await Task.Delay(1000); // 用于测试
object info = null;
if (info != null)
{
return Ok(data: info);
}
else
{
return Error("ID不存在!");
}
}
}
}
\ No newline at end of file
......@@ -11,10 +11,12 @@
public static async ETVoid HandleIActorRequest(Session session, IActorRequest iActorRequest)
{
long replyId = IdGenerater.GetProcessId(iActorRequest.ActorId);
iActorRequest.ActorId = iActorRequest.ActorId & IdGenerater.HeadMask | IdGenerater.Head;
InstanceIdStruct instanceIdStruct = new InstanceIdStruct(iActorRequest.ActorId);
int replyId = instanceIdStruct.Process;
instanceIdStruct.Process = IdGenerater.Process;
iActorRequest.ActorId = instanceIdStruct.ToLong();
string address = StartConfigComponent.Instance.GetProcessInnerAddress(replyId);
string address = StartProcessConfigCategory.Instance.Get(replyId).InnerAddress;
Session ss = NetInnerComponent.Instance.Get(address);
Entity entity = Game.EventSystem.Get(iActorRequest.ActorId);
if (entity == null)
......@@ -47,8 +49,10 @@
public static async ETVoid HandleIActorMessage(Session session, IActorMessage iActorMessage)
{
long replyId = IdGenerater.GetProcessId(iActorMessage.ActorId);
iActorMessage.ActorId = iActorMessage.ActorId & IdGenerater.HeadMask | IdGenerater.Head;
InstanceIdStruct instanceIdStruct = new InstanceIdStruct(iActorMessage.ActorId);
int replyId = instanceIdStruct.Process;
instanceIdStruct.Process = IdGenerater.Process;
iActorMessage.ActorId = instanceIdStruct.ToLong();
Entity entity = Game.EventSystem.Get(iActorMessage.ActorId);
if (entity == null)
......
......@@ -7,15 +7,37 @@ namespace ETHotfix
{
public override void Run()
{
Options options = Game.Scene.GetComponent<Options>();
StartProcessConfig processConfig = StartProcessConfigCategory.Instance.Get(options.Process);
Game.Scene.AddComponent<TimerComponent>();
Game.Scene.AddComponent<OpcodeTypeComponent>();
Game.Scene.AddComponent<MessageDispatcherComponent>();
Game.Scene.AddComponent<ConfigComponent>();
Game.Scene.AddComponent<CoroutineLockComponent>();
// 发送普通actor消息
Game.Scene.AddComponent<ActorMessageSenderComponent>();
// 发送location actor消息
Game.Scene.AddComponent<ActorLocationSenderComponent>();
// 访问location server的组件
Game.Scene.AddComponent<LocationProxyComponent>();
Game.Scene.AddComponent<ActorMessageDispatcherComponent>();
// 数值订阅组件
Game.Scene.AddComponent<NumericWatcherComponent>();
// 控制台组件
Game.Scene.AddComponent<ConsoleComponent>();
Game.Scene.AddComponent<NetInnerComponent, string>(processConfig.InnerAddress);
RunInner().Coroutine();
}
public async ETVoid RunInner()
{
foreach (StartConfig startConfig in StartConfigComponent.Instance.StartConfig.List)
var processScenes = StartSceneConfigCategory.Instance.GetByProcess(IdGenerater.Process);
foreach (StartSceneConfig startConfig in processScenes)
{
SceneConfig sceneConfig = startConfig.GetComponent<SceneConfig>();
await SceneFactory.Create(Game.Scene, startConfig.Id, sceneConfig.Name, sceneConfig.SceneType);
await SceneFactory.Create(Game.Scene, startConfig.SceneId, startConfig.Zone, startConfig.Name, startConfig.Type, startConfig);
}
}
}
......
......@@ -6,12 +6,13 @@ namespace ETHotfix
{
public static async ETTask<Scene> Create(Entity parent, string name, SceneType sceneType)
{
return await Create(parent, IdGenerater.GenerateSceneId(), name, sceneType);
long id = IdGenerater.GenerateId();
return await Create(parent, id, parent.DomainZone(), name, sceneType);
}
public static async ETTask<Scene> Create(Entity parent, long id, string name, SceneType sceneType)
public static async ETTask<Scene> Create(Entity parent, long id, int zone, string name, SceneType sceneType, StartSceneConfig startSceneConfig = null)
{
Scene scene = EntityFactory.CreateScene(id, name, sceneType);
Scene scene = EntitySceneFactory.CreateScene(id, zone, sceneType, name);
scene.Parent = parent;
scene.AddComponent<MailBoxComponent, MailboxType>(MailboxType.UnOrderMessageDispatcher);
......@@ -19,8 +20,10 @@ namespace ETHotfix
switch (scene.SceneType)
{
case SceneType.Realm:
scene.AddComponent<NetOuterComponent, string>($"{startSceneConfig.OuterPort}:{startSceneConfig.OuterPort}");
break;
case SceneType.Gate:
scene.AddComponent<NetOuterComponent, string>($"{startSceneConfig.OuterPort}:{startSceneConfig.OuterPort}");
scene.AddComponent<PlayerComponent>();
scene.AddComponent<GateSessionKeyComponent>();
break;
......
......@@ -30,7 +30,4 @@
<ProjectReference Include="..\ThirdParty\MongoDBDriver\MongoDB.Driver.Core\MongoDB.Driver.Core.csproj" />
<ProjectReference Include="..\ThirdParty\MongoDBDriver\MongoDB.Driver\MongoDB.Driver.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Module\Http\" />
</ItemGroup>
</Project>
\ No newline at end of file
......@@ -80,7 +80,7 @@ namespace ETModel
case "reload":
try
{
Game.EventSystem.Add(DLLType.Hotfix, DllHelper.GetHotfixAssembly());
Game.EventSystem.Add(DllHelper.GetHotfixAssembly());
}
catch (Exception e)
{
......
using System;
using System.Collections.Generic;
using System.Net;
namespace ETModel
{
[ObjectSystem]
public class StartConfigComponentSystem: AwakeSystem<StartConfigComponent, StartConfig, long>
{
public override void Awake(StartConfigComponent self, StartConfig allConfig, long id)
{
self.Awake(allConfig, id);
}
}
public class StartConfigComponent: Entity
{
public static StartConfigComponent Instance { get; private set; }
// 所有进程的配置
public StartConfig AllConfig;
// 当前进程的配置
public StartConfig StartConfig;
// 所有domain的字典
private Dictionary<long, StartConfig> configDict = new Dictionary<long, StartConfig>();
// 所有有内网地址的进程字典
private Dictionary<long, string> innerAddressDict = new Dictionary<long, string>();
// 所有agent
public Dictionary<long, StartConfig> Agents = new Dictionary<long, StartConfig>();
private Dictionary<string, StartConfig> nameDict = new Dictionary<string, StartConfig>();
private Dictionary<int, StartConfig> typeDict = new Dictionary<int, StartConfig>();
public List<StartConfig> Gates { get; } = new List<StartConfig>();
public void Awake(StartConfig allConfig, long id)
{
Instance = this;
this.AllConfig = allConfig;
this.AllConfig.Parent = this;
// 每个进程的配置
foreach (StartConfig s in this.AllConfig.List)
{
s.SceneInstanceId = (s.Id << IdGenerater.HeadPos) + s.Id;
if (s.Id == id)
{
this.StartConfig = s;
}
InnerConfig innerConfig = s.GetComponent<InnerConfig>();
if (innerConfig != null)
{
this.innerAddressDict.Add(s.Id, innerConfig.Address);
}
// 每个进程里面domain的配置
foreach (StartConfig startConfig in s.List)
{
startConfig.SceneInstanceId = (startConfig.Parent.Id << IdGenerater.HeadPos) + startConfig.Id;
this.configDict.Add(startConfig.Id, startConfig);
SceneConfig sceneConfig = startConfig.GetComponent<SceneConfig>();
switch (sceneConfig.SceneType)
{
case SceneType.Gate:
this.Gates.Add(startConfig);
break;
case SceneType.Map:
this.nameDict.Add(sceneConfig.Name, startConfig);
break;
default:
this.typeDict.Add((int)sceneConfig.SceneType, startConfig);
break;
}
}
}
}
public long GetInstanceId(SceneType sceneType)
{
if (!this.typeDict.TryGetValue((int) sceneType, out StartConfig startConfig))
{
throw new Exception($"GetInstanceId cant get StartConfig: {sceneType}");
}
return startConfig.SceneInstanceId;
}
public StartConfig GetByType(SceneType sceneType)
{
if (!this.typeDict.TryGetValue((int) sceneType, out StartConfig startConfig))
{
throw new Exception($"GetByType cant get StartConfig: {sceneType}");
}
return startConfig;
}
public StartConfig GetByName(string sceneName)
{
if (!this.nameDict.TryGetValue(sceneName, out StartConfig startConfig))
{
throw new Exception($"GetByName cant get StartConfig: {sceneName}");
}
return startConfig;
}
public override void Dispose()
{
if (this.IsDisposed)
{
return;
}
base.Dispose();
Instance = null;
this.configDict.Clear();
this.innerAddressDict.Clear();
this.Gates.Clear();
this.Agents.Clear();
this.typeDict.Clear();
this.nameDict.Clear();
this.StartConfig = null;
}
public StartConfig GetAgent(long agentId)
{
return this.Agents[agentId];
}
public StartConfig Get(long id)
{
try
{
return this.configDict[id];
}
catch (Exception e)
{
throw new Exception($"not found startconfig: {id}", e);
}
}
public string GetProcessInnerAddress(long id)
{
try
{
// 内网地址需要找到进程配置,进程配置是domain配置的parent
return this.innerAddressDict[id];
}
catch (Exception e)
{
throw new Exception($"not found innerAddress: {id}", e);
}
}
public StartConfig[] GetAll()
{
List<StartConfig> startConfigs = new List<StartConfig>();
foreach (var kv in this.AllConfig.Children)
{
startConfigs.Add((StartConfig)kv.Value);
}
return startConfigs.ToArray();
}
}
}
\ No newline at end of file
namespace ETModel
{
[Config]
public partial class StartProcessConfigCategory : ACategory<StartProcessConfig>
{
public static StartProcessConfigCategory Instance;
public StartProcessConfigCategory()
{
Instance = this;
}
}
public partial class StartProcessConfig: IConfig
{
public long Id { get; set; }
public string InnerIP;
public string InnerPort;
public string OuterIP;
}
}
namespace ETModel
{
[Config]
public partial class StartSceneConfigCategory : ACategory<StartSceneConfig>
{
public static StartSceneConfigCategory Instance;
public StartSceneConfigCategory()
{
Instance = this;
}
}
public partial class StartSceneConfig: IConfig
{
public long Id { get; set; }
public int Process;
public int Zone;
public string SceneType;
public string Name;
public int OuterPort;
}
}
namespace ETModel
{
[Config]
public partial class StartZoneConfigCategory : ACategory<StartZoneConfig>
{
public static StartZoneConfigCategory Instance;
public StartZoneConfigCategory()
{
Instance = this;
}
}
public partial class StartZoneConfig: IConfig
{
public long Id { get; set; }
public string DBConnection;
public string DBName;
}
}
......@@ -3,9 +3,14 @@ namespace ETModel
[Config]
public partial class UnitConfigCategory : ACategory<UnitConfig>
{
public static UnitConfigCategory Instance;
public UnitConfigCategory()
{
Instance = this;
}
}
public class UnitConfig: IConfig
public partial class UnitConfig: IConfig
{
public long Id { get; set; }
public string Name;
......
using System.ComponentModel;
namespace ETModel
{
public partial class StartProcessConfigCategory : ISupportInitialize
{
public void EndInit()
{
}
}
public partial class StartProcessConfig: ISupportInitialize
{
public string InnerAddress;
public void BeginInit()
{
}
public void EndInit()
{
this.InnerAddress = $"{this.InnerIP}:{this.InnerPort}";
}
}
}
using System.Collections.Generic;
using System.ComponentModel;
namespace ETModel
{
public partial class StartSceneConfigCategory: ISupportInitialize
{
public MultiMap<int, StartSceneConfig> Gates = new MultiMap<int, StartSceneConfig>();
public MultiMap<int, StartSceneConfig> ProcessScenes = new MultiMap<int, StartSceneConfig>();
public Dictionary<long, Dictionary<string, StartSceneConfig>> ZoneScenesByName = new Dictionary<long, Dictionary<string, StartSceneConfig>>();
public StartSceneConfig LocationConfig;
public List<StartSceneConfig> GetByProcess(int process)
{
return this.ProcessScenes[process];
}
public StartSceneConfig GetBySceneName(int zone, string name)
{
return this.ZoneScenesByName[zone][name];
}
public void EndInit()
{
foreach (StartSceneConfig startSceneConfig in this.GetAll().Values)
{
this.ProcessScenes.Add(startSceneConfig.Process, startSceneConfig);
if (!this.ZoneScenesByName.ContainsKey(startSceneConfig.Zone))
{
this.ZoneScenesByName.Add(startSceneConfig.Zone, new Dictionary<string, StartSceneConfig>());
}
this.ZoneScenesByName[startSceneConfig.Zone].Add(startSceneConfig.Name, startSceneConfig);
switch (startSceneConfig.Type)
{
case SceneType.Gate:
this.Gates.Add(startSceneConfig.Zone, startSceneConfig);
break;
case SceneType.Location:
this.LocationConfig = startSceneConfig;
break;
}
}
}
}
public partial class StartSceneConfig: ISupportInitialize
{
public long SceneId;
public SceneType Type;
public StartProcessConfig StartProcessConfig
{
get
{
return StartProcessConfigCategory.Instance.Get(this.Process);
}
}
public StartZoneConfig StartZoneConfig
{
get
{
return StartZoneConfigCategory.Instance.Get(this.Process);
}
}
private string outerAddress;
public string OuterAddress
{
get
{
if (this.outerAddress == null)
{
this.outerAddress = $"{this.StartProcessConfig.OuterIP}:{this.OuterPort}";
}
return this.outerAddress;
}
}
private string innerOuterAddress;
public string InnerOuterAddress
{
get
{
if (this.innerOuterAddress == null)
{
this.innerOuterAddress = $"{this.StartProcessConfig.InnerAddress}:{this.OuterPort}";
}
return this.innerOuterAddress;
}
}
public void BeginInit()
{
}
public void EndInit()
{
this.Type = EnumHelper.FromString<SceneType>(this.SceneType);
InstanceIdStruct instanceIdStruct = new InstanceIdStruct(this.Process, (uint) this.Id);
this.SceneId = instanceIdStruct.ToLong();
}
}
}
\ No newline at end of file
......@@ -19,15 +19,5 @@
{
this.Account = account;
}
public override void Dispose()
{
if (this.IsDisposed)
{
return;
}
base.Dispose();
}
}
}
\ No newline at end of file
namespace ETModel
{
public static class Game
{
public static Scene Scene { get; set; }
private static EventSystem eventSystem;
public static EventSystem EventSystem
{
get
{
return eventSystem ?? (eventSystem = new EventSystem());
}
}
private static ObjectPool objectPool;
public static ObjectPool ObjectPool
{
get
{
return objectPool ?? (objectPool = new ObjectPool());
}
}
public static Options Options;
public static void Close()
{
Scene.Dispose();
Scene = null;
objectPool = null;
eventSystem = null;
}
}
}
\ No newline at end of file
namespace ETModel
{
public sealed class Scene: Entity
{
public SceneType SceneType { get; set; }
public string Name { get; set; }
public Scene Get(long id)
{
return (Scene)this.Children[id];
}
public new Entity Domain
{
get
{
return this.domain;
}
set
{
this.domain = value;
}
}
public new Entity Parent
{
get
{
return this.parent;
}
set
{
this.parent = value;
this.parent.Children.Add(this.Id, this);
}
}
}
}
\ No newline at end of file
......@@ -8,6 +8,8 @@ namespace ETModel
/// </summary>
public class ConfigComponent: Entity
{
public static ConfigComponent Instance;
public Dictionary<Type, ACategory> AllConfig = new Dictionary<Type, ACategory>();
}
}
\ No newline at end of file
namespace ETModel
{
public class HttpResult
{
public int code;
public bool status;
public string msg = "";
[MongoDB.Bson.Serialization.Attributes.BsonIgnoreIfNull]
public object data;
}
public static class HttpErrorCode
{
public const int Exception = 999;
public const int Success = 1000;
public const int RpcFail = 1002;
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Reflection;
using System.Text;
namespace ETModel
{
[ObjectSystem]
public class HttpComponentComponentAwakeSystem : AwakeSystem<HttpComponent>
{
public override void Awake(HttpComponent self)
{
self.Awake();
}
}
[ObjectSystem]
public class HttpComponentComponentLoadSystem : LoadSystem<HttpComponent>
{
public override void Load(HttpComponent self)
{
self.Load();
}
}
[ObjectSystem]
public class HttpComponentComponentStartSystem : StartSystem<HttpComponent>
{
public override void Start(HttpComponent self)
{
self.Start();
}
}
/// <summary>
/// http请求分发器
/// </summary>
public class HttpComponent : Entity
{
public HttpListener listener;
public HttpConfig HttpConfig;
public Dictionary<string, IHttpHandler> dispatcher;
// 处理方法
private Dictionary<MethodInfo, IHttpHandler> handlersMapping;
// Get处理
private Dictionary<string, MethodInfo> getHandlers;
private Dictionary<string, MethodInfo> postHandlers;
public void Awake()
{
StartConfig startConfig = StartConfigComponent.Instance.StartConfig;
this.HttpConfig = startConfig.GetComponent<HttpConfig>();
this.Load();
}
public void Load()
{
this.dispatcher = new Dictionary<string, IHttpHandler>();
this.handlersMapping = new Dictionary<MethodInfo, IHttpHandler>();
this.getHandlers = new Dictionary<string, MethodInfo>();
this.postHandlers = new Dictionary<string, MethodInfo>();
HashSet<Type> types = Game.EventSystem.GetTypes(typeof(HttpHandlerAttribute));
foreach (Type type in types)
{
object[] attrs = type.GetCustomAttributes(typeof(HttpHandlerAttribute), false);
if (attrs.Length == 0)
{
continue;
}
HttpHandlerAttribute httpHandlerAttribute = (HttpHandlerAttribute)attrs[0];
object obj = Activator.CreateInstance(type);
IHttpHandler ihttpHandler = obj as IHttpHandler;
if (ihttpHandler == null)
{
throw new Exception($"HttpHandler handler not inherit IHttpHandler class: {obj.GetType().FullName}");
}
this.dispatcher.Add(httpHandlerAttribute.Path, ihttpHandler);
LoadMethod(type, httpHandlerAttribute, ihttpHandler);
}
}
public void Start()
{
try
{
this.listener = new HttpListener();
if (this.HttpConfig.Url == null)
{
this.HttpConfig.Url = "";
}
foreach (string s in this.HttpConfig.Url.Split(';'))
{
if (s.Trim() == "")
{
continue;
}
this.listener.Prefixes.Add(s);
}
this.listener.Start();
this.Accept().Coroutine();
}
catch (HttpListenerException e)
{
throw new Exception($"http server error: {e.ErrorCode}", e);
}
}
public void LoadMethod(Type type, HttpHandlerAttribute httpHandlerAttribute, IHttpHandler httpHandler)
{
// 扫描这个类里面的方法
MethodInfo[] methodInfos = type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.InvokeMethod | BindingFlags.Instance);
foreach (MethodInfo method in methodInfos)
{
object[] getAttrs = method.GetCustomAttributes(typeof(GetAttribute), false);
if (getAttrs.Length != 0)
{
GetAttribute get = (GetAttribute)getAttrs[0];
string path = method.Name;
if (!string.IsNullOrEmpty(get.Path))
{
path = get.Path;
}
getHandlers.Add(httpHandlerAttribute.Path + path, method);
//Log.Debug($"add handler[{httpHandler}.{method.Name}] path {httpHandlerAttribute.Path + path}");
}
object[] postAttrs = method.GetCustomAttributes(typeof(PostAttribute), false);
if (postAttrs.Length != 0)
{
// Post处理方法
PostAttribute post = (PostAttribute)postAttrs[0];
string path = method.Name;
if (!string.IsNullOrEmpty(post.Path))
{
path = post.Path;
}
postHandlers.Add(httpHandlerAttribute.Path + path, method);
//Log.Debug($"add handler[{httpHandler}.{method.Name}] path {httpHandlerAttribute.Path + path}");
}
if (getAttrs.Length == 0 && postAttrs.Length == 0)
{
continue;
}
handlersMapping.Add(method, httpHandler);
}
}
public async ETVoid Accept()
{
long instanceId = this.InstanceId;
while (true)
{
if (this.InstanceId != instanceId)
{
return;
}
HttpListenerContext context = await this.listener.GetContextAsync();
await InvokeHandler(context);
context.Response.Close();
}
}
/// <summary>
/// 调用处理方法
/// </summary>
/// <param name="context"></param>
private async ETTask InvokeHandler(HttpListenerContext context)
{
context.Response.StatusCode = 404;
MethodInfo methodInfo = null;
IHttpHandler httpHandler = null;
string postbody = "";
switch (context.Request.HttpMethod)
{
case "GET":
this.getHandlers.TryGetValue(context.Request.Url.AbsolutePath, out methodInfo);
if (methodInfo != null)
{
this.handlersMapping.TryGetValue(methodInfo, out httpHandler);
}
break;
case "POST":
this.postHandlers.TryGetValue(context.Request.Url.AbsolutePath, out methodInfo);
if (methodInfo != null)
{
this.handlersMapping.TryGetValue(methodInfo, out httpHandler);
using (StreamReader sr = new StreamReader(context.Request.InputStream))
{
postbody = sr.ReadToEnd();
}
}
break;
default:
context.Response.StatusCode = 405;
break;
}
if (httpHandler != null)
{
object[] args = InjectParameters(context, methodInfo, postbody);
// 自动把返回值,以json方式响应。
object resp = methodInfo.Invoke(httpHandler, args);
object result = resp;
if (resp is ETTask<HttpResult> t)
{
await t;
result = t.GetType().GetProperty("Result").GetValue(t, null);
}
if (result != null)
{
using (StreamWriter sw = new StreamWriter(context.Response.OutputStream,Encoding.UTF8))
{
if (result.GetType() == typeof(string))
{
sw.Write(result.ToString());
}
else
{
sw.Write(JsonHelper.ToJson(result));
}
}
}
}
}
/// <summary>
/// 注入参数
/// </summary>
/// <param name="context"></param>
/// <param name="methodInfo"></param>
/// <param name="postbody"></param>
/// <returns></returns>
private static object[] InjectParameters(HttpListenerContext context, MethodInfo methodInfo, string postbody)
{
context.Response.StatusCode = 200;
ParameterInfo[] parameterInfos = methodInfo.GetParameters();
object[] args = new object[parameterInfos.Length];
for (int i = 0; i < parameterInfos.Length; i++)
{
ParameterInfo item = parameterInfos[i];
if (item.ParameterType == typeof(HttpListenerRequest))
{
args[i] = context.Request;
continue;
}
if (item.ParameterType == typeof(HttpListenerResponse))
{
args[i] = context.Response;
continue;
}
try
{
switch (context.Request.HttpMethod)
{
case "POST":
if (item.Name == "postBody") // 约定参数名称为postBody,只传string类型。本来是byte[],有需求可以改。
{
args[i] = postbody;
}
else if (item.ParameterType.IsClass && item.ParameterType != typeof(string) && !string.IsNullOrEmpty(postbody))
{
object entity = JsonHelper.FromJson(item.ParameterType, postbody);
args[i] = entity;
}
break;
case "GET":
string query = context.Request.QueryString[item.Name];
if (query != null)
{
object value = Convert.ChangeType(query, item.ParameterType);
args[i] = value;
}
break;
default:
args[i] = null;
break;
}
}
catch (Exception e)
{
Log.Error(e);
args[i] = null;
}
}
return args;
}
public override void Dispose()
{
if (this.IsDisposed)
{
return;
}
base.Dispose();
this.listener.Stop();
this.listener.Close();
}
}
}
\ No newline at end of file
using System;
namespace ETModel
{
public class HttpHandlerAttribute : BaseAttribute
{
public AppType AppType { get; }
public string Path { get; }
public HttpHandlerAttribute(AppType appType, string path)
{
this.AppType = appType;
this.Path = path;
}
}
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)]
public class GetAttribute : Attribute
{
public string Path { get; }
public GetAttribute()
{
}
public GetAttribute(string path)
{
this.Path = path;
}
}
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)]
public class PostAttribute : Attribute
{
public string Path { get; }
public PostAttribute()
{
}
public PostAttribute(string path)
{
this.Path = path;
}
}
}
\ No newline at end of file
using System.Net;
namespace ETModel
{
public interface IHttpHandler
{
void Handle(HttpListenerContext context);
}
public abstract class AHttpHandler : IHttpHandler
{
public virtual void Handle(HttpListenerContext context)
{
}
public virtual HttpResult Ok(string msg = "", object data = null)
{
return new HttpResult
{
code = HttpErrorCode.Success,
msg = msg,
status = true,
data = data
};
}
public virtual HttpResult Error(string msg = "")
{
return new HttpResult
{
code = HttpErrorCode.Exception,
msg = msg,
status = false
};
}
}
}
\ No newline at end of file
#if SERVER
using CommandLine;
#endif
using CommandLine;
namespace ETModel
{
public class Options
public class Options: Entity
{
[Option("id", Required = false, Default = 1)]
public int Id { get; set; }
[Option("config", Required = false, Default = "AllServer.txt")]
public string Config { get; set; }
[Option("process", Required = false, Default = 1)]
public int Process { get; set; }
}
}
\ No newline at end of file
......@@ -134,17 +134,14 @@
<Compile Include="..\..\Unity\Assets\Model\Base\UnOrderMultiMapSet.cs">
<Link>Base\UnOrderMultiMapSet.cs</Link>
</Compile>
<Compile Include="..\..\Unity\Assets\Model\Component\Config\CopyConfig.cs">
<Link>Component\Config\CopyConfig.cs</Link>
<Compile Include="..\..\Unity\Assets\Model\Entity\EntitySceneFactory.cs">
<Link>Entity\EntitySceneFactory.cs</Link>
</Compile>
<Compile Include="..\..\Unity\Assets\Model\Component\Config\ProcessConfig.cs">
<Link>Component\Config\ProcessConfig.cs</Link>
<Compile Include="..\..\Unity\Assets\Model\Entity\Game.cs">
<Link>Entity\Game.cs</Link>
</Compile>
<Compile Include="..\..\Unity\Assets\Model\Component\Config\SceneConfig.cs">
<Link>Component\Config\SceneConfig.cs</Link>
</Compile>
<Compile Include="..\..\Unity\Assets\Model\Component\Config\StartConfig.cs">
<Link>Component\Config\StartConfig.cs</Link>
<Compile Include="..\..\Unity\Assets\Model\Entity\Scene.cs">
<Link>Entity\Scene.cs</Link>
</Compile>
<Compile Include="..\..\Unity\Assets\Model\Entity\SceneType.cs">
<Link>Entity\SceneType.cs</Link>
......@@ -218,11 +215,6 @@
<Compile Include="..\..\Unity\Assets\Model\Base\RecyclableMemoryStream\RecyclableMemoryStreamManager.cs" Link="Base\RecyclableMemoryStream\RecyclableMemoryStreamManager.cs" />
<Compile Include="..\..\Unity\Assets\Model\Base\TryLocker.cs" Link="Base\TryLocker.cs" />
<Compile Include="..\..\Unity\Assets\Model\Base\UnOrderMultiMap.cs" Link="Base\UnOrderMultiMap.cs" />
<Compile Include="..\..\Unity\Assets\Model\Component\Config\ClientConfig.cs" Link="Component\Config\ClientConfig.cs" />
<Compile Include="..\..\Unity\Assets\Model\Component\Config\DBConfig.cs" Link="Module\DB\DBConfig.cs" />
<Compile Include="..\..\Unity\Assets\Model\Component\Config\HttpConfig.cs" Link="Module\Http\HttpConfig.cs" />
<Compile Include="..\..\Unity\Assets\Model\Component\Config\InnerConfig.cs" Link="Module\Message\InnerConfig.cs" />
<Compile Include="..\..\Unity\Assets\Model\Component\Config\OuterConfig.cs" Link="Module\Message\OuterConfig.cs" />
<Compile Include="..\..\Unity\Assets\Model\Component\TimerComponent.cs" Link="Component\TimerComponent.cs" />
<Compile Include="..\..\Unity\Assets\Model\Module\Config\ACategory.cs" Link="Module\Config\ACategory.cs" />
<Compile Include="..\..\Unity\Assets\Model\Module\Config\ConfigAttribute.cs" Link="Module\Config\ConfigAttribute.cs" />
......@@ -410,7 +402,6 @@
</ItemGroup>
<ItemGroup>
<Folder Include="Base\RecyclableMemoryStream\" />
<Folder Include="Component\Config\" />
<Folder Include="Module\Message\Network\KCP\" />
<Folder Include="Module\Message\Network\TCP\" />
<Folder Include="Module\Message\MessagePool\" />
......
{"_id":1,"InnerIP":"127.0.0.1","InnerPort":"20001","OuterIP":"127.0.0.1"}
{"_id":2,"InnerIP":"127.0.0.2","InnerPort":"20002","OuterIP":"127.0.0.2"}
fileFormatVersion: 2
guid: 7ab151f52cd2d474fbcbbfd59355fbb9
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
{"_id":1,"Process":1,"Zone":1,"SceneType":"Realm","Name":"Realm","OuterPort":10002}
{"_id":2,"Process":1,"Zone":1,"SceneType":"Gate","Name":"Gate1","OuterPort":10003}
{"_id":3,"Process":1,"Zone":1,"SceneType":"Gate","Name":"Gate2","OuterPort":10004}
{"_id":4,"Process":1,"Zone":1,"SceneType":"Location","Name":"Location"}
{"_id":5,"Process":1,"Zone":1,"SceneType":"Map","Name":"Map"}
fileFormatVersion: 2
guid: 656280210d67e1a4981e2300efa9177b
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
{"_id":1,"DBConnection":"mongdb://127.0.0.1","DBName":"ET1"}
{"_id":2,"DBConnection":"mongdb://127.0.0.1","DBName":"ET2"}
fileFormatVersion: 2
guid: e8584de077a43b4489271bfda6e979c2
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
using System;
using System.IO;
using ETModel;
using UnityEditor;
namespace ETEditor
{
[InitializeOnLoad]
public class Startup
{
private const string ScriptAssembliesDir = "Library/ScriptAssemblies";
private const string CodeDir = "Assets/Res/Code/";
private const string HotfixDll = "Unity.Hotfix.dll";
private const string HotfixPdb = "Unity.Hotfix.pdb";
static Startup()
{
File.Copy(Path.Combine(ScriptAssembliesDir, HotfixDll), Path.Combine(CodeDir, "Hotfix.dll.bytes"), true);
File.Copy(Path.Combine(ScriptAssembliesDir, HotfixPdb), Path.Combine(CodeDir, "Hotfix.pdb.bytes"), true);
Log.Info($"复制Hotfix.dll, Hotfix.pdb到Res/Code完成");
AssetDatabase.Refresh ();
}
}
}
\ No newline at end of file
......@@ -61,8 +61,7 @@ public class ExcelExporterEditor : EditorWindow
ExportAll(clientPath);
ExportAllClass(@"./Assets/Model/Module/Demo/Config", "namespace ETModel\n{\n");
ExportAllClass(@"./Assets/Hotfix/Module/Demo/Config", "using ETModel;\n\nnamespace ETHotfix\n{\n");
ExportAllClass(@"./Assets/Model/Demo/Config", "namespace ETModel\n{\n");
Log.Info($"导出客户端配置完成!");
}
......@@ -73,7 +72,7 @@ public class ExcelExporterEditor : EditorWindow
ExportAll(ServerConfigPath);
ExportAllClass(@"../Server/Model/Module/Demo/Config", "namespace ETModel\n{\n");
ExportAllClass(@"../Server/Model/Demo/Config", "namespace ETModel\n{\n");
Log.Info($"导出服务端配置完成!");
}
......@@ -124,9 +123,14 @@ public class ExcelExporterEditor : EditorWindow
sb.Append($"\t[Config]\n");
sb.Append($"\tpublic partial class {protoName}Category : ACategory<{protoName}>\n");
sb.Append("\t{\n");
sb.Append($"\t\tpublic static {protoName}Category Instance;\n");
sb.Append($"\t\tpublic {protoName}Category()\n");
sb.Append("\t\t{\n");
sb.Append($"\t\t\tInstance = this;\n");
sb.Append("\t\t}\n");
sb.Append("\t}\n\n");
sb.Append($"\tpublic class {protoName}: IConfig\n");
sb.Append($"\tpublic partial class {protoName}: IConfig\n");
sb.Append("\t{\n");
sb.Append("\t\tpublic long Id { get; set; }\n");
......@@ -279,7 +283,7 @@ public class ExcelExporterEditor : EditorWindow
string fieldValue = GetCellString(row, j);
if (fieldValue == "")
{
throw new Exception($"sheet: {sheet.SheetName} 中有空白字段 {i},{j}");
continue;
}
if (j > 2)
......
......@@ -8,462 +8,22 @@ using UnityEngine;
namespace ETModel
{
enum StartConfigComponentType
{
ClientConfig,
DBConfig,
SceneConfig,
HttpConfig,
InnerConfig,
OuterConfig,
ProcessConfig,
CopyConfig,
MapConfig,
}
[ObjectSystem]
class StartConfigDrawerAwakeSystem : AwakeSystem<StartConfigDrawer, int>
{
public override void Awake(StartConfigDrawer self, int level)
{
StartConfig startConfig = self.GetParent<StartConfig>();
foreach (var childStartConfig in startConfig.List)
{
childStartConfig.AddComponentNoPool<StartConfigDrawer, int>(level + 1);
}
self.level = level;
}
}
#if !SERVER
[HideInHierarchy]
#endif
[NoObjectPool]
public class StartConfigDrawer: Entity
{
public GUIStyle style = new GUIStyle();
public int level;
public bool isFold = true;
private StartConfigComponentType st;
public StartConfigDrawer()
{
this.Id = IdGenerater.GenerateId();
this.style.normal.textColor = Color.red;
this.style.alignment = TextAnchor.MiddleLeft;
this.style.fixedHeight = 16;
}
public bool OnGUI()
{
StartConfig startConfig = this.GetParent<StartConfig>();
GUILayout.BeginHorizontal(GUILayout.Height(16));
if (this.level > 0)
{
string s = "";
for (int i = 1; i < this.level; ++i)
{
s += $" ";
}
GUILayout.Label(s, GUILayout.Width(20 * this.level));
}
{
GUILayout.BeginHorizontal(GUILayout.Width(240), GUILayout.Height(16));
this.isFold = EditorGUILayout.Foldout(isFold, $"子配置数量:{startConfig.List.Count}");
if (GUILayout.Button("添加子配置", GUILayout.Height(16), GUILayout.Width(75)))
{
StartConfig s = new StartConfig();
startConfig.Add(s);
s.AddComponentNoPool<StartConfigDrawer, int>(this.level + 1);
for (int i = 0; i < startConfig.List.Count; ++i)
{
startConfig.List[i].Id = i + 1;
}
this.isFold = true;
return false;
}
if (GUILayout.Button("上", GUILayout.Height(16), GUILayout.Width(30)))
{
StartConfig parentStartConfig = startConfig.GetParent<StartConfig>();
int index = parentStartConfig.List.IndexOf(startConfig);
if (index == 0)
{
return true;
}
parentStartConfig.List.Remove(startConfig);
parentStartConfig.List.Insert(index - 1, startConfig);
for (int i = 0; i < parentStartConfig.List.Count; ++i)
{
parentStartConfig.List[i].Id = i + 1;
}
return false;
}
if (GUILayout.Button("下", GUILayout.Height(16), GUILayout.Width(30)))
{
StartConfig parentStartConfig = startConfig.GetParent<StartConfig>();
int index = parentStartConfig.List.IndexOf(startConfig);
if (index == parentStartConfig.List.Count - 1)
{
return true;
}
parentStartConfig.List.Remove(startConfig);
parentStartConfig.List.Insert(index + 1, startConfig);
for (int i = 0; i < parentStartConfig.List.Count; ++i)
{
parentStartConfig.List[i].Id = i + 1;
}
return false;
}
GUILayout.EndHorizontal();
}
{
GUILayout.BeginHorizontal(GUILayout.Width(50));
GUILayout.Label($"Id: ");
startConfig.Id = EditorGUILayout.LongField(startConfig.Id, GUILayout.Width(30));
GUILayout.EndHorizontal();
}
{
GUILayout.BeginHorizontal(GUILayout.Width(200));
ProcessConfig processConfig = startConfig.GetComponent<ProcessConfig>();
if (processConfig != null)
{
GUILayout.Label($" ProcessConfig(", this.style);
GUILayout.Label($"服务器IP: ");
processConfig.ServerIP = EditorGUILayout.TextField(processConfig.ServerIP, GUILayout.Width(100));
GUILayout.Label($"),", this.style);
}
GUILayout.EndHorizontal();
}
{
GUILayout.BeginHorizontal(GUILayout.Width(200));
SceneConfig sceneConfig = startConfig.GetComponent<SceneConfig>();
if (sceneConfig != null)
{
GUILayout.Label($" SceneConfig(", this.style);
GUILayout.Label($"SceneType: ");
sceneConfig.SceneType = (SceneType)EditorGUILayout.EnumPopup(sceneConfig.SceneType, GUILayout.Width(100));
GUILayout.Label($"Name: ");
sceneConfig.Name = EditorGUILayout.TextField(sceneConfig.Name, GUILayout.Width(100));
GUILayout.Label($"),", this.style);
}
GUILayout.EndHorizontal();
}
{
GUILayout.BeginHorizontal(GUILayout.Width(150));
InnerConfig innerConfig = startConfig.GetComponent<InnerConfig>();
if (innerConfig != null)
{
GUILayout.Label($" InnerConfig(", this.style);
GUILayout.Label($"内网地址:");
innerConfig.Address = EditorGUILayout.TextField(innerConfig.Address, GUILayout.Width(120));
GUILayout.Label($"),", this.style);
}
GUILayout.EndHorizontal();
}
{
GUILayout.BeginHorizontal(GUILayout.Width(350));
OuterConfig outerConfig = startConfig.GetComponent<OuterConfig>();
if (outerConfig != null)
{
GUILayout.Label($" OuterConfig(", this.style);
GUILayout.Label($"外网地址:");
outerConfig.Address = EditorGUILayout.TextField(outerConfig.Address, GUILayout.Width(120));
GUILayout.Label($"外网地址2:");
outerConfig.Address2 = EditorGUILayout.TextField(outerConfig.Address2, GUILayout.Width(120));
GUILayout.Label($"),", this.style);
}
GUILayout.EndHorizontal();
}
{
GUILayout.BeginHorizontal(GUILayout.Width(50));
CopyConfig copyConfig = startConfig.GetComponent<CopyConfig>();
if (copyConfig != null)
{
GUILayout.Label($" CopyConfig(", this.style);
GUILayout.Label($"),", this.style);
}
GUILayout.EndHorizontal();
public class ServerCommandLineEditor: EditorWindow
{
public void OnGUI()
{
if (GUILayout.Button("启动"))
{
string arguments = $"";
ProcessHelper.Run("App.exe", arguments, "../Bin/");
}
{
GUILayout.BeginHorizontal(GUILayout.Width(50));
MapConfig mapConfig = startConfig.GetComponent<MapConfig>();
if (mapConfig != null)
{
GUILayout.Label($" MapConfig(", this.style);
GUILayout.Label($"MapType: ");
mapConfig.MapType = (MapType)EditorGUILayout.EnumPopup(mapConfig.MapType, GUILayout.Width(100));
GUILayout.Label($"),", this.style);
}
GUILayout.EndHorizontal();
}
{
GUILayout.BeginHorizontal(GUILayout.Width(350));
ClientConfig clientConfig = startConfig.GetComponent<ClientConfig>();
if (clientConfig != null)
{
GUILayout.Label($" ClientConfig(", this.style);
GUILayout.Label($"连接地址:");
clientConfig.Address = EditorGUILayout.TextField(clientConfig.Address, GUILayout.Width(120));
GUILayout.Label($"),", this.style);
}
DBConfig dbConfig = startConfig.GetComponent<DBConfig>();
if (dbConfig != null)
{
GUILayout.Label($" DBConfig(", this.style);
GUILayout.Label($"连接串:");
dbConfig.ConnectionString = EditorGUILayout.TextField(dbConfig.ConnectionString);
GUILayout.Label($"DBName:");
dbConfig.DBName = EditorGUILayout.TextField(dbConfig.DBName);
GUILayout.Label($"),", this.style);
}
GUILayout.EndHorizontal();
}
{
GUILayout.BeginHorizontal(GUILayout.Width(200), GUILayout.Height(16));
this.st = (StartConfigComponentType) EditorGUILayout.EnumPopup(this.st, GUILayout.Width(100));
if (GUILayout.Button("添加组件", GUILayout.Height(16)))
{
Assembly assembly = Assembly.GetAssembly(typeof(Init));
Type type = assembly.GetType($"ETModel.{this.st.ToString()}");
startConfig.AddComponent(type);
}
if (GUILayout.Button("删除组件", GUILayout.Height(16)))
{
Assembly assembly = Assembly.GetAssembly(typeof(Init));
Type type = assembly.GetType($"ETModel.{this.st.ToString()}");
startConfig.RemoveComponent(type);
}
if (GUILayout.Button("删除该行配置", GUILayout.Height(16)))
{
startConfig.GetParent<StartConfig>().Remove(startConfig);
return false;
}
GUILayout.EndHorizontal();
}
GUILayout.EndHorizontal();
if (this.isFold)
{
foreach (StartConfig child in startConfig.List)
{
if (child.GetComponent<StartConfigDrawer>()?.OnGUI() == false)
{
return false;
}
}
}
return true;
}
}
public class ServerCommandLineEditor: EditorWindow
{
private const string ConfigDir = @"../Config/StartConfig/";
private List<string> files;
private int selectedIndex;
private string fileName;
private string newFileName = "";
private StartConfig startConfig;
[MenuItem("Tools/命令行配置")]
private static void ShowWindow()
{
Game.EventSystem.Add(DLLType.Editor, typeof(ServerCommandLineEditor).Assembly);
GetWindow(typeof (ServerCommandLineEditor));
}
private void OnEnable()
{
Game.EventSystem.Add(DLLType.Editor, typeof(ServerCommandLineEditor).Assembly);
this.files = this.GetConfigFiles();
if (this.files.Count > 0)
{
this.fileName = this.files[this.selectedIndex];
this.LoadConfig();
}
}
public void ClearConfig()
{
startConfig?.Dispose();
}
private List<string> GetConfigFiles()
{
List<string> fs = Directory.GetFiles(ConfigDir).ToList();
DirectoryInfo directoryInfo = new DirectoryInfo(ConfigDir);
FileInfo[] fileInfo = directoryInfo.GetFiles();
fs = fileInfo.Select(x => x.Name).ToList();
return fs;
}
private void LoadConfig()
{
string filePath = this.GetFilePath();
if (!File.Exists(filePath))
{
return;
}
string s2 = "";
try
{
this.ClearConfig();
startConfig = MongoHelper.FromJson<StartConfig>(File.ReadAllText(filePath));
this.startConfig.AddComponentNoPool<StartConfigDrawer, int>(0);
}
catch (Exception e)
{
Log.Error($"加载配置失败! {s2} \n {e}");
}
}
private string GetFilePath()
{
return Path.Combine(ConfigDir, this.fileName);
}
private void Save()
{
string path = this.GetFilePath();
File.WriteAllText(path, MongoHelper.ToJson(startConfig));
}
private Vector2 scrollPos;
private void OnGUI()
{
{
GUILayout.BeginHorizontal();
string[] filesArray = this.files.ToArray();
this.selectedIndex = EditorGUILayout.Popup(this.selectedIndex, filesArray);
string lastFile = this.fileName;
this.fileName = this.files[this.selectedIndex];
if (this.fileName != lastFile)
{
this.LoadConfig();
}
this.newFileName = EditorGUILayout.TextField("文件名", this.newFileName);
if (GUILayout.Button("添加"))
{
this.ClearConfig();
this.startConfig = new StartConfig();
startConfig.AddComponent<StartConfigDrawer>();
this.fileName = this.newFileName;
this.newFileName = "";
File.WriteAllText(this.GetFilePath(), MongoHelper.ToJson(this.startConfig));
this.files = this.GetConfigFiles();
this.selectedIndex = this.files.IndexOf(this.fileName);
this.LoadConfig();
}
if (GUILayout.Button("复制"))
{
this.fileName = $"{this.fileName}-copy";
this.Save();
this.files = this.GetConfigFiles();
this.selectedIndex = this.files.IndexOf(this.fileName);
this.newFileName = "";
}
if (GUILayout.Button("重命名"))
{
if (this.newFileName == "")
{
Log.Debug("请输入新名字!");
}
else
{
File.Delete(this.GetFilePath());
this.fileName = this.newFileName;
this.Save();
this.files = this.GetConfigFiles();
this.selectedIndex = this.files.IndexOf(this.fileName);
this.newFileName = "";
}
}
if (GUILayout.Button("删除"))
{
File.Delete(this.GetFilePath());
this.files = this.GetConfigFiles();
this.selectedIndex = 0;
this.newFileName = "";
}
if (GUILayout.Button("启动数据库"))
{
ProcessHelper.Run("mongod", @"--dbpath=db", "../Database/bin/");
}
GUILayout.EndHorizontal();
}
scrollPos = GUILayout.BeginScrollView(this.scrollPos, true, true);
startConfig.GetComponent<StartConfigDrawer>()?.OnGUI();
GUILayout.EndScrollView();
GUILayout.BeginHorizontal();
if (GUILayout.Button("保存"))
{
this.Save();
}
if (GUILayout.Button("启动"))
{
string arguments = $"--config={this.fileName}";
ProcessHelper.Run("App.exe", arguments, "../Bin/");
}
if (GUILayout.Button("启动数据库"))
{
ProcessHelper.Run("mongod", @"--dbpath=db", "../Database/bin/");
}
GUILayout.EndHorizontal();
}
private void OnDestroy()
{
this.ClearConfig();
}
}
GUILayout.EndHorizontal();
}
}
}
\ No newline at end of file
fileFormatVersion: 2
guid: 74f3c0d89734b0442bd2fd678368dccf
guid: bd9b82894424a2742a30f53d7c8d787e
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName: code.unity3d
assetBundleName:
assetBundleVariant:
using System;
using System.Collections.Generic;
using ETModel;
namespace ETHotfix
{
[ObjectSystem]
public class ConfigAwakeSystem : AwakeSystem<ConfigComponent>
{
public override void Awake(ConfigComponent self)
{
ConfigComponent.Instance = self;
self.Awake();
}
}
[ObjectSystem]
public class ConfigLoadSystem : LoadSystem<ConfigComponent>
{
public override void Load(ConfigComponent self)
{
self.Load();
}
}
[ObjectSystem]
public class ConfigDestroySystem : DestroySystem<ConfigComponent>
{
public override void Destroy(ConfigComponent self)
{
ConfigComponent.Instance = null;
}
}
public static class ConfigComponentSystem
{
public static void Awake(this ConfigComponent self)
{
self.Load();
}
public static void Load(this ConfigComponent self)
{
self.AllConfig.Clear();
HashSet<Type> types = Game.EventSystem.GetTypes(typeof(ConfigAttribute));
foreach (Type type in types)
{
object obj = Activator.CreateInstance(type);
ACategory iCategory = obj as ACategory;
if (iCategory == null)
{
throw new Exception($"class: {type.Name} not inherit from ACategory");
}
iCategory.BeginInit();
iCategory.EndInit();
self.AllConfig[iCategory.ConfigType] = iCategory;
}
}
}
}
\ No newline at end of file
fileFormatVersion: 2
guid: c2f4424953aa07a4a8045688edac22ac
guid: a0358a06fc42a94479b98404125c357a
MonoImporter:
externalObjects: {}
serializedVersion: 2
......
namespace ETModel
using System.Runtime.InteropServices;
namespace ETModel
{
public static class IdGenerater
{
public const int HeadPos = 50;
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct IdStruct
{
public uint Time; // 30bit
public ushort Value; // 16bit
public int Process; // 18bit
private static long appId;
public static long Head { get; private set; }
public static long AppId
{
set
{
appId = value;
Head = value << HeadPos;
}
get
{
return appId;
}
}
public static long HeadMask = 0x0003ffffffffffff;
public long ToLong()
{
ulong result = 0;
result |= (uint)this.Process;
result |= (ulong)this.Value << 18;
result |= (ulong)this.Time << 34;
return (long)result;
}
public IdStruct(int process, uint time, ushort value)
{
this.Process = process;
this.Time = time;
this.Value = value;
}
public IdStruct(long id)
{
ulong result = (ulong) id;
this.Process = (int)(result & 0x03ffff);
result >>= 18;
this.Value = (ushort)(result & (ushort.MaxValue));
result >>= 16;
this.Time = (uint)result;
}
private static ushort value;
public override string ToString()
{
return $"process: {this.Process}, time: {this.Time}, value: {this.Value}";
}
}
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct InstanceIdStruct
{
public ulong Value; // 46bit
public int Process; // 18bit
public long ToLong()
{
ulong result = 0;
result |= (uint)this.Process;
result |= this.Value << 18;
return (long)result;
}
public InstanceIdStruct(long id)
{
ulong result = (ulong) id;
this.Process = (int)(result & 0x03ffff);
result >>= 18;
this.Value = result;
}
public InstanceIdStruct(int process, ulong value)
{
this.Process = process;
this.Value = value;
}
private static int sceneId = 100000;
public override string ToString()
{
return $"process: {this.Process}, value: {this.Value}";
}
}
public static class IdGenerater
{
public const int MaxZone = 1024;
private static int process;
private static uint value;
public static int Process
{
set
{
process = value;
}
get
{
return process;
}
}
public static long GenerateSceneId()
{
return ++sceneId;
}
public static int GetProcess(long v)
{
return new IdStruct(v).Process;
}
public static long GenerateSceneInstanceId(long id)
{
return IdGenerater.Head + id;
}
// 一个区顶多1000个配置scene
private static ulong MaxConfigSceneId = 1024 * 1000;
// Scene的InstanceId跟Id一样
public static long GenerateProcessSceneId()
{
InstanceIdStruct instanceIdStruct = new InstanceIdStruct(process, 0);
return instanceIdStruct.ToLong();
}
public static long GenerateId()
{
long time = TimeHelper.ClientNowSeconds();
public static long lastTime;
public static long GenerateInstanceId()
{
InstanceIdStruct instanceIdStruct = new InstanceIdStruct(process, ++MaxConfigSceneId);
return instanceIdStruct.ToLong();
}
public static long GenerateId()
{
long time = TimeHelper.ClientNowSeconds();
if (time != lastTime)
{
value = 0;
lastTime = time;
}
if (++value > ushort.MaxValue - 1)
{
Log.Error($"id is not enough! value: {value}");
}
return Head + (time << 18) + ++value;
}
if (time > int.MaxValue)
{
Log.Error($"time > int.MaxValue value: {time}");
}
public static int GetProcessId(long v)
{
return (int)(v >> HeadPos);
}
}
IdStruct idStruct = new IdStruct(process, (uint)time, (ushort)value);
return idStruct.ToLong();
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
#if !SERVER
using UnityEngine;
......@@ -11,12 +12,13 @@ namespace ETModel
public enum EntityStatus: byte
{
None = 0,
IsFromPool = 0x01,
IsRegister = 0x02,
IsComponent = 0x04
IsFromPool = 1,
IsRegister = 1 << 1,
IsComponent = 1 << 2,
IsCreate = 1 << 3,
}
public partial class Entity : Object, IDisposable
public partial class Entity : Object
{
private static readonly Pool<HashSet<Entity>> hashSetPool = new Pool<HashSet<Entity>>();
......@@ -27,13 +29,10 @@ namespace ETModel
[BsonIgnore]
public long InstanceId { get; set; }
#if !SERVER
public static GameObject Global { get; } = GameObject.Find("/Global");
[BsonIgnore]
public GameObject ViewGO { get; set; }
#endif
protected Entity()
{
}
[BsonIgnore]
private EntityStatus status = EntityStatus.None;
......@@ -55,18 +54,11 @@ namespace ETModel
{
this.status &= ~EntityStatus.IsFromPool;
}
if (this.InstanceId == 0)
{
this.InstanceId = IdGenerater.GenerateId();
}
this.IsRegister = value;
}
}
[BsonIgnore]
private bool IsRegister
public bool IsRegister
{
get
{
......@@ -86,7 +78,8 @@ namespace ETModel
{
this.status &= ~EntityStatus.IsRegister;
}
Game.EventSystem.RegisterSystem(this, value);
EventSystem.Instance.RegisterSystem(this, value);
}
}
......@@ -109,6 +102,26 @@ namespace ETModel
}
}
}
[BsonIgnore]
public bool IsCreate
{
get
{
return (this.status & EntityStatus.IsCreate) == EntityStatus.IsCreate;
}
set
{
if (value)
{
this.status |= EntityStatus.IsCreate;
}
else
{
this.status &= ~EntityStatus.IsCreate;
}
}
}
[BsonIgnore]
public bool IsDisposed
......@@ -172,7 +185,7 @@ namespace ETModel
{
if (this.parent != null)
{
throw new Exception($"Component parent is null: {this.GetType().Name}");
throw new Exception($"Component parent is not null: {this.GetType().Name}");
}
this.parent = value;
......@@ -185,17 +198,9 @@ namespace ETModel
private void AfterSetParent()
{
if (this.parent.domain != null)
{
this.Domain = this.parent.domain;
}
this.Domain = this.parent.domain;
// 检测自己的domain是不是跟父亲一样
if (this.Domain != null && this.parent.Domain != null && this.Domain.InstanceId != this.parent.Domain.InstanceId && !(this is Scene))
{
Log.Error($"自己的domain跟parent不一样: {this.GetType().Name}");
}
#if !SERVER
#if UNITY_EDITOR
if (this.ViewGO != null && this.parent.ViewGO != null)
{
this.ViewGO.transform.SetParent(this.parent.ViewGO.transform, false);
......@@ -210,7 +215,7 @@ namespace ETModel
public override string ToString()
{
return MongoHelper.ToJson(this);
return this.ToJson();
}
......@@ -240,13 +245,40 @@ namespace ETModel
Entity preDomain = this.domain;
this.domain = value;
if (!(this.domain is Scene))
//if (!(this.domain is Scene))
//{
// throw new Exception($"domain is not scene: {this.GetType().Name}");
//}
if (preDomain == null)
{
throw new Exception($"domain is not scene: {this.GetType().Name}");
this.InstanceId = IdGenerater.GenerateInstanceId();
// 反序列化出来的需要设置父子关系
if (!this.IsCreate)
{
if (this.componentsDB != null)
{
foreach (Entity component in this.componentsDB)
{
component.IsComponent = true;
this.Components.Add(component.GetType(), component);
component.parent = this;
}
}
if (this.childrenDB != null)
{
foreach (Entity child in this.childrenDB)
{
child.IsComponent = false;
this.Children.Add(child.Id, child);
child.parent = this;
}
}
}
}
this.domain = value;
// 是否注册跟parent一致
if (this.parent != null)
{
......@@ -270,41 +302,36 @@ namespace ETModel
}
}
if (preDomain == null && !this.IsFromPool)
if (preDomain == null && !this.IsCreate)
{
Game.EventSystem.Deserialize(this);
EventSystem.Instance.Deserialize(this);
}
}
}
[BsonElement("Children")]
[BsonIgnoreIfNull]
private HashSet<Entity> childrenDB;
protected HashSet<Entity> childrenDB;
[BsonIgnore]
private Dictionary<long, Entity> children;
protected Dictionary<long, Entity> children;
[BsonIgnore]
public Dictionary<long, Entity> Children
{
get
{
if (this.children == null)
{
this.children = childrenPool.Fetch();
}
return this.children;
return this.children ?? (this.children = childrenPool.Fetch());
}
}
private void AddChild(Entity entity)
public void AddChild(Entity entity)
{
this.Children.Add(entity.Id, entity);
this.AddChildDB(entity);
}
private void RemoveChild(Entity entity)
public void RemoveChild(Entity entity)
{
if (this.children == null)
{
......@@ -334,7 +361,7 @@ namespace ETModel
this.childrenDB.Add(entity);
}
private void RemoveChildDB(Entity entity)
public void RemoveChildDB(Entity entity)
{
if (!(entity is ISerializeToEntity))
{
......@@ -358,6 +385,12 @@ namespace ETModel
}
}
public void RemoveAllChild()
{
this.children.Clear();
this.childrenDB.Clear();
}
[BsonElement("C")]
[BsonIgnoreIfNull]
private HashSet<Entity> componentsDB;
......@@ -370,56 +403,56 @@ namespace ETModel
{
get
{
return this.components;
return this.components ?? (this.components = dictPool.Fetch());
}
}
protected Entity()
{
this.InstanceId = IdGenerater.GenerateId();
#if !SERVER
if (!this.GetType().IsDefined(typeof (HideInHierarchy), true))
{
this.ViewGO = new GameObject();
this.ViewGO.name = this.GetType().Name;
this.ViewGO.layer = LayerNames.GetLayerInt(LayerNames.HIDDEN);
this.ViewGO.transform.SetParent(Global.transform, false);
this.ViewGO.AddComponent<ComponentView>().Component = this;
}
#endif
}
public virtual void Dispose()
public override void Dispose()
{
if (this.IsDisposed)
{
return;
}
long instanceId = this.InstanceId;
EventSystem.Instance.Remove(this.InstanceId);
this.InstanceId = 0;
Game.EventSystem.Remove(instanceId);
// 触发Destroy事件
Game.EventSystem.Destroy(this);
this.domain = null;
// 清理Component
if (this.components != null)
{
foreach (var kv in this.components)
{
kv.Value.Dispose();
}
this.components.Clear();
dictPool.Recycle(this.components);
this.components = null;
// 从池中创建的才需要回到池中,从db中不需要回收
if (this.componentsDB != null)
{
this.componentsDB.Clear();
if (this.IsFromPool)
{
hashSetPool.Recycle(this.componentsDB);
this.componentsDB = null;
}
}
}
// 清理Children
if (this.children != null)
{
var deletes = this.children;
this.children = null;
foreach (Entity child in deletes.Values)
foreach (Entity child in this.children.Values)
{
child.Dispose();
}
deletes.Clear();
childrenPool.Recycle(deletes);
this.children.Clear();
childrenPool.Recycle(this.children);
this.children = null;
if (this.childrenDB != null)
{
......@@ -432,91 +465,38 @@ namespace ETModel
}
}
}
// 触发Destroy事件
EventSystem.Instance.Destroy(this);
this.domain = null;
// 清理Component
if (this.components != null)
if (this.parent != null && !this.parent.IsDisposed)
{
var deletes = this.components;
this.components = null;
foreach (var kv in deletes)
if (this.IsComponent)
{
kv.Value.Dispose();
this.parent.RemoveComponent(this);
}
deletes.Clear();
dictPool.Recycle(deletes);
// 从池中创建的才需要回到池中,从db中不需要回收
if (this.componentsDB != null)
else
{
this.componentsDB.Clear();
if (this.IsFromPool)
{
hashSetPool.Recycle(this.componentsDB);
this.componentsDB = null;
}
this.parent.RemoveChild(this);
}
}
if (this.IsComponent)
{
this.parent?.RemoveComponent(this);
}
else
{
this.parent?.RemoveChild(this);
}
this.parent = null;
if (this.IsFromPool)
{
Game.ObjectPool.Recycle(this);
ObjectPool.Instance.Recycle(this);
}
else
{
#if !SERVER
if (this.ViewGO != null)
{
UnityEngine.Object.Destroy(this.ViewGO);
}
#endif
base.Dispose();
}
status = EntityStatus.None;
}
public override void EndInit()
{
try
{
if (this.childrenDB != null)
{
foreach (Entity child in this.childrenDB)
{
child.IsComponent = false;
this.AddChild(child);
child.parent = this;
}
}
if (this.componentsDB != null)
{
foreach (Entity component in this.componentsDB)
{
component.IsComponent = true;
this.AddToComponent(component.GetType(), component);
component.parent = this;
}
}
}
catch (Exception e)
{
Log.Error(e);
}
}
private void AddToComponentsDB(Entity component)
{
if (this.componentsDB == null)
......
using System;
using System;
namespace ETModel
{
public partial class Entity
{
private Entity CreateWithComponentParent(Type type)
{
Entity component;
if (type.IsDefined(typeof (NoObjectPool), false))
{
component = (Entity)Activator.CreateInstance(type);
}
else
{
component = Game.ObjectPool.Fetch(type);
}
public partial class Entity
{
public static Entity Create(Type type, bool isFromPool)
{
Entity component;
if (isFromPool)
{
component = (Entity)ObjectPool.Instance.Fetch(type);
}
else
{
component = (Entity)Activator.CreateInstance(type);
}
component.IsFromPool = isFromPool;
component.IsCreate = true;
component.Id = 0;
return component;
}
private Entity CreateWithComponentParent(Type type, bool isFromPool = true)
{
Entity component = Create(type, isFromPool);
this.Domain = parent.Domain;
component.Id = parent.Id;
component.ComponentParent = parent;
component.Id = parent.Id;
component.ComponentParent = parent;
Game.EventSystem.Awake(component);
return component;
}
EventSystem.Instance.Awake(component);
return component;
}
private T CreateWithComponentParent<T>(bool isFromPool = true) where T : Entity
{
Type type = typeof (T);
Entity component;
if (!isFromPool)
{
component = (Entity)Activator.CreateInstance(type);
}
else
{
component = Game.ObjectPool.Fetch(type);
}
component.Domain = this.Domain;
component.Id = this.Id;
component.ComponentParent = this;
private T CreateWithComponentParent<T>(bool isFromPool = true) where T : Entity
{
Type type = typeof (T);
Entity component = Create(type, isFromPool);
Game.EventSystem.Awake(component);
return (T)component;
}
component.Id = this.Id;
component.ComponentParent = this;
EventSystem.Instance.Awake(component);
return (T)component;
}
private T CreateWithComponentParent<T, A>(A a, bool isFromPool = true) where T : Entity
{
Type type = typeof (T);
Entity component;
if (!isFromPool)
{
component = (Entity)Activator.CreateInstance(type);
}
else
{
component = Game.ObjectPool.Fetch(type);
}
component.Domain = this.Domain;
component.Id = this.Id;
component.ComponentParent = this;
private T CreateWithComponentParent<T, A>(A a, bool isFromPool = true) where T : Entity
{
Type type = typeof (T);
Entity component = Create(type, isFromPool);
component.Id = this.Id;
component.ComponentParent = this;
Game.EventSystem.Awake(component, a);
return (T)component;
}
EventSystem.Instance.Awake(component, a);
return (T)component;
}
private T CreateWithComponentParent<T, A, B>(A a, B b, bool isFromPool = true) where T : Entity
{
Type type = typeof (T);
Entity component;
if (!isFromPool)
{
component = (Entity)Activator.CreateInstance(type);
}
else
{
component = Game.ObjectPool.Fetch(type);
}
component.Domain = this.Domain;
component.Id = this.Id;
component.ComponentParent = this;
private T CreateWithComponentParent<T, A, B>(A a, B b, bool isFromPool = true) where T : Entity
{
Type type = typeof (T);
Entity component = Create(type, isFromPool);
Game.EventSystem.Awake(component, a, b);
return (T)component;
}
component.Id = this.Id;
component.ComponentParent = this;
EventSystem.Instance.Awake(component, a, b);
return (T)component;
}
private T CreateWithComponentParent<T, A, B, C>(A a, B b, C c, bool isFromPool = true) where T : Entity
{
Type type = typeof (T);
Entity component;
if (!isFromPool)
{
component = (Entity)Activator.CreateInstance(type);
}
else
{
component = Game.ObjectPool.Fetch(type);
}
component.Domain = this.Domain;
component.Id = this.Id;
component.ComponentParent = this;
private T CreateWithComponentParent<T, A, B, C>(A a, B b, C c, bool isFromPool = true) where T : Entity
{
Type type = typeof (T);
Entity component = Create(type, isFromPool);
component.Id = this.Id;
component.ComponentParent = this;
Game.EventSystem.Awake(component, a, b, c);
return (T)component;
}
}
EventSystem.Instance.Awake(component, a, b, c);
return (T)component;
}
}
}
\ No newline at end of file
using System;
using System;
namespace ETModel
{
......@@ -6,88 +6,143 @@ namespace ETModel
{
public static Entity CreateWithParent(Type type, Entity parent)
{
Entity component = Game.ObjectPool.Fetch(type);
component.Domain = parent.Domain;
component.Id = component.InstanceId;
Entity component = Entity.Create(type, true);
component.Id = IdGenerater.GenerateId();
component.Parent = parent;
Game.EventSystem.Awake(component);
EventSystem.Instance.Awake(component);
return component;
}
public static T CreateWithParent<T>(Entity parent) where T : Entity
{
Type type = typeof (T);
T component = (T)Game.ObjectPool.Fetch(type);
component.Domain = parent.Domain;
component.Id = component.InstanceId;
T component = (T)Entity.Create(type, true);
component.Id = IdGenerater.GenerateId();
component.Parent = parent;
Game.EventSystem.Awake(component);
EventSystem.Instance.Awake(component);
return component;
}
public static T CreateWithParent<T, A>(Entity parent, A a) where T : Entity
{
Type type = typeof (T);
T component = (T)Game.ObjectPool.Fetch(type);
component.Domain = parent.Domain;
component.Id = component.InstanceId;
T component = (T)Entity.Create(type, true);
component.Id = IdGenerater.GenerateId();
component.Parent = parent;
Game.EventSystem.Awake(component, a);
EventSystem.Instance.Awake(component, a);
return component;
}
public static T CreateWithParent<T, A, B>(Entity parent, A a, B b) where T : Entity
{
Type type = typeof (T);
T component = (T)Game.ObjectPool.Fetch(type);
component.Domain = parent.Domain;
component.Id = component.InstanceId;
T component = (T)Entity.Create(type, true);
component.Id = IdGenerater.GenerateId();
component.Parent = parent;
Game.EventSystem.Awake(component, a, b);
EventSystem.Instance.Awake(component, a, b);
return component;
}
public static T CreateWithParent<T, A, B, C>(Entity parent, A a, B b, C c, bool fromPool = true) where T : Entity
{
Type type = typeof (T);
T component = (T)Game.ObjectPool.Fetch(type);
component.Domain = parent.Domain;
component.Id = component.InstanceId;
T component = (T)Entity.Create(type, true);
component.Id = IdGenerater.GenerateId();
component.Parent = parent;
Game.EventSystem.Awake(component, a, b, c);
EventSystem.Instance.Awake(component, a, b, c);
return component;
}
public static T CreateWithParent<T, A, B, C, D>(Entity parent, A a, B b, C c, D d, bool fromPool = true) where T : Entity
{
Type type = typeof(T);
T component = (T)Entity.Create(type, true);
component.Id = IdGenerater.GenerateId();
component.Parent = parent;
EventSystem.Instance.Awake(component, a, b, c, d);
return component;
}
public static Entity CreateWithParentAndId(Type type, Entity parent, long id)
{
Entity component = Entity.Create(type, true);
component.Id = id;
component.Parent = parent;
EventSystem.Instance.Awake(component);
return component;
}
public static T CreateWithParentAndId<T>(Entity parent, long id) where T : Entity
{
Type type = typeof (T);
T component = (T)Entity.Create(type, true);
component.Id = id;
component.Parent = parent;
EventSystem.Instance.Awake(component);
return component;
}
public static T CreateWithParentAndId<T, A>(Entity parent, long id, A a) where T : Entity
{
Type type = typeof (T);
T component = (T)Entity.Create(type, true);
component.Id = id;
component.Parent = parent;
EventSystem.Instance.Awake(component, a);
return component;
}
public static T CreateWithParentAndId<T, A, B>(Entity parent, long id, A a, B b) where T : Entity
{
Type type = typeof (T);
T component = (T)Entity.Create(type, true);
component.Id = id;
component.Parent = parent;
EventSystem.Instance.Awake(component, a, b);
return component;
}
T component = (T)Game.ObjectPool.Fetch(type);
component.Domain = parent.Domain;
component.Id = component.InstanceId;
public static T CreateWithParentAndId<T, A, B, C>(Entity parent, long id, A a, B b, C c, bool fromPool = true) where T : Entity
{
Type type = typeof (T);
T component = (T)Entity.Create(type, true);
component.Id = id;
component.Parent = parent;
EventSystem.Instance.Awake(component, a, b, c);
return component;
}
public static T CreateWithParentAndId<T, A, B, C, D>(Entity parent, long id, A a, B b, C c, D d, bool fromPool = true) where T : Entity
{
Type type = typeof(T);
T component = (T)Entity.Create(type, true);
component.Id = id;
component.Parent = parent;
Game.EventSystem.Awake(component, a, b, c, d);
EventSystem.Instance.Awake(component, a, b, c, d);
return component;
}
public static Entity Create(Entity domain, Type type)
{
Entity component = Game.ObjectPool.Fetch(type);
component.Domain = domain ?? component;
component.Id = component.InstanceId;
Entity component = Entity.Create(type, true);
component.Domain = domain;
component.Id = IdGenerater.GenerateId();
Game.EventSystem.Awake(component);
EventSystem.Instance.Awake(component);
return component;
}
......@@ -95,130 +150,81 @@ namespace ETModel
public static T Create<T>(Entity domain) where T : Entity
{
Type type = typeof (T);
T component = (T)Game.ObjectPool.Fetch(type);
component.Domain = domain ?? component;
component.Id = component.InstanceId;
Game.EventSystem.Awake(component);
T component = (T)Entity.Create(type, true);
component.Domain = domain;
component.Id = IdGenerater.GenerateId();
EventSystem.Instance.Awake(component);
return component;
}
public static T Create<T, A>(Entity domain, A a) where T : Entity
{
Type type = typeof (T);
T component = (T)Game.ObjectPool.Fetch(type);
component.Domain = domain ?? component;
component.Id = component.InstanceId;
Game.EventSystem.Awake(component, a);
T component = (T)Entity.Create(type, true);
component.Domain = domain;
component.Id = IdGenerater.GenerateId();
EventSystem.Instance.Awake(component, a);
return component;
}
public static T Create<T, A, B>(Entity domain, A a, B b) where T : Entity
{
Type type = typeof (T);
T component = (T)Game.ObjectPool.Fetch(type);
component.Domain = domain ?? component;
component.Id = component.InstanceId;
Game.EventSystem.Awake(component, a, b);
T component = (T)Entity.Create(type, true);
component.Domain = domain;
component.Id = IdGenerater.GenerateId();
EventSystem.Instance.Awake(component, a, b);
return component;
}
public static T Create<T, A, B, C>(Entity domain, A a, B b, C c) where T : Entity
{
Type type = typeof (T);
T component = (T) Game.ObjectPool.Fetch(type);
component.Domain = domain ?? component;
component.Id = component.InstanceId;
Game.EventSystem.Awake(component, a, b, c);
T component = (T)Entity.Create(type, true);
component.Domain = domain;
component.Id = IdGenerater.GenerateId();
EventSystem.Instance.Awake(component, a, b, c);
return component;
}
public static T CreateWithId<T>(Entity domain, long id) where T : Entity
{
Type type = typeof (T);
T component = (T)Game.ObjectPool.Fetch(type);
component.Domain = domain ?? component;
T component = (T)Entity.Create(type, true);
component.Domain = domain;
component.Id = id;
Game.EventSystem.Awake(component);
EventSystem.Instance.Awake(component);
return component;
}
public static T CreateWithId<T, A>(Entity domain, long id, A a) where T : Entity
{
Type type = typeof (T);
T component = (T)Game.ObjectPool.Fetch(type);
component.Domain = domain ?? component;
T component = (T)Entity.Create(type, true);
component.Domain = domain;
component.Id = id;
Game.EventSystem.Awake(component, a);
EventSystem.Instance.Awake(component, a);
return component;
}
public static T CreateWithId<T, A, B>(Entity domain, long id, A a, B b) where T : Entity
{
Type type = typeof (T);
T component = (T)Game.ObjectPool.Fetch(type);
component.Domain = domain ?? component;
T component = (T)Entity.Create(type, true);
component.Domain = domain;
component.Id = id;
Game.EventSystem.Awake(component, a, b);
EventSystem.Instance.Awake(component, a, b);
return component;
}
public static T CreateWithId<T, A, B, C>(Entity domain, long id, A a, B b, C c) where T : Entity
{
Type type = typeof (T);
T component = (T)Game.ObjectPool.Fetch(type);
component.Domain = domain ?? component;
T component = (T)Entity.Create(type, true);
component.Domain = domain;
component.Id = id;
Game.EventSystem.Awake(component, a, b, c);
EventSystem.Instance.Awake(component, a, b, c);
return component;
}
#if SERVER
public static Scene CreateScene(long id, string name, SceneType sceneType, Scene parent = null)
{
Scene scene = (Scene)Game.ObjectPool.Fetch(typeof(Scene));
scene.Id = id;
Game.EventSystem.Remove(scene.InstanceId);
// 高14位是进程id
scene.InstanceId = IdGenerater.GenerateSceneInstanceId(id);
Game.EventSystem.RegisterSystem(scene);
if (parent != null)
{
scene.Parent = parent;
}
scene.Domain = scene;
scene.Name = name;
scene.SceneType = sceneType;
return scene;
}
#endif
public static Scene CreateScene(SceneType sceneType, string name, Scene parent = null,long id = 0)
{
Scene scene = (Scene)Game.ObjectPool.Fetch(typeof(Scene));
scene.Id = id != 0 ? id : IdGenerater.GenerateId();
scene.Name = name;
scene.SceneType = sceneType;
if (parent != null)
{
scene.Parent = parent;
}
scene.Domain = scene;
return scene;
}
}
}
......@@ -8,16 +8,31 @@ namespace ETModel
{
public enum DLLType
{
Core,
Model,
Hotfix,
Editor,
}
public sealed class EventSystem
public sealed class EventSystem: IDisposable
{
private static EventSystem instance;
public static EventSystem Instance
{
get
{
if (instance == null)
{
instance = new EventSystem();
}
return instance;
}
}
private readonly Dictionary<long, Entity> allComponents = new Dictionary<long, Entity>();
private readonly Dictionary<DLLType, Assembly> assemblies = new Dictionary<DLLType, Assembly>();
private readonly Dictionary<string, Assembly> assemblies = new Dictionary<string, Assembly>();
private readonly UnOrderMultiMapSet<Type, Type> types = new UnOrderMultiMapSet<Type, Type>();
......@@ -38,7 +53,7 @@ namespace ETModel
private readonly UnOrderMultiMap<Type, IChangeSystem> changeSystems = new UnOrderMultiMap<Type, IChangeSystem>();
private readonly UnOrderMultiMap<Type, IDeserializeSystem> deserializeSystems = new UnOrderMultiMap<Type, IDeserializeSystem>();
private Queue<long> updates = new Queue<long>();
private Queue<long> updates2 = new Queue<long>();
......@@ -50,9 +65,14 @@ namespace ETModel
private Queue<long> lateUpdates = new Queue<long>();
private Queue<long> lateUpdates2 = new Queue<long>();
public void Add(DLLType dllType, Assembly assembly)
private EventSystem()
{
this.assemblies[dllType] = assembly;
this.Add(typeof(EventSystem).Assembly);
}
public void Add(Assembly assembly)
{
this.assemblies[assembly.ManifestModule.ScopeName] = assembly;
this.types.Clear();
foreach (Assembly value in this.assemblies.Values)
{
......@@ -69,8 +89,10 @@ namespace ETModel
continue;
}
BaseAttribute baseAttribute = (BaseAttribute) objects[0];
this.types.Add(baseAttribute.AttributeType, type);
foreach (BaseAttribute baseAttribute in objects)
{
this.types.Add(baseAttribute.AttributeType, type);
}
}
}
......@@ -86,7 +108,6 @@ namespace ETModel
foreach (Type type in this.GetTypes(typeof(ObjectSystemAttribute)))
{
object obj = Activator.CreateInstance(type);
switch (obj)
{
case IAwakeSystem objectSystem:
......@@ -117,28 +138,30 @@ namespace ETModel
}
this.allEvents.Clear();
if (this.types.ContainsKey(typeof (EventAttribute)))
foreach (Type type in types[typeof(EventAttribute)])
{
foreach (Type type in types[typeof(EventAttribute)])
{
object[] attrs = type.GetCustomAttributes(typeof(EventAttribute), false);
object[] attrs = type.GetCustomAttributes(typeof(EventAttribute), false);
foreach (object attr in attrs)
foreach (object attr in attrs)
{
EventAttribute aEventAttribute = (EventAttribute)attr;
object obj = Activator.CreateInstance(type);
IEvent iEvent = obj as IEvent;
if (iEvent == null)
{
EventAttribute aEventAttribute = (EventAttribute)attr;
object obj = Activator.CreateInstance(type);
IEvent iEvent = obj as IEvent;
if (iEvent == null)
{
Log.Error($"{obj.GetType().Name} 没有继承IEvent");
}
this.RegisterEvent(aEventAttribute.Type, iEvent);
Log.Error($"{obj.GetType().Name} 没有继承IEvent");
}
this.RegisterEvent(aEventAttribute.Type, iEvent);
}
}
this.Load();
}
public Assembly GetAssembly(string name)
{
return this.assemblies[name];
}
public void RegisterEvent(string eventId, IEvent e)
{
......@@ -148,11 +171,6 @@ namespace ETModel
}
this.allEvents[eventId].Add(e);
}
public Assembly Get(DLLType dllType)
{
return this.assemblies[dllType];
}
public HashSet<Type> GetTypes(Type systemAttributeType)
{
......@@ -617,10 +635,15 @@ namespace ETModel
{
return;
}
foreach (AEvent aEvent in iEvents)
foreach (object obj in iEvents)
{
try
{
if (!(obj is AEvent aEvent))
{
Log.Error($"event error: {obj.GetType().Name}");
continue;
}
aEvent.Run();
}
catch (Exception e)
......@@ -641,14 +664,12 @@ namespace ETModel
{
try
{
if (obj is AEvent<A> aEvent)
{
aEvent.Run(a);
}
else if (obj is EventProxy eventProxy)
if (!(obj is AEvent<A> aEvent))
{
eventProxy.Handle(a);
Log.Error($"event error: {obj.GetType().Name}");
continue;
}
aEvent.Run(a);
}
catch (Exception e)
{
......@@ -668,14 +689,12 @@ namespace ETModel
{
try
{
if (obj is AEvent<A, B> aEvent)
if (!(obj is AEvent<A, B> aEvent))
{
aEvent.Run(a, b);
}
else if (obj is EventProxy eventProxy)
{
eventProxy.Handle(a, b);
Log.Error($"event error: {obj.GetType().Name}");
continue;
}
aEvent.Run(a, b);
}
catch (Exception e)
{
......@@ -695,14 +714,12 @@ namespace ETModel
{
try
{
if (obj is AEvent<A, B, C> aEvent)
if (!(obj is AEvent<A, B, C> aEvent))
{
aEvent.Run(a, b, c);
}
else if (obj is EventProxy eventProxy)
{
eventProxy.Handle(a, b, c);
Log.Error($"event error: {obj.GetType().Name}");
continue;
}
aEvent.Run(a, b, c);
}
catch (Exception e)
{
......@@ -710,7 +727,7 @@ namespace ETModel
}
}
}
public override string ToString()
{
StringBuilder sb = new StringBuilder();
......@@ -768,5 +785,10 @@ namespace ETModel
return sb.ToString();
}
public void Dispose()
{
instance = null;
}
}
}
\ No newline at end of file
using System.ComponentModel;
using System;
using System.ComponentModel;
using MongoDB.Bson.Serialization.Attributes;
#if !SERVER
using UnityEngine;
#endif
namespace ETModel
{
public abstract class Object: ISupportInitialize
{
public virtual void BeginInit()
public abstract class Object: ISupportInitialize, IDisposable
{
#if UNITY_EDITOR
public static GameObject Global
{
get
{
return GameObject.Find("/Global");
}
}
public virtual void EndInit()
{
}
}
[BsonIgnore]
public GameObject ViewGO { get; }
#endif
public Object()
{
#if UNITY_EDITOR
if (!this.GetType().IsDefined(typeof (HideInHierarchy), true))
{
this.ViewGO = new GameObject();
this.ViewGO.name = this.GetType().Name;
this.ViewGO.layer = LayerMask.NameToLayer("Hidden");
this.ViewGO.transform.SetParent(Global.transform, false);
this.ViewGO.AddComponent<ComponentView>().Component = this;
}
#endif
}
public virtual void BeginInit()
{
}
public virtual void EndInit()
{
}
public virtual void Dispose()
{
#if UNITY_EDITOR
if (this.ViewGO != null)
{
UnityEngine.Object.Destroy(this.ViewGO);
}
#endif
}
}
}
\ No newline at end of file
......@@ -8,48 +8,33 @@ using UnityEngine;
namespace ETModel
{
public class ComponentQueue: IDisposable
public class ComponentQueue: Object
{
public long Id;
#if !SERVER
public static GameObject Global { get; } = GameObject.Find("/Global");
public GameObject ViewGO { get; set; }
#endif
public string TypeName { get; }
private readonly Queue<Entity> queue = new Queue<Entity>();
private readonly Queue<Object> queue = new Queue<Object>();
public ComponentQueue(string typeName)
{
this.Id = IdGenerater.GenerateId();
this.TypeName = typeName;
#if !SERVER
this.ViewGO = new GameObject();
this.ViewGO.name = this.GetType().Name;
this.ViewGO.layer = LayerNames.GetLayerInt(LayerNames.HIDDEN);
this.ViewGO.transform.SetParent(Global.transform, false);
this.ViewGO.AddComponent<ComponentView>().Component = this;
#endif
}
public void Enqueue(Entity entity)
public void Enqueue(Object entity)
{
this.queue.Enqueue(entity);
}
public Entity Dequeue()
public Object Dequeue()
{
return this.queue.Dequeue();
}
public Entity Peek()
public Object Peek()
{
return this.queue.Peek();
}
public Queue<Entity> Queue
public Queue<Object> Queue
{
get
{
......@@ -65,66 +50,60 @@ namespace ETModel
}
}
public void Dispose()
public override void Dispose()
{
while (this.queue.Count > 0)
{
Entity component = this.queue.Dequeue();
Object component = this.queue.Dequeue();
component.Dispose();
}
}
}
public class ObjectPool: IDisposable
public class ObjectPool: Object
{
#if !SERVER
public static GameObject Global { get; } = GameObject.Find("/Global");
public GameObject ViewGO { get; set; }
#endif
public string Name { get; set; }
private readonly Dictionary<Type, ComponentQueue> dictionary = new Dictionary<Type, ComponentQueue>();
private static ObjectPool instance;
public ObjectPool()
{
#if !SERVER
this.ViewGO = new GameObject();
this.ViewGO.name = this.GetType().Name;
this.ViewGO.layer = LayerNames.GetLayerInt(LayerNames.HIDDEN);
this.ViewGO.transform.SetParent(Global.transform, false);
this.ViewGO.AddComponent<ComponentView>().Component = this;
#endif
}
public static ObjectPool Instance
{
get
{
if (instance == null)
{
instance = new ObjectPool();
}
public Entity Fetch(Type type)
return instance;
}
}
public readonly Dictionary<Type, ComponentQueue> dictionary = new Dictionary<Type, ComponentQueue>();
public Object Fetch(Type type)
{
Entity obj;
if (!this.dictionary.TryGetValue(type, out ComponentQueue queue))
Object obj;
if (!this.dictionary.TryGetValue(type, out ComponentQueue queue))
{
obj = (Entity)Activator.CreateInstance(type);
obj = (Object)Activator.CreateInstance(type);
}
else if (queue.Count == 0)
{
obj = (Entity)Activator.CreateInstance(type);
obj = (Object)Activator.CreateInstance(type);
}
else
{
obj = queue.Dequeue();
}
obj.IsFromPool = true;
return obj;
}
public T Fetch<T>() where T: Entity
public T Fetch<T>() where T: Object
{
T t = (T) this.Fetch(typeof(T));
return t;
}
public void Recycle(Entity obj)
public void Recycle(Object obj)
{
Type type = obj.GetType();
ComponentQueue queue;
......@@ -132,7 +111,7 @@ namespace ETModel
{
queue = new ComponentQueue(type.Name);
#if !SERVER
#if UNITY_EDITOR
if (queue.ViewGO != null)
{
queue.ViewGO.transform.SetParent(this.ViewGO.transform);
......@@ -142,224 +121,23 @@ namespace ETModel
this.dictionary.Add(type, queue);
}
#if !SERVER
#if UNITY_EDITOR
if (obj.ViewGO != null)
{
obj.ViewGO.transform.SetParent(queue.ViewGO.transform);
}
#endif
obj.Id = 0;
queue.Enqueue(obj);
}
public void Dispose()
public override void Dispose()
{
foreach (var kv in this.dictionary)
{
kv.Value.Dispose();
}
this.dictionary.Clear();
}
public override string ToString()
{
StringBuilder sb = new StringBuilder();
Dictionary<Type, int> typeCount = new Dictionary<Type, int>();
foreach (var kv in this.dictionary)
{
typeCount[kv.Key] = kv.Value.Count;
}
IOrderedEnumerable<KeyValuePair<Type, int>> orderByDescending = typeCount.OrderByDescending(s => s.Value);
sb.AppendLine("ObjectPool Count: ");
foreach (var kv in orderByDescending)
{
if (kv.Value == 1)
{
continue;
}
sb.AppendLine($"\t{kv.Key.Name}: {kv.Value}");
}
MultiMapSet<string, string> dict = Check();
sb.Append("not reset field:\n");
foreach (KeyValuePair<string,HashSet<string>> pair in dict.GetDictionary())
{
sb.Append(pair.Key + ": ");
foreach (string value in pair.Value)
{
sb.Append(value + ", ");
}
sb.Append("\n");
}
return sb.ToString();
}
public void LogErrorCheckResult()
{
MultiMapSet<string, string> dict = Check();
if (dict.Count == 0)
{
return;
}
StringBuilder sb = new StringBuilder();
sb.Append("not reset field:\n");
foreach (KeyValuePair<string,HashSet<string>> pair in dict.GetDictionary())
{
sb.Append(pair.Key + ": ");
foreach (string value in pair.Value)
{
sb.Append(value + ", ");
}
sb.Append("\n");
}
Log.Error(sb.ToString());
}
public MultiMapSet<string, string> Check()
{
MultiMapSet<string, string> dict = new MultiMapSet<string, string>();
foreach (ComponentQueue queue in this.dictionary.Values)
{
foreach (Entity entity in queue.Queue)
{
Type type = entity.GetType();
FieldInfo[] fieldInfos = type.GetFields();
foreach (FieldInfo fieldInfo in fieldInfos)
{
if (fieldInfo.IsLiteral)
{
continue;
}
if (fieldInfo.GetCustomAttributes(typeof (NoMemoryCheck)).Count() > 0)
{
continue;
}
Type fieldType = fieldInfo.FieldType;
if (fieldType == typeof (int))
{
if ((int) fieldInfo.GetValue(entity) != 0)
{
dict.Add(type.Name, fieldInfo.Name);
}
continue;
}
if (fieldType == typeof (uint))
{
if ((uint) fieldInfo.GetValue(entity) != 0)
{
dict.Add(type.Name, fieldInfo.Name);
}
continue;
}
if (fieldType == typeof (long))
{
if ((long) fieldInfo.GetValue(entity) != 0)
{
dict.Add(type.Name, fieldInfo.Name);
}
continue;
}
if (fieldType == typeof (ulong))
{
if ((ulong) fieldInfo.GetValue(entity) != 0)
{
dict.Add(type.Name, fieldInfo.Name);
}
continue;
}
if (fieldType == typeof (short))
{
if ((short) fieldInfo.GetValue(entity) != 0)
{
dict.Add(type.Name, fieldInfo.Name);
}
continue;
}
if (fieldType == typeof (ushort))
{
if ((ushort) fieldInfo.GetValue(entity) != 0)
{
dict.Add(type.Name, fieldInfo.Name);
}
continue;
}
if (fieldType == typeof (float))
{
if (Math.Abs((float)fieldInfo.GetValue(entity)) > 0.0001)
{
dict.Add(type.Name, fieldInfo.Name);
}
continue;
}
if (fieldType == typeof (double))
{
if (Math.Abs((double)fieldInfo.GetValue(entity)) > 0.0001)
{
dict.Add(type.Name, fieldInfo.Name);
}
continue;
}
if (fieldType == typeof (bool))
{
if ((bool) fieldInfo.GetValue(entity) != false)
{
dict.Add(type.Name, fieldInfo.Name);
}
continue;
}
if (typeof(ICollection).IsAssignableFrom(fieldType))
{
object fieldValue = fieldInfo.GetValue(entity);
if (fieldValue == null)
{
continue;
}
if (((ICollection)fieldValue).Count != 0)
{
dict.Add(type.Name, fieldInfo.Name);
}
continue;
}
PropertyInfo propertyInfo = fieldType.GetProperty("Count");
if (propertyInfo != null)
{
if ((int) propertyInfo.GetValue(fieldInfo.GetValue(entity)) != 0)
{
dict.Add(type.Name, fieldInfo.Name);
}
continue;
}
if (fieldType.IsClass)
{
if (fieldInfo.GetValue(entity) != null)
{
dict.Add(type.Name, fieldInfo.Name);
}
continue;
}
}
}
}
return dict;
instance = null;
}
}
}
\ No newline at end of file
namespace ETModel
{
public class ClientConfig: AConfigComponent
{
public string Address { get; set; }
}
}
\ No newline at end of file
fileFormatVersion: 2
guid: 55a8e5c4f18085e478c48b724a130a3f
timeCreated: 1498879500
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
namespace ETModel
{
[NoObjectPool]
public class CopyConfig: AConfigComponent
{
}
}
\ No newline at end of file
using MongoDB.Bson.Serialization.Attributes;
namespace ETModel
{
[BsonIgnoreExtraElements]
public class DBConfig : AConfigComponent
{
public string ConnectionString { get; set; }
public string DBName { get; set; }
}
}
\ No newline at end of file
fileFormatVersion: 2
guid: e8535ccd83c14ff44949812c618f7618
timeCreated: 1498901248
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using MongoDB.Bson.Serialization.Attributes;
namespace ETModel
{
[BsonIgnoreExtraElements]
public class HttpConfig: AConfigComponent
{
public string Url { get; set; } = "";
public int AppId { get; set; }
public string AppKey { get; set; } = "";
public string ManagerSystemUrl { get; set; } = "";
}
}
\ No newline at end of file
fileFormatVersion: 2
guid: d1dc4ae9437263b4cb6956129ea85149
timeCreated: 1498901248
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using System.Net;
using MongoDB.Bson.Serialization.Attributes;
namespace ETModel
{
[NoObjectPool]
[BsonIgnoreExtraElements]
public class InnerConfig: AConfigComponent
{
public string Address { get; set; }
}
}
\ No newline at end of file
fileFormatVersion: 2
guid: 4064ddb40060cc1428752c3e0801d9c8
timeCreated: 1498879500
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
namespace ETModel
{
public enum MapType
{
// 城市
City,
// 野外
Field,
// 副本
Copy,
}
[NoObjectPool]
public class MapConfig: AConfigComponent
{
public MapType MapType;
}
}
\ No newline at end of file
using MongoDB.Bson.Serialization.Attributes;
namespace ETModel
{
[BsonIgnoreExtraElements]
public class OuterConfig: AConfigComponent
{
public string Address { get; set; }
public string Address2 { get; set; }
}
}
\ No newline at end of file
fileFormatVersion: 2
guid: 40de537c2dfc44a439eab4fb74502abe
timeCreated: 1498879500
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
namespace ETModel
{
[NoObjectPool]
public class ProcessConfig: AConfigComponent
{
public string ServerIP { get; set; }
}
}
\ No newline at end of file
using MongoDB.Bson.Serialization.Attributes;
namespace ETModel
{
[BsonIgnoreExtraElements]
public class RunServerConfig: AConfigComponent
{
public string IP = "";
}
}
\ No newline at end of file
fileFormatVersion: 2
guid: 9ae51a9486e2bc54580bb6ad0e16c28e
timeCreated: 1498879500
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
namespace ETModel
{
[NoObjectPool]
public class SceneConfig: AConfigComponent
{
public SceneType SceneType;
public string Name;
}
}
\ No newline at end of file
fileFormatVersion: 2
guid: 996fa0f2c5ccf0f41b69ce7466ff562f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using System.Collections.Generic;
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
#if !SERVER
using UnityEngine;
#endif
namespace ETModel
{
#if !SERVER
[HideInHierarchy]
#endif
[NoObjectPool]
public class StartConfig: Entity
{
[BsonIgnore]
public long SceneInstanceId { get; set; }
public List<StartConfig> List = new List<StartConfig>();
public void Add(StartConfig startConfig)
{
startConfig.parent = this;
this.List.Add(startConfig);
}
public StartConfig Get(long id)
{
foreach (StartConfig startConfig in this.List)
{
if (startConfig.Id == id)
{
return startConfig;
}
}
return null;
}
public void Remove(StartConfig startConfig)
{
this.List.Remove(startConfig);
}
public override void EndInit()
{
base.EndInit();
foreach (StartConfig startConfig in this.List)
{
startConfig.parent = this;
}
}
}
}
\ No newline at end of file
fileFormatVersion: 2
guid: c181dc38f15288746960812611a7767e
timeCreated: 1498118076
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
namespace ETModel
{
[Config]
public partial class StartProcessConfigCategory : ACategory<StartProcessConfig>
{
public static StartProcessConfigCategory Instance;
public StartProcessConfigCategory()
{
Instance = this;
}
}
public partial class StartProcessConfig: IConfig
{
public long Id { get; set; }
public string InnerIP;
public string InnerPort;
public string OuterIP;
}
}
fileFormatVersion: 2
guid: 5117c0c6bc0179c4a88657c4fbdeaca1
guid: 39cf2e924f672d54190b2f6c0387eb7f
MonoImporter:
externalObjects: {}
serializedVersion: 2
......
namespace ETModel
{
[Config]
public partial class StartSceneConfigCategory : ACategory<StartSceneConfig>
{
public static StartSceneConfigCategory Instance;
public StartSceneConfigCategory()
{
Instance = this;
}
}
public partial class StartSceneConfig: IConfig
{
public long Id { get; set; }
public int Process;
public int Zone;
public string SceneType;
public string Name;
public int OuterPort;
}
}
fileFormatVersion: 2
guid: dd9012b6e149e91419235c827bf6ac70
guid: 3cabfc3c98fa5584fa09d864a093f35d
MonoImporter:
externalObjects: {}
serializedVersion: 2
......
namespace ETModel
{
[Config]
public partial class StartZoneConfigCategory : ACategory<StartZoneConfig>
{
public static StartZoneConfigCategory Instance;
public StartZoneConfigCategory()
{
Instance = this;
}
}
public partial class StartZoneConfig: IConfig
{
public long Id { get; set; }
public string DBConnection;
public string DBName;
}
}
fileFormatVersion: 2
guid: 4e1a0ea8fc40f1c49b49bc53fcb204ab
guid: 909993798dcc71343b950e590de2fc00
MonoImporter:
externalObjects: {}
serializedVersion: 2
......
......@@ -3,9 +3,14 @@ namespace ETModel
[Config]
public partial class UnitConfigCategory : ACategory<UnitConfig>
{
public static UnitConfigCategory Instance;
public UnitConfigCategory()
{
Instance = this;
}
}
public class UnitConfig: IConfig
public partial class UnitConfig: IConfig
{
public long Id { get; set; }
public string Name;
......
......@@ -17,21 +17,22 @@ namespace ETModel
[HideInHierarchy]
public sealed class Unit: Entity
{
public GameObject GameObject;
public void Awake(GameObject gameObject)
{
this.ViewGO = gameObject;
this.ViewGO.AddComponent<ComponentView>().Component = this;
this.GameObject = gameObject;
}
public Vector3 Position
{
get
{
return ViewGO.transform.position;
return GameObject.transform.position;
}
set
{
ViewGO.transform.position = value;
GameObject.transform.position = value;
}
}
......@@ -39,22 +40,12 @@ namespace ETModel
{
get
{
return ViewGO.transform.rotation;
return GameObject.transform.rotation;
}
set
{
ViewGO.transform.rotation = value;
GameObject.transform.rotation = value;
}
}
public override void Dispose()
{
if (this.IsDisposed)
{
return;
}
base.Dispose();
}
}
}
\ No newline at end of file
namespace ETModel
{
public static class EntitySceneFactory
{
public static Scene CreateScene(long id, int zone, SceneType sceneType, string name, Scene parent = null)
{
Scene scene = new Scene(id, zone, sceneType, name);
scene.IsRegister = true;
scene.Parent = parent;
scene.Domain = scene;
return scene;
}
public static Scene CreateScene(int zone, SceneType sceneType, string name, Scene parent = null)
{
long id = IdGenerater.GenerateId();
Scene scene = new Scene(id, zone, sceneType, name);
scene.IsRegister = true;
scene.Parent = parent;
scene.Domain = scene;
return scene;
}
}
}
\ No newline at end of file
fileFormatVersion: 2
guid: a920bf8988c17394d9c3efe4f107704b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
using UnityEngine;
namespace ETModel
namespace ETModel
{
public static class Game
{
private static EventSystem eventSystem;
public static EventSystem EventSystem
{
get
{
return eventSystem ?? (eventSystem = new EventSystem());
}
}
private static Scene scene;
public static class Game
{
public static EventSystem EventSystem
{
get
{
return EventSystem.Instance;
}
}
public static Scene Scene
{
get
{
if (scene != null)
{
return scene;
}
scene = new Scene() { Name = "ClientM" };
return scene;
}
}
private static Scene scene;
private static ObjectPool objectPool;
public static Scene Scene
{
get
{
return scene ?? (scene = EntitySceneFactory.CreateScene(1, SceneType.Process, "Process"));
}
}
public static ObjectPool ObjectPool
{
get
{
if (objectPool != null)
{
return objectPool;
}
objectPool = new ObjectPool() { Name = "ClientM" };
return objectPool;
}
}
public static void Close()
{
scene?.Dispose();
scene = null;
objectPool?.Dispose();
objectPool = null;
eventSystem = null;
}
}
public static ObjectPool ObjectPool
{
get
{
return ObjectPool.Instance;
}
}
public static void Close()
{
scene?.Dispose();
scene = null;
ObjectPool.Instance.Dispose();
EventSystem.Instance.Dispose();
}
}
}
\ No newline at end of file
......@@ -2,8 +2,24 @@
{
public sealed class Scene: Entity
{
public SceneType SceneType { get; set; }
public string Name { get; set; }
public int Zone { get; }
public SceneType SceneType { get; }
public string Name { get; }
public Scene(long id, int zone, SceneType sceneType, string name)
{
this.Id = id;
this.InstanceId = id;
this.Zone = zone;
this.SceneType = sceneType;
this.Name = name;
this.IsCreate = true;
}
public Scene Get(long id)
{
return (Scene)this.Children?[id];
}
public new Entity Domain
{
......@@ -25,15 +41,30 @@
}
set
{
this.parent = value;
this.parent.Children.Add(this.Id, this);
#if !SERVER
if (this.ViewGO != null && this.parent.ViewGO != null)
if (value == null)
{
this.ViewGO.transform.SetParent(this.parent.ViewGO.transform, false);
this.parent = this;
return;
}
this.parent = value;
this.parent.Children.Add(this.Id, this);
#if UNITY_EDITOR
this.ViewGO.transform.SetParent(this.parent.ViewGO.transform, false);
#endif
}
}
}
public static class SceneEx
{
public static int DomainZone(this Entity entity)
{
return ((Scene) entity.Domain).Zone;
}
public static Scene DomainScene(this Entity entity)
{
return (Scene) entity.Domain;
}
}
}
\ No newline at end of file
......@@ -18,7 +18,7 @@ namespace ETModel
SynchronizationContext.SetSynchronizationContext(OneThreadSynchronizationContext.Instance);
DontDestroyOnLoad(gameObject);
Game.EventSystem.Add(DLLType.Model, typeof(Init).Assembly);
Game.EventSystem.Add(typeof(Init).Assembly);
Game.Scene.AddComponent<TimerComponent>();
Game.Scene.AddComponent<GlobalConfigComponent>();
......
......@@ -7,9 +7,6 @@ namespace ETModel
public abstract class ACategory : Object
{
public abstract Type ConfigType { get; }
public abstract IConfig GetOne();
public abstract IConfig[] GetAll();
public abstract IConfig TryGet(int type);
}
/// <summary>
......@@ -18,11 +15,11 @@ namespace ETModel
/// <typeparam name="T"></typeparam>
public abstract class ACategory<T> : ACategory where T : IConfig
{
protected Dictionary<long, IConfig> dict;
protected Dictionary<long, T> dict;
public override void BeginInit()
{
this.dict = new Dictionary<long, IConfig>();
this.dict = new Dictionary<long, T>();
string configStr = ConfigHelper.GetText(typeof(T).Name);
......@@ -57,22 +54,22 @@ namespace ETModel
{
}
public override IConfig TryGet(int type)
public T Get(int id)
{
IConfig t;
if (!this.dict.TryGetValue(type, out t))
T t;
if (!this.dict.TryGetValue(id, out t))
{
return null;
throw new Exception($"not found config: {typeof(T)} id: {id}");
}
return t;
}
public override IConfig[] GetAll()
public Dictionary<long, T> GetAll()
{
return this.dict.Values.ToArray();
return this.dict;
}
public override IConfig GetOne()
public T GetOne()
{
return this.dict.Values.First();
}
......
......@@ -3,111 +3,13 @@ using System.Collections.Generic;
namespace ETModel
{
[ObjectSystem]
public class ConfigComponentAwakeSystem : AwakeSystem<ConfigComponent>
{
public override void Awake(ConfigComponent self)
{
self.Awake();
}
}
[ObjectSystem]
public class ConfigComponentLoadSystem : LoadSystem<ConfigComponent>
{
public override void Load(ConfigComponent self)
{
self.Load();
}
}
/// <summary>
/// Config组件会扫描所有的有ConfigAttribute标签的配置,加载进来
/// </summary>
public class ConfigComponent: Entity
{
private Dictionary<Type, ACategory> allConfig = new Dictionary<Type, ACategory>();
public void Awake()
{
this.Load();
}
public void Load()
{
this.allConfig.Clear();
HashSet<Type> types = Game.EventSystem.GetTypes(typeof(ConfigAttribute));
foreach (Type type in types)
{
object[] attrs = type.GetCustomAttributes(typeof (ConfigAttribute), false);
if (attrs.Length == 0)
{
continue;
}
ConfigAttribute configAttribute = attrs[0] as ConfigAttribute;
object obj = Activator.CreateInstance(type);
ACategory iCategory = obj as ACategory;
if (iCategory == null)
{
throw new Exception($"class: {type.Name} not inherit from ACategory");
}
iCategory.BeginInit();
iCategory.EndInit();
this.allConfig[iCategory.ConfigType] = iCategory;
}
}
public IConfig GetOne(Type type)
{
ACategory configCategory;
if (!this.allConfig.TryGetValue(type, out configCategory))
{
throw new Exception($"ConfigComponent not found key: {type.FullName}");
}
return configCategory.GetOne();
}
public IConfig Get(Type type, int id)
{
ACategory configCategory;
if (!this.allConfig.TryGetValue(type, out configCategory))
{
throw new Exception($"ConfigComponent not found key: {type.FullName}");
}
return configCategory.TryGet(id);
}
public IConfig TryGet(Type type, int id)
{
ACategory configCategory;
if (!this.allConfig.TryGetValue(type, out configCategory))
{
return null;
}
return configCategory.TryGet(id);
}
public IConfig[] GetAll(Type type)
{
ACategory configCategory;
if (!this.allConfig.TryGetValue(type, out configCategory))
{
throw new Exception($"ConfigComponent not found key: {type.FullName}");
}
return configCategory.GetAll();
}
public ACategory GetCategory(Type type)
{
ACategory configCategory;
bool ret = this.allConfig.TryGetValue(type, out configCategory);
return ret ? configCategory : null;
}
}
/// <summary>
/// Config组件会扫描所有的有ConfigAttribute标签的配置,加载进来
/// </summary>
public class ConfigComponent: Entity
{
public static ConfigComponent Instance;
public Dictionary<Type, ACategory> AllConfig = new Dictionary<Type, ACategory>();
}
}
\ No newline at end of file
......@@ -17,6 +17,8 @@ namespace ETModel
[HideInHierarchy]
public sealed class UI: Entity
{
public GameObject GameObject;
public string Name { get; private set; }
public Dictionary<string, UI> children = new Dictionary<string, UI>();
......@@ -27,7 +29,7 @@ namespace ETModel
gameObject.AddComponent<ComponentView>().Component = this;
gameObject.layer = LayerMask.NameToLayer(LayerNames.UI);
this.Name = name;
this.ViewGO = gameObject;
this.GameObject = gameObject;
}
public override void Dispose()
......
fileFormatVersion: 2
guid: 0f64d5db023e08d4ebcf697a468402ce
folderAsset: yes
timeCreated: 1506045262
licenseType: Free
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
fileFormatVersion: 2
guid: d83695ee9902da74ba90d2c142a2519e
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 0
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 1
settings:
DefaultValueInitialized: true
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册