using System.Collections.Generic; namespace ET.Server { [EntitySystemOf(typeof(DBSaveComponent))] [FriendOf(typeof(DBSaveComponent))] public static partial class DBSaveComponentSystem { [EntitySystem] private static void Awake(this DBSaveComponent self) { self.RunFlushLoop().NoContext(); } [EntitySystem] private static void Destroy(this DBSaveComponent self) { self.DirtyAccounts.Clear(); } public static void MarkDirty(this DBSaveComponent self, string account) { if (string.IsNullOrEmpty(account)) { return; } self.DirtyAccounts.Add(account); } public static async ETTask FlushNow(this DBSaveComponent self, string account) { if (string.IsNullOrEmpty(account)) { return; } Scene root = self.Root(); DBComponent dbComponent = root.GetComponent(); PlayerComponent playerComponent = root.GetComponent(); if (dbComponent == null || playerComponent == null) { return; } Player player = playerComponent.GetByAccount(account); if (player == null) { self.DirtyAccounts.Remove(account); return; } await dbComponent.Save(player.Id, player); self.DirtyAccounts.Remove(account); } private static async ETTask RunFlushLoop(this DBSaveComponent self) { Scene root = self.Root(); TimerComponent timerComponent = root.GetComponent(); if (timerComponent == null) { return; } while (!self.IsDisposed) { await timerComponent.WaitAsync(self.FlushIntervalMs); if (self.IsDisposed) { break; } await self.FlushDirtyPlayers(); } } private static async ETTask FlushDirtyPlayers(this DBSaveComponent self) { if (self.DirtyAccounts.Count == 0) { return; } List accounts = new(self.DirtyAccounts); foreach (string account in accounts) { await self.FlushNow(account); } } } }