Files
Convention-Python/Convention/Runtime/GlobalConfig.py
2025-09-26 10:34:34 +08:00

265 lines
8.2 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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._data_find: 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,
"find": self._data_find
})
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)
self._data_find[key] = 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)