using System; using System.Collections.Generic; using System.Linq.Expressions; using System.Threading; using ETModel; using MongoDB.Bson; using MongoDB.Bson.Serialization; using MongoDB.Driver; namespace ETHotfix { [ObjectSystem] public class DbProxyComponentSystem : AwakeSystem { public override void Awake(DBProxyComponent self) { self.Awake(); } } /// /// 用来与数据库操作代理 /// public static class DBProxyComponentEx { public static void Awake(this DBProxyComponent self) { StartConfig dbStartConfig = StartConfigComponent.Instance.DBConfig; self.dbAddress = dbStartConfig.GetComponent().IPEndPoint; } public static async ETTask Save(this DBProxyComponent self, ComponentWithId component) { Session session = Game.Scene.GetComponent().Get(self.dbAddress); await session.Call(new DBSaveRequest { Component = component }); } public static async ETTask SaveBatch(this DBProxyComponent self, List components) { Session session = Game.Scene.GetComponent().Get(self.dbAddress); await session.Call(new DBSaveBatchRequest { Components = components }); } public static async ETTask Save(this DBProxyComponent self, ComponentWithId component, CancellationToken cancellationToken) { Session session = Game.Scene.GetComponent().Get(self.dbAddress); await session.Call(new DBSaveRequest { Component = component }, cancellationToken); } public static async ETVoid SaveLog(this DBProxyComponent self, ComponentWithId component) { Session session = Game.Scene.GetComponent().Get(self.dbAddress); await session.Call(new DBSaveRequest { Component = component, CollectionName = "Log" }); } public static ETTask Query(this DBProxyComponent self, long id) where T: ComponentWithId { string key = typeof (T).Name + id; ETTaskCompletionSource tcs = new ETTaskCompletionSource(); if (self.TcsQueue.ContainsKey(key)) { self.TcsQueue.Add(key, tcs); return tcs.Task; } self.TcsQueue.Add(key, tcs); self.QueryInner(id, key).Coroutine(); return tcs.Task; } private static async ETVoid QueryInner(this DBProxyComponent self, long id, string key) where T: ComponentWithId { try { Session session = Game.Scene.GetComponent().Get(self.dbAddress); DBQueryResponse dbQueryResponse = (DBQueryResponse)await session.Call(new DBQueryRequest { CollectionName = typeof(T).Name, Id = id }); T result = (T)dbQueryResponse.Component; object[] tcss = self.TcsQueue.GetAll(key); self.TcsQueue.Remove(key); foreach (ETTaskCompletionSource tcs in tcss) { tcs.SetResult(result); } } catch (Exception e) { object[] tcss = self.TcsQueue.GetAll(key); self.TcsQueue.Remove(key); foreach (ETTaskCompletionSource tcs in tcss) { tcs.SetException(e); } } } /// /// 根据查询表达式查询 /// /// /// /// /// public static async ETTask> Query(this DBProxyComponent self, Expression> exp) where T: ComponentWithId { ExpressionFilterDefinition filter = new ExpressionFilterDefinition(exp); IBsonSerializerRegistry serializerRegistry = BsonSerializer.SerializerRegistry; IBsonSerializer documentSerializer = serializerRegistry.GetSerializer(); string json = filter.Render(documentSerializer, serializerRegistry).ToJson(); return await self.Query(json); } public static async ETTask> Query(this DBProxyComponent self, List ids) where T : ComponentWithId { Session session = Game.Scene.GetComponent().Get(self.dbAddress); DBQueryBatchResponse dbQueryBatchResponse = (DBQueryBatchResponse)await session.Call(new DBQueryBatchRequest { CollectionName = typeof(T).Name, IdList = ids }); return dbQueryBatchResponse.Components; } /// /// 根据json查询条件查询 /// /// /// /// /// public static ETTask> Query(this DBProxyComponent self, string json) where T : ComponentWithId { string key = typeof (T).Name + json; ETTaskCompletionSource> tcs = new ETTaskCompletionSource>(); if (self.TcsQueue.ContainsKey(key)) { self.TcsQueue.Add(key, tcs); return tcs.Task; } self.TcsQueue.Add(key, tcs); self.QueryInner(json, key).Coroutine(); return tcs.Task; } private static async ETVoid QueryInner(this DBProxyComponent self, string json, string key) where T : ComponentWithId { try { Session session = Game.Scene.GetComponent().Get(self.dbAddress); DBQueryJsonResponse dbQueryJsonResponse = (DBQueryJsonResponse)await session.Call(new DBQueryJsonRequest { CollectionName = typeof(T).Name, Json = json }); var result = dbQueryJsonResponse.Components; object[] tcss = self.TcsQueue.GetAll(key); self.TcsQueue.Remove(key); foreach (ETTaskCompletionSource> tcs in tcss) { tcs.SetResult(result); } } catch (Exception e) { object[] tcss = self.TcsQueue.GetAll(key); self.TcsQueue.Remove(key); foreach (ETTaskCompletionSource> tcs in tcss) { tcs.SetException(e); } } } } }