From 6577857d41d1bc613d7766a9bca76be34e97cccd Mon Sep 17 00:00:00 2001 From: ninemine <1371605831@qq.com> Date: Sat, 12 Jul 2025 20:43:27 +0800 Subject: [PATCH] BS 0.1.0 GlobalConfig --- Convention/Runtime/GlobalConfig.md | 88 ---------- Convention/Runtime/GlobalConfig.py | 261 +++++++++++++++++++++++++++++ 2 files changed, 261 insertions(+), 88 deletions(-) delete mode 100644 Convention/Runtime/GlobalConfig.md create mode 100644 Convention/Runtime/GlobalConfig.py diff --git a/Convention/Runtime/GlobalConfig.md b/Convention/Runtime/GlobalConfig.md deleted file mode 100644 index f68a490..0000000 --- a/Convention/Runtime/GlobalConfig.md +++ /dev/null @@ -1,88 +0,0 @@ -[返回](./Runtime-README.md) - -# /Convention/Runtime/GlobalConfig - ---- - -全局配置管理模块,提供配置文件操作、日志系统和项目级配置管理 - -## GlobalConfig类 - -### 构造与初始化 -- `GlobalConfig(string dataDir, bool isTryCreateDataDir = false, bool isLoad = true)` -- `GlobalConfig(ToolFile dataDir, bool isTryCreateDataDir = false, bool isLoad = true)` - -#### 初始化流程 -1. 设置数据目录,确保目录存在 -2. 检查配置文件,不存在则生成空配置 -3. 可选自动加载现有配置 - -### 静态配置 -- `ConstConfigFile` 配置文件名(默认"config.json") -- `InitExtensionEnv()` 初始化扩展环境 -- `GenerateEmptyConfigJson(ToolFile file)` 生成空配置JSON - -### 文件管理 -- `GetConfigFile()` / `ConfigFile` 获取配置文件对象 -- `GetFile(string path, bool isMustExist = false)` 获取数据目录下的文件 -- `CreateFile(string path)` 创建文件 -- `EraseFile(string path)` 清空文件内容 -- `RemoveFile(string path)` 删除文件 - -### 配置数据操作 - -能够被`foreach`/`for`使用迭代器历遍配置内容的键值对 - -#### 数据访问 -- `operator[](string key)` 索引器访问配置项 -- `Contains(string key)` 检查键是否存在 -- `Remove(string key)` 删除配置项 -- `DataSize()` 获取配置项数量 - -#### 持久化 -- `SaveProperties()` 保存配置到文件 -- `LoadProperties()` 从文件加载配置 - -配置文件格式: -```json -{ - "properties": { - "key1": "value1", - "key2": "value2" - } -} -``` - -### 日志系统 -- `GetLogFile()` / `LogFile` 获取日志文件对象 -- `DefaultLogger` 默认日志输出器(可自定义) - -#### 日志方法 -- `Log(string messageType, string message, Action logger)` -- `Log(string messageType, string message)` 使用默认日志器 -- `LogPropertyNotFound(string message, Action logger, object @default = null)` -- `LogPropertyNotFound(string message, object @default = null)` -- `LogMessageOfPleaseCompleteConfiguration()` 记录配置提示信息 - -#### 日志格式 -``` -[time] MessageType : Message -``` - -自动调整消息类型的对齐宽度 - -### 配置查找 -- `FindItem(string key, object @default = null)` 查找配置项,支持默认值 - -## ProjectConfig类 - -继承自 `GlobalConfig`,专门用于项目级配置管理 - -### 静态配置 -- `ProjectConfigFileFocus` 项目配置目录焦点(默认"Assets/") -- `InitExtensionEnv()` 初始化项目扩展环境 -- `SetProjectConfigFileFocus(string path)` 设置项目配置焦点目录 -- `GetProjectConfigFileFocus()` 获取项目配置焦点目录 - -### 构造 -- `ProjectConfig(bool isLoad = true)` 使用默认项目目录构造 diff --git a/Convention/Runtime/GlobalConfig.py b/Convention/Runtime/GlobalConfig.py new file mode 100644 index 0000000..5a56438 --- /dev/null +++ b/Convention/Runtime/GlobalConfig.py @@ -0,0 +1,261 @@ +from .Config import * +from .File import ToolFile +from .String import FillString +from typing import * +import json +import os + +# 静态配置 +ConstConfigFile = "config.json" + +def InitExtensionEnv(): + """初始化扩展环境""" + global ConstConfigFile + ConstConfigFile = "config.json" + ProjectConfig.InitExtensionEnv() + +def GenerateEmptyConfigJson(file: ToolFile): + """生成空配置JSON""" + file.SaveAsJson({"properties": {}}) + return file + +class GlobalConfig: + """全局配置管理类""" + + def __init__( + self, + data_dir: Optional[Union[str, ToolFile]] = None, + is_try_create_data_dir: bool = False, + is_load: bool = True + ): + """ + 构造与初始化 + + Args: + data_dir: 数据目录路径或ToolFile对象 + is_try_create_data_dir: 是否尝试创建数据目录 + is_load: 是否自动加载现有配置 + """ + # 设置数据目录,确保目录存在 + if data_dir is None: + data_dir = ToolFile(os.path.abspath('./')) + + self.data_dir: ToolFile = data_dir if isinstance(data_dir, ToolFile) else ToolFile(str(data_dir)) + + if not self.data_dir.IsDir(): + self.data_dir.BackToParentDir() + + if not self.data_dir.Exists(): + if is_try_create_data_dir: + self.data_dir.MustExistsPath() + else: + raise FileNotFoundError(f"Can't find data dir: {self.data_dir.GetDir()}") + + # 检查配置文件,不存在则生成空配置 + self._data_pair: Dict[str, Any] = {} + self._const_config_file = ConstConfigFile + config_file = self.ConfigFile + + if not config_file.Exists(): + GenerateEmptyConfigJson(config_file) + elif is_load: + self.LoadProperties() + + def __del__(self): + pass + + # 文件管理 + def GetConfigFile(self) -> ToolFile: + """获取配置文件对象""" + return self.data_dir | self._const_config_file + + @property + def ConfigFile(self) -> ToolFile: + """获取配置文件对象(属性形式)""" + return self.GetConfigFile() + + def GetFile(self, path: str, is_must_exist: bool = False) -> ToolFile: + """获取数据目录下的文件""" + result = self.data_dir | path + if is_must_exist and not result.Exists(): + result.MustExistsPath() + return result + + def CreateFile(self, path: str) -> bool: + """创建文件""" + result = self.data_dir | path + if result.Exists(): + return False + if not result.GetParentDir().Exists(): + return False + result.Create() + return True + + def EraseFile(self, path: str) -> bool: + """清空文件内容""" + result = self.data_dir | path + if result.Exists(): + try: + result.Remove() + result.Create() + return True + except: + pass + return False + + def RemoveFile(self, path: str) -> bool: + """删除文件""" + result = self.data_dir | path + if result.Exists(): + try: + result.Remove() + return True + except: + pass + return False + + # 配置数据操作 - 支持迭代器 + def __setitem__(self, key: str, value: Any) -> Any: + """索引器设置配置项""" + self._data_pair[key] = value + return value + + def __getitem__(self, key: str) -> Any: + """索引器获取配置项""" + return self._data_pair[key] + + def __contains__(self, key: str) -> bool: + """检查键是否存在""" + return key in self._data_pair + + def __delitem__(self, key: str): + """删除配置项""" + del self._data_pair[key] + + def __iter__(self): + """迭代器支持""" + return iter(self._data_pair.items()) + + def __len__(self) -> int: + """获取配置项数量""" + return len(self._data_pair) + + def Contains(self, key: str) -> bool: + """检查键是否存在""" + return key in self._data_pair + + def Remove(self, key: str) -> bool: + """删除配置项""" + if key in self._data_pair: + del self._data_pair[key] + return True + return False + + def DataSize(self) -> int: + """获取配置项数量""" + return len(self._data_pair) + + # 持久化 + def SaveProperties(self) -> 'GlobalConfig': + """保存配置到文件""" + config = self.ConfigFile + config.SaveAsJson({ + "properties": self._data_pair + }) + return self + + def LoadProperties(self) -> 'GlobalConfig': + """从文件加载配置""" + config = self.ConfigFile + if not config.Exists(): + self._data_pair = {} + else: + data = config.LoadAsJson() + if "properties" in data: + self._data_pair = data["properties"] + else: + raise ValueError("Can't find properties in config file") + return self + + # 日志系统 + def GetLogFile(self) -> ToolFile: + """获取日志文件对象""" + return self.GetFile(self.ConfigFile.GetFilename(True) + "_log.txt", True) + + @property + def LogFile(self) -> ToolFile: + """获取日志文件对象(属性形式)""" + return self.GetLogFile() + + def DefaultLogger(self, message: str): + """默认日志输出器""" + print(message) + + def Log(self, message_type: str, message: Union[str, Any], logger: Optional[Callable[[str], None]] = None) -> 'GlobalConfig': + """记录日志""" + str_message_type = str(message_type) + # 使用String中的工具函数自动调整消息类型的对齐宽度 + aligned_message_type = FillString(str_message_type, max_length=len("Property not found"), side="center") + what = f"[{Nowf()}] {aligned_message_type} : {str(message)}" + + if logger is None: + logger = self.DefaultLogger + + logger(what) + + # 写入日志文件 + log = self.GetLogFile() + # 读取现有内容并追加新内容 + try: + existing_content = log.LoadAsText() + except: + existing_content = "" + log.SaveAsText(existing_content + what + '\n') + return self + + def LogPropertyNotFound(self, message: str, logger: Optional[Callable[[str], None]] = None, default: Any = None) -> 'GlobalConfig': + """记录属性未找到的日志""" + if default is not None: + message = f"{message} (default = {default})" + self.Log("Property not found", message, logger) + return self + + def LogMessageOfPleaseCompleteConfiguration(self) -> 'GlobalConfig': + """记录配置提示信息""" + self.Log("Error", "Please complete configuration") + return self + + # 配置查找 + def FindItem(self, key: str, default: Any = None) -> Any: + """查找配置项,支持默认值""" + if key in self._data_pair: + return self._data_pair[key] + else: + self.LogPropertyNotFound(key, default=default) + return default + + +class ProjectConfig(GlobalConfig): + """项目级配置管理类,继承自GlobalConfig""" + + # 静态配置 + ProjectConfigFileFocus = "Assets/" + + @staticmethod + def InitExtensionEnv(): + """初始化项目扩展环境""" + ProjectConfig.ProjectConfigFileFocus = "Assets/" + + @staticmethod + def SetProjectConfigFileFocus(path: str): + """设置项目配置焦点目录""" + ProjectConfig.ProjectConfigFileFocus = path + + @staticmethod + def GetProjectConfigFileFocus() -> str: + """获取项目配置焦点目录""" + return ProjectConfig.ProjectConfigFileFocus + + def __init__(self, is_load: bool = True): + """使用默认项目目录构造""" + super().__init__(ProjectConfig.GetProjectConfigFileFocus(), is_try_create_data_dir=True, is_load=is_load)