mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-03-23 03:04:29 +08:00
Compare commits
112 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cf486cbeff | ||
|
|
8d656b90a7 | ||
|
|
fc386fb4bc | ||
|
|
bbf1dc8d0c | ||
|
|
b95c65a30e | ||
|
|
9ab09cf47b | ||
|
|
63b1d71a0e | ||
|
|
cdc49c319a | ||
|
|
d94d8deb29 | ||
|
|
49609d3821 | ||
|
|
003fe42ad8 | ||
|
|
a42ec0c282 | ||
|
|
884249649d | ||
|
|
d582dffe40 | ||
|
|
63a6c2e6f0 | ||
|
|
f3d45169cd | ||
|
|
86645d34cb | ||
|
|
ab04f0ace7 | ||
|
|
51492b1dcd | ||
|
|
4caa3c0d71 | ||
|
|
fca3808657 | ||
|
|
5996ecf5f3 | ||
|
|
53edd13f8f | ||
|
|
0442fec2d1 | ||
|
|
2001eddbff | ||
|
|
3130a3bab2 | ||
|
|
ba4ee24ce7 | ||
|
|
dfae4ba207 | ||
|
|
ccb51791a3 | ||
|
|
55234c4d70 | ||
|
|
108bcbf27e | ||
|
|
51393c30ee | ||
|
|
589f9f7d63 | ||
|
|
ba8369c8b3 | ||
|
|
9ca28a44d8 | ||
|
|
0c5c9dceae | ||
|
|
d7e7d3cc7f | ||
|
|
b5c67850ce | ||
|
|
1f680d2822 | ||
|
|
075d397a4c | ||
|
|
5fb96761a3 | ||
|
|
e49713a842 | ||
|
|
aee13c3c1d | ||
|
|
05c4f06717 | ||
|
|
2accbf4bdf | ||
|
|
60068aff4f | ||
|
|
9c69c4ec00 | ||
|
|
65b949b62f | ||
|
|
4afa856fdc | ||
|
|
27858df94e | ||
|
|
1c2e68fc5a | ||
|
|
3d8e19b5e2 | ||
|
|
ef05713bf2 | ||
|
|
e022a10bd5 | ||
|
|
c82a15f8bc | ||
|
|
2d89efa4b7 | ||
|
|
597d4dfeda | ||
|
|
f3deb299ac | ||
|
|
fc2f9ebf1a | ||
|
|
0640a06e44 | ||
|
|
94f75bfa03 | ||
|
|
10640f1c73 | ||
|
|
cb0d0682b0 | ||
|
|
8b5efc69ec | ||
|
|
54103c21a4 | ||
|
|
7aa009ab06 | ||
|
|
90bfa7200a | ||
|
|
e4cc0c7943 | ||
|
|
0b7d5c8f0c | ||
|
|
920a2c519e | ||
|
|
f48a8db094 | ||
|
|
4362989056 | ||
|
|
1c30149ebd | ||
|
|
4156839bd9 | ||
|
|
d038b67e29 | ||
|
|
820cdcf0fa | ||
|
|
b01867b231 | ||
|
|
494c341c08 | ||
|
|
9c2e63f0e1 | ||
|
|
378d7afb23 | ||
|
|
00a687168f | ||
|
|
b6c13088cd | ||
|
|
ea79df232b | ||
|
|
ffda10be86 | ||
|
|
b37873a67c | ||
|
|
11c7bc1457 | ||
|
|
c6024bf94a | ||
|
|
248a29b4df | ||
|
|
1f0eb55288 | ||
|
|
caeb1ab80f | ||
|
|
4750910675 | ||
|
|
43b88e7573 | ||
|
|
8e4e794661 | ||
|
|
52f95c7e5f | ||
|
|
8ea462de28 | ||
|
|
95de78efae | ||
|
|
aeed1f903c | ||
|
|
027a214479 | ||
|
|
fb14d7122c | ||
|
|
53b04c12f0 | ||
|
|
f5d1985a59 | ||
|
|
05d7557fa1 | ||
|
|
f771b7dbef | ||
|
|
f35c9309f3 | ||
|
|
5c5525e3e9 | ||
|
|
ac2a9759e1 | ||
|
|
4257d58f86 | ||
|
|
bca92e52a3 | ||
|
|
af76e0ab0b | ||
|
|
23f186d395 | ||
|
|
25f7779b4e | ||
|
|
1b9e81bbdb |
62
.ai/environment/tools.ai.yaml
Normal file
62
.ai/environment/tools.ai.yaml
Normal file
@ -0,0 +1,62 @@
|
||||
schema_version: 1
|
||||
generated_at_utc: "2026-03-21T04:47:58Z"
|
||||
generated_from: ".ai/environment/tools.raw.yaml"
|
||||
generator: "scripts/generate-ai-environment.py"
|
||||
platform:
|
||||
family: "wsl-linux"
|
||||
os: "Linux"
|
||||
distro: "Ubuntu 24.04.4 LTS"
|
||||
shell: "bash"
|
||||
capabilities:
|
||||
dotnet: true
|
||||
python: true
|
||||
node: true
|
||||
bun: true
|
||||
docker: true
|
||||
fast_search: true
|
||||
json_cli: true
|
||||
tool_selection:
|
||||
search:
|
||||
preferred: "rg"
|
||||
fallback: "grep"
|
||||
use_for: "Repository text search."
|
||||
json:
|
||||
preferred: "jq"
|
||||
fallback: "python3"
|
||||
use_for: "Inspecting or transforming JSON command output."
|
||||
shell:
|
||||
preferred: "bash"
|
||||
fallback: "sh"
|
||||
use_for: "Repository shell scripts and command execution."
|
||||
scripting:
|
||||
preferred: "python3"
|
||||
fallback: "bash"
|
||||
use_for: "Non-trivial local automation and helper scripts."
|
||||
docs_package_manager:
|
||||
preferred: "bun"
|
||||
fallback: "npm"
|
||||
use_for: "Installing and previewing the docs site."
|
||||
build_and_test:
|
||||
preferred: "dotnet"
|
||||
fallback: "unavailable"
|
||||
use_for: "Build, test, restore, and solution validation."
|
||||
python:
|
||||
available: true
|
||||
helper_packages:
|
||||
requests: true
|
||||
rich: true
|
||||
openai: false
|
||||
tiktoken: false
|
||||
pydantic: false
|
||||
pytest: false
|
||||
preferences:
|
||||
prefer_project_listed_tools: true
|
||||
prefer_python_for_non_trivial_automation: true
|
||||
avoid_unlisted_system_tools: true
|
||||
rules:
|
||||
- "Use rg instead of grep for repository search when rg is available."
|
||||
- "Use jq for JSON inspection; fall back to python3 if jq is unavailable."
|
||||
- "Prefer python3 over complex bash for non-trivial scripting when python3 is available."
|
||||
- "Use bun for docs preview workflows when bun is available; otherwise fall back to npm."
|
||||
- "Use dotnet for repository build and test workflows."
|
||||
- "Do not assume unrelated system tools are part of the supported project environment."
|
||||
89
.ai/environment/tools.raw.yaml
Normal file
89
.ai/environment/tools.raw.yaml
Normal file
@ -0,0 +1,89 @@
|
||||
schema_version: 1
|
||||
generated_at_utc: "2026-03-21T04:47:28Z"
|
||||
generator: "scripts/collect-dev-environment.sh"
|
||||
|
||||
platform:
|
||||
os: "Linux"
|
||||
distro: "Ubuntu 24.04.4 LTS"
|
||||
version: "24.04"
|
||||
kernel: "5.15.167.4-microsoft-standard-WSL2"
|
||||
wsl: true
|
||||
wsl_version: "2.4.13"
|
||||
shell: "bash"
|
||||
|
||||
required_runtimes:
|
||||
dotnet:
|
||||
installed: true
|
||||
version: "10.0.104"
|
||||
path: "/usr/bin/dotnet"
|
||||
purpose: "Builds and tests the GFramework solution."
|
||||
python3:
|
||||
installed: true
|
||||
version: "Python 3.12.3"
|
||||
path: "/usr/bin/python3"
|
||||
purpose: "Runs local automation and environment collection scripts."
|
||||
node:
|
||||
installed: true
|
||||
version: "v20.20.1"
|
||||
path: "/usr/bin/node"
|
||||
purpose: "Provides the JavaScript runtime used by docs tooling."
|
||||
bun:
|
||||
installed: true
|
||||
version: "1.3.10"
|
||||
path: "/root/.bun/bin/bun"
|
||||
purpose: "Installs and previews the VitePress documentation site."
|
||||
|
||||
required_tools:
|
||||
git:
|
||||
installed: true
|
||||
version: "git version 2.43.0"
|
||||
path: "/usr/bin/git"
|
||||
purpose: "Source control and patch review."
|
||||
bash:
|
||||
installed: true
|
||||
version: "GNU bash, version 5.2.21(1)-release (x86_64-pc-linux-gnu)"
|
||||
path: "/usr/bin/bash"
|
||||
purpose: "Executes repository scripts and shell automation."
|
||||
rg:
|
||||
installed: true
|
||||
version: "ripgrep 15.1.0 (rev af60c2de9d)"
|
||||
path: "/root/.bun/install/global/node_modules/@openai/codex-linux-x64/vendor/x86_64-unknown-linux-musl/path/rg"
|
||||
purpose: "Fast text search across the repository."
|
||||
jq:
|
||||
installed: true
|
||||
version: "jq-1.7"
|
||||
path: "/usr/bin/jq"
|
||||
purpose: "Inspecting and transforming JSON outputs."
|
||||
|
||||
project_tools:
|
||||
docker:
|
||||
installed: true
|
||||
version: "Docker version 29.2.1, build a5c7197"
|
||||
path: "/usr/bin/docker"
|
||||
purpose: "Runs MegaLinter and other containerized validation tools."
|
||||
|
||||
python_packages:
|
||||
requests:
|
||||
installed: true
|
||||
version: "2.31.0"
|
||||
purpose: "Simple HTTP calls in local helper scripts."
|
||||
rich:
|
||||
installed: true
|
||||
version: "13.7.1"
|
||||
purpose: "Readable CLI output for local Python helpers."
|
||||
openai:
|
||||
installed: false
|
||||
version: "not-installed"
|
||||
purpose: "Optional scripted access to OpenAI APIs."
|
||||
tiktoken:
|
||||
installed: false
|
||||
version: "not-installed"
|
||||
purpose: "Optional token counting for prompt and context inspection."
|
||||
pydantic:
|
||||
installed: false
|
||||
version: "not-installed"
|
||||
purpose: "Optional typed config and schema validation for helper scripts."
|
||||
pytest:
|
||||
installed: false
|
||||
version: "not-installed"
|
||||
purpose: "Optional lightweight testing for Python helper scripts."
|
||||
58
.github/workflows/ci.yml
vendored
58
.github/workflows/ci.yml
vendored
@ -13,8 +13,9 @@ permissions:
|
||||
security-events: write
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: Build and Test
|
||||
# 代码质量检查 job(并行执行,不阻塞构建)
|
||||
code-quality:
|
||||
name: Code Quality & Security
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
@ -23,6 +24,11 @@ jobs:
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
# 校验C#命名空间与源码目录是否符合命名规范
|
||||
- name: Validate C# naming
|
||||
run: bash scripts/validate-csharp-naming.sh
|
||||
|
||||
# 缓存MegaLinter
|
||||
- name: Cache MegaLinter
|
||||
uses: actions/cache@v5
|
||||
@ -31,8 +37,7 @@ jobs:
|
||||
key: ${{ runner.os }}-megalinter-v9
|
||||
restore-keys: |
|
||||
${{ runner.os }}-megalinter-
|
||||
|
||||
|
||||
|
||||
# MegaLinter扫描步骤
|
||||
# 执行代码质量检查和安全扫描,生成SARIF格式报告
|
||||
- name: MegaLinter
|
||||
@ -41,11 +46,13 @@ jobs:
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
FAIL_ON_ERROR: ${{ github.ref == 'refs/heads/main' }}
|
||||
|
||||
# 上传SARIF格式的安全和代码质量问题报告到GitHub安全中心
|
||||
- name: Upload SARIF
|
||||
uses: github/codeql-action/upload-sarif@v4
|
||||
with:
|
||||
sarif_file: megalinter-reports/sarif
|
||||
|
||||
# 缓存TruffleHog
|
||||
- name: Cache TruffleHog
|
||||
uses: actions/cache@v5
|
||||
@ -57,7 +64,7 @@ jobs:
|
||||
# 使用 TruffleHog 工具扫描代码库中的敏感信息泄露,如API密钥、密码等
|
||||
# 该步骤会比较基础分支和当前提交之间的差异,检测新增内容中是否包含敏感数据
|
||||
- name: TruffleHog OSS
|
||||
uses: trufflesecurity/trufflehog@v3.93.7
|
||||
uses: trufflesecurity/trufflehog@v3.93.8
|
||||
with:
|
||||
# 扫描路径,. 表示扫描整个仓库
|
||||
path: .
|
||||
@ -65,6 +72,18 @@ jobs:
|
||||
base: ${{ github.event.before }}
|
||||
# 当前提交哈希,作为扫描的目标版本
|
||||
head: ${{ github.sha }}
|
||||
|
||||
# 构建和测试 job(并行执行)
|
||||
build-and-test:
|
||||
name: Build and Test
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
# 检出源代码
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
# 安装和配置.NET SDK版本
|
||||
- name: Setup .NET 8
|
||||
@ -110,21 +129,36 @@ jobs:
|
||||
run: dotnet build -c Release --no-restore
|
||||
|
||||
# 运行单元测试,输出TRX格式结果到TestResults目录
|
||||
- name: Test - Core
|
||||
# 在同一个 step 中并发执行所有测试以加快速度
|
||||
- name: Test All Projects
|
||||
run: |
|
||||
dotnet test GFramework.Core.Tests \
|
||||
-c Release \
|
||||
--no-build \
|
||||
--logger "trx;LogFileName=core-$RANDOM.trx" \
|
||||
--results-directory TestResults
|
||||
|
||||
- name: Test - SourceGenerators
|
||||
run: |
|
||||
--results-directory TestResults &
|
||||
|
||||
dotnet test GFramework.Game.Tests \
|
||||
-c Release \
|
||||
--no-build \
|
||||
--logger "trx;LogFileName=game-$RANDOM.trx" \
|
||||
--results-directory TestResults &
|
||||
|
||||
dotnet test GFramework.SourceGenerators.Tests \
|
||||
-c Release \
|
||||
--no-build \
|
||||
--logger "trx;LogFileName=sg-$RANDOM.trx" \
|
||||
--results-directory TestResults
|
||||
--results-directory TestResults &
|
||||
|
||||
dotnet test GFramework.Ecs.Arch.Tests \
|
||||
-c Release \
|
||||
--no-build \
|
||||
--logger "trx;LogFileName=ecs-arch-$RANDOM.trx" \
|
||||
--results-directory TestResults &
|
||||
|
||||
# 等待所有后台测试完成
|
||||
wait
|
||||
|
||||
- name: Generate CTRF report
|
||||
run: |
|
||||
mkdir -p ctrf
|
||||
@ -164,4 +198,4 @@ jobs:
|
||||
fetch-previous-results: true
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
if: always()
|
||||
if: always()
|
||||
|
||||
5
.gitignore
vendored
5
.gitignore
vendored
@ -11,4 +11,7 @@ opencode.json
|
||||
.claude/settings.json
|
||||
.omc/
|
||||
docs/.omc/
|
||||
docs/.vitepress/cache/
|
||||
docs/.vitepress/cache/
|
||||
local-plan/
|
||||
# tool
|
||||
.venv/
|
||||
220
AGENTS.md
Normal file
220
AGENTS.md
Normal file
@ -0,0 +1,220 @@
|
||||
# AGENTS.md
|
||||
|
||||
This document is the single source of truth for coding behavior in this repository.
|
||||
|
||||
All AI agents and contributors must follow these rules when writing, reviewing, or modifying code in `GFramework`.
|
||||
|
||||
## Environment Capability Inventory
|
||||
|
||||
- Before choosing runtimes or CLI tools, read `@.ai/environment/tools.ai.yaml`.
|
||||
- Use `@.ai/environment/tools.raw.yaml` only when you need the full collected facts behind the AI-facing hints.
|
||||
- Prefer the project-relevant tools listed there instead of assuming every installed system tool is fair game.
|
||||
- If the real environment differs from the inventory, use the project-relevant installed tool and report the mismatch.
|
||||
|
||||
## Commenting Rules (MUST)
|
||||
|
||||
All generated or modified code MUST include clear and meaningful comments where required by the rules below.
|
||||
|
||||
### XML Documentation (Required)
|
||||
|
||||
- All public, protected, and internal types and members MUST include XML documentation comments (`///`).
|
||||
- Use `<summary>`, `<param>`, `<returns>`, `<exception>`, and `<remarks>` where applicable.
|
||||
- Comments must explain intent, contract, and usage constraints instead of restating syntax.
|
||||
- If a member participates in lifecycle, threading, registration, or disposal behavior, document that behavior
|
||||
explicitly.
|
||||
|
||||
### Inline Comments
|
||||
|
||||
- Add inline comments for:
|
||||
- Non-trivial logic
|
||||
- Concurrency or threading behavior
|
||||
- Performance-sensitive paths
|
||||
- Workarounds, compatibility constraints, or edge cases
|
||||
- Registration order, lifecycle sequencing, or generated code assumptions
|
||||
- Avoid obvious comments such as `// increment i`.
|
||||
|
||||
### Architecture-Level Comments
|
||||
|
||||
- Core framework components such as Architecture, Module, System, Context, Registry, Service Module, and Lifecycle types
|
||||
MUST include high-level explanations of:
|
||||
- Responsibilities
|
||||
- Lifecycle
|
||||
- Interaction with other components
|
||||
- Why the abstraction exists
|
||||
- When to use it instead of alternatives
|
||||
|
||||
### Source Generator Comments
|
||||
|
||||
- Generated logic and generator pipelines MUST explain:
|
||||
- What is generated
|
||||
- Why it is generated
|
||||
- The semantic assumptions the generator relies on
|
||||
- Any diagnostics or fallback behavior
|
||||
|
||||
### Complex Logic Requirement
|
||||
|
||||
- Methods with non-trivial logic MUST document:
|
||||
- The core idea
|
||||
- Key decisions
|
||||
- Edge case handling, if any
|
||||
|
||||
### Quality Rules
|
||||
|
||||
- Comments MUST NOT be trivial, redundant, or misleading.
|
||||
- Prefer explaining `why` and `when`, not just `what`.
|
||||
- Code should remain understandable without requiring external context.
|
||||
- Prefer slightly more explanation over too little for framework code.
|
||||
|
||||
### Enforcement
|
||||
|
||||
- Missing required documentation is a coding standards violation.
|
||||
- Code that does not meet the documentation rules is considered incomplete.
|
||||
|
||||
## Code Style
|
||||
|
||||
### Language and Project Settings
|
||||
|
||||
- Follow the repository defaults:
|
||||
- `ImplicitUsings` disabled
|
||||
- `Nullable` enabled
|
||||
- `GenerateDocumentationFile` enabled for shipped libraries
|
||||
- `LangVersion` is generally `preview` in the main libraries and abstractions
|
||||
- Do not rely on implicit imports. Declare every required `using` explicitly.
|
||||
- Write null-safe code that respects nullable annotations instead of suppressing warnings by default.
|
||||
|
||||
### Naming and Structure
|
||||
|
||||
- Use the namespace pattern `GFramework.{Module}.{Feature}` with PascalCase segments.
|
||||
- Follow standard C# naming:
|
||||
- Types, methods, properties, events, and constants: PascalCase
|
||||
- Interfaces: `I` prefix
|
||||
- Parameters and locals: camelCase
|
||||
- Private fields: `_camelCase`
|
||||
- Keep abstractions projects free of implementation details and engine-specific dependencies.
|
||||
- Preserve existing module boundaries. Do not introduce new cross-module dependencies without clear architectural need.
|
||||
|
||||
### Formatting
|
||||
|
||||
- Use 4 spaces for indentation. Do not use tabs.
|
||||
- Use Allman braces.
|
||||
- Keep `using` directives at the top of the file and sort them consistently.
|
||||
- Separate logical blocks with blank lines when it improves readability.
|
||||
- Prefer one primary type per file unless the surrounding project already uses a different local pattern.
|
||||
- Keep line length readable. Around 120 characters is the preferred upper bound.
|
||||
|
||||
### C# Conventions
|
||||
|
||||
- Prefer explicit, readable code over clever shorthand in framework internals.
|
||||
- Match existing async patterns and naming conventions (`Async` suffix for asynchronous methods).
|
||||
- Avoid hidden side effects in property getters, constructors, and registration helpers.
|
||||
- Preserve deterministic behavior in registries, lifecycle orchestration, and generated outputs.
|
||||
- When adding analyzers or suppressions, keep them minimal and justify them in code comments if the reason is not
|
||||
obvious.
|
||||
|
||||
### Analyzer and Validation Expectations
|
||||
|
||||
- The repository uses `Meziantou.Analyzer`; treat analyzer feedback as part of the coding standard.
|
||||
- Naming must remain compatible with `scripts/validate-csharp-naming.sh`.
|
||||
|
||||
## Testing Requirements
|
||||
|
||||
### Required Coverage
|
||||
|
||||
- Every non-trivial feature, bug fix, or behavior change MUST include tests or an explicit justification for why a test
|
||||
is not practical.
|
||||
- Public API changes must be covered by unit or integration tests.
|
||||
- Regression fixes should include a test that fails before the fix and passes after it.
|
||||
|
||||
### Test Organization
|
||||
|
||||
- Mirror the source structure in test projects whenever practical.
|
||||
- Reuse existing architecture test infrastructure when relevant:
|
||||
- `ArchitectureTestsBase<T>`
|
||||
- `SyncTestArchitecture`
|
||||
- `AsyncTestArchitecture`
|
||||
- Keep tests focused on observable behavior, not implementation trivia.
|
||||
|
||||
### Source Generator Tests
|
||||
|
||||
- Source generator changes MUST be covered by generator tests.
|
||||
- Preserve snapshot-based verification patterns already used in the repository.
|
||||
- When generator behavior changes intentionally, update snapshots together with the implementation.
|
||||
|
||||
### Validation Commands
|
||||
|
||||
Use the smallest command set that proves the change, then expand if the change is cross-cutting.
|
||||
|
||||
```bash
|
||||
# Build the full solution
|
||||
dotnet build GFramework.sln -c Release
|
||||
|
||||
# Run all tests
|
||||
dotnet test GFramework.sln -c Release
|
||||
|
||||
# Run a single test project
|
||||
dotnet test GFramework.Core.Tests -c Release
|
||||
dotnet test GFramework.Game.Tests -c Release
|
||||
dotnet test GFramework.SourceGenerators.Tests -c Release
|
||||
dotnet test GFramework.Ecs.Arch.Tests -c Release
|
||||
|
||||
# Run a single NUnit test or test group
|
||||
dotnet test GFramework.Core.Tests -c Release --filter "FullyQualifiedName~CommandExecutorTests.Execute"
|
||||
|
||||
# Validate naming rules used by CI
|
||||
bash scripts/validate-csharp-naming.sh
|
||||
```
|
||||
|
||||
### Test Execution Expectations
|
||||
|
||||
- Run targeted tests for the code you changed whenever possible.
|
||||
- Run broader solution-level validation for changes that touch shared abstractions, lifecycle behavior, source
|
||||
generators, or dependency wiring.
|
||||
- Do not claim completion if required tests were skipped; state what was not run and why.
|
||||
|
||||
## Security Rules
|
||||
|
||||
- Validate external or user-controlled input before it reaches file system, serialization, reflection, code generation,
|
||||
or process boundaries.
|
||||
- Do not build command strings, file paths, type names, or generated code from untrusted input without strict validation
|
||||
or allow-listing.
|
||||
- Avoid logging secrets, tokens, credentials, or machine-specific sensitive data.
|
||||
- Keep source generators deterministic and free of hidden environment or network dependencies.
|
||||
- Prefer least-privilege behavior for file, process, and environment access.
|
||||
- Do not introduce unsafe deserialization, broad reflection-based activation, or dynamic code execution unless it is
|
||||
explicitly required and tightly constrained.
|
||||
- When adding caching, pooling, or shared mutable state, document thread-safety assumptions and failure modes.
|
||||
- Minimize new package dependencies. Add them only when necessary and keep scope narrow.
|
||||
|
||||
## Documentation Rules
|
||||
|
||||
### Code Documentation
|
||||
|
||||
- Any change to public API, lifecycle semantics, module behavior, or extension points MUST update the related XML docs.
|
||||
- If a framework abstraction changes meaning or intended usage, update the explanatory comments in code as part of the
|
||||
same change.
|
||||
|
||||
### Repository Documentation
|
||||
|
||||
- Update the relevant `README.md` or `docs/` page when behavior, setup steps, architecture guidance, or user-facing
|
||||
examples change.
|
||||
- The main documentation site lives under `docs/`, with Chinese content under `docs/zh-CN/`.
|
||||
- Keep code samples, package names, and command examples aligned with the current repository state.
|
||||
- Prefer documenting behavior and design intent, not only API surface.
|
||||
|
||||
### Documentation Preview
|
||||
|
||||
When documentation changes need local preview, use:
|
||||
|
||||
```bash
|
||||
cd docs && bun install && bun run dev
|
||||
```
|
||||
|
||||
## Review Standard
|
||||
|
||||
Before considering work complete, confirm:
|
||||
|
||||
- Required comments and XML docs are present
|
||||
- Code follows repository style and naming rules
|
||||
- Relevant tests were added or updated
|
||||
- Sensitive or unsafe behavior was not introduced
|
||||
- User-facing documentation is updated when needed
|
||||
134
CLAUDE.md
Normal file
134
CLAUDE.md
Normal file
@ -0,0 +1,134 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides project understanding for AI agents working in this repository.
|
||||
|
||||
## Project Overview
|
||||
|
||||
GFramework 是面向游戏开发的模块化 C# 框架,核心能力与引擎解耦。项目灵感参考 QFramework,并在模块边界、工程组织和可扩展性方面持续重构。
|
||||
|
||||
## AI Agent Instructions
|
||||
|
||||
All coding rules are defined in:
|
||||
|
||||
@AGENTS.md
|
||||
|
||||
Follow them strictly.
|
||||
|
||||
## Module Dependency Graph
|
||||
|
||||
```text
|
||||
GFramework (meta package) ─→ Core + Game
|
||||
GFramework.Core ─→ Core.Abstractions
|
||||
GFramework.Game ─→ Game.Abstractions, Core, Core.Abstractions
|
||||
GFramework.Godot ─→ Core, Game, Core.Abstractions, Game.Abstractions
|
||||
GFramework.Ecs.Arch ─→ Ecs.Arch.Abstractions, Core, Core.Abstractions
|
||||
GFramework.SourceGenerators ─→ SourceGenerators.Common, SourceGenerators.Abstractions
|
||||
```
|
||||
|
||||
- **Abstractions projects** (`netstandard2.1`): 只包含接口和契约定义,不承载运行时实现逻辑。
|
||||
- **Core / Game / Ecs.Arch** (`net8.0;net9.0;net10.0`): 平台无关的核心实现层。
|
||||
- **Godot**: Godot 引擎集成层,负责与节点、场景和引擎生命周期对接。
|
||||
- **SourceGenerators** (`netstandard2.1`): Roslyn 增量源码生成器及其公共基础设施。
|
||||
|
||||
## Architecture Pattern
|
||||
|
||||
框架核心采用 `Architecture / Model / System / Utility` 四层结构:
|
||||
|
||||
- **IArchitecture**: 顶层容器,负责生命周期管理、组件注册、模块安装和统一服务访问。
|
||||
- **IContextAware**: 统一上下文访问接口,组件通过 `SetContext(IArchitectureContext)` 获取架构上下文。
|
||||
- **IModel**: 数据与状态层,负责长期状态和业务数据建模。
|
||||
- **ISystem**: 业务逻辑层,负责命令执行、流程编排和规则落地。
|
||||
- **IUtility**: 通用无状态工具层,供其他层复用。
|
||||
|
||||
关键实现位于 `GFramework.Core/Architectures/Architecture.cs`,其职责是作为总协调器串联生命周期、组件注册和模块系统。
|
||||
|
||||
## Architecture Details
|
||||
|
||||
### Lifecycle
|
||||
|
||||
Architecture 负责统一生命周期编排,核心阶段包括:
|
||||
|
||||
- `Init`
|
||||
- `Ready`
|
||||
- `Destroy`
|
||||
|
||||
在实现层中,生命周期被拆分为更细粒度的初始化与销毁阶段,用于保证 Utility、Model、System、服务模块和钩子的顺序一致性。
|
||||
|
||||
### Component Coordination
|
||||
|
||||
框架通过独立组件协作完成架构编排:
|
||||
|
||||
- `ArchitectureLifecycle`: 管理生命周期阶段、阶段转换和生命周期钩子。
|
||||
- `ArchitectureComponentRegistry`: 管理 Model、System、Utility 的注册与解析。
|
||||
- `ArchitectureModules`: 管理模块安装、服务模块接入和扩展点注册。
|
||||
|
||||
这组拆分的目标是降低单个核心类的职责密度,同时保持对外 API 稳定。
|
||||
|
||||
### Context Propagation
|
||||
|
||||
`IArchitectureContext` 和相关 Provider 类型负责在组件之间传播上下文能力,使 Model、System
|
||||
和外部扩展都能通过统一入口访问架构服务,而不直接耦合具体实现细节。
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### CQRS
|
||||
|
||||
命令与查询分离,支持同步与异步执行。Mediator 模式通过源码生成器集成,以减少模板代码并保持调用路径清晰。
|
||||
|
||||
### EventBus
|
||||
|
||||
类型安全事件总线支持事件发布、订阅、优先级、过滤器和弱引用订阅。它是模块之间松耦合通信的核心基础设施之一。
|
||||
|
||||
### BindableProperty
|
||||
|
||||
响应式属性模型通过值变化通知驱动界面或业务层更新,适合表达轻量级状态同步。
|
||||
|
||||
### Coroutine
|
||||
|
||||
帧驱动协程系统基于 `IYieldInstruction` 和调度器抽象,支持等待时间、事件和任务完成等常见模式。
|
||||
|
||||
### IoC
|
||||
|
||||
依赖注入通过 `MicrosoftDiContainer` 对 `Microsoft.Extensions.DependencyInjection` 进行封装,用于统一组件注册和服务解析体验。
|
||||
|
||||
### Service Modules
|
||||
|
||||
`IServiceModule` 模式用于向 Architecture 注册内置服务,例如 EventBus、CommandExecutor、QueryExecutor 等。这一模式承担“基础设施能力装配”的职责。
|
||||
|
||||
## Source Generators
|
||||
|
||||
当前仓库包含多类 Roslyn 增量源码生成器:
|
||||
|
||||
- `LoggerGenerator` (`[Log]`): 自动生成日志字段和日志辅助方法。
|
||||
- `PriorityGenerator` (`[Priority]`): 生成优先级比较相关实现。
|
||||
- `EnumExtensionsGenerator` (`[GenerateEnumExtensions]`): 生成枚举扩展能力。
|
||||
- `ContextAwareGenerator` (`[ContextAware]`): 自动实现 `IContextAware` 相关样板逻辑。
|
||||
|
||||
这些生成器的目标是减少重复代码,同时保持框架层 API 的一致性与可维护性。
|
||||
|
||||
## Module Structure
|
||||
|
||||
仓库以“抽象层 + 实现层 + 集成层 + 生成器层”的方式组织:
|
||||
|
||||
- `GFramework.Core.Abstractions` / `GFramework.Game.Abstractions`: 约束接口和公共契约。
|
||||
- `GFramework.Core` / `GFramework.Game`: 提供平台无关实现。
|
||||
- `GFramework.Godot`: 提供与 Godot 运行时集成的适配实现。
|
||||
- `GFramework.Ecs.Arch`: 提供 ECS Architecture 相关扩展。
|
||||
- `GFramework.SourceGenerators` 及相关 Abstractions/Common: 提供代码生成能力。
|
||||
|
||||
这种结构的核心设计目标是让抽象稳定、实现可替换、引擎集成隔离、生成器能力可独立演进。
|
||||
|
||||
## Documentation Structure
|
||||
|
||||
项目文档位于 `docs/`,中文内容位于 `docs/zh-CN/`。文档内容覆盖:
|
||||
|
||||
- 入门与安装
|
||||
- Core / Game / Godot / ECS 各模块能力
|
||||
- Source Generator 使用说明
|
||||
- 教程、最佳实践与故障排查
|
||||
|
||||
阅读顺序通常建议先看根目录 `README.md` 和各子模块 `README.md`,再进入 `docs/` 查阅专题说明。
|
||||
|
||||
## Design Intent
|
||||
|
||||
GFramework 的设计重点不是把所有能力堆进单一核心类,而是通过清晰的模块边界、可组合的服务注册方式、稳定的抽象契约以及适度自动化的源码生成,构建一个适合长期演进的游戏开发基础框架。
|
||||
@ -0,0 +1,42 @@
|
||||
using System.Collections.Concurrent;
|
||||
|
||||
namespace GFramework.Core.Abstractions.Architectures;
|
||||
|
||||
/// <summary>
|
||||
/// 架构模块注册表 - 用于外部模块的自动注册
|
||||
/// </summary>
|
||||
public static class ArchitectureModuleRegistry
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, Func<IServiceModule>> Factories = new(StringComparer.Ordinal);
|
||||
|
||||
/// <summary>
|
||||
/// 注册模块工厂(幂等操作,相同模块名只会注册一次)
|
||||
/// </summary>
|
||||
/// <param name="factory">模块工厂函数</param>
|
||||
public static void Register(Func<IServiceModule> factory)
|
||||
{
|
||||
// 创建临时实例以获取模块名(用于幂等性检查)
|
||||
var tempModule = factory();
|
||||
var moduleName = tempModule.ModuleName;
|
||||
|
||||
// 幂等注册:相同模块名只注册一次
|
||||
Factories.TryAdd(moduleName, factory);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建所有已注册的模块实例
|
||||
/// </summary>
|
||||
/// <returns>模块实例集合</returns>
|
||||
public static IEnumerable<IServiceModule> CreateModules()
|
||||
{
|
||||
return Factories.Values.Select(f => f());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清空注册表(主要用于测试)
|
||||
/// </summary>
|
||||
public static void Clear()
|
||||
{
|
||||
Factories.Clear();
|
||||
}
|
||||
}
|
||||
@ -1,10 +1,10 @@
|
||||
using GFramework.Core.Abstractions.lifecycle;
|
||||
using GFramework.Core.Abstractions.model;
|
||||
using GFramework.Core.Abstractions.system;
|
||||
using GFramework.Core.Abstractions.utility;
|
||||
using GFramework.Core.Abstractions.Lifecycle;
|
||||
using GFramework.Core.Abstractions.Model;
|
||||
using GFramework.Core.Abstractions.Systems;
|
||||
using GFramework.Core.Abstractions.Utility;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace GFramework.Core.Abstractions.architecture;
|
||||
namespace GFramework.Core.Abstractions.Architectures;
|
||||
|
||||
/// <summary>
|
||||
/// 架构接口,专注于生命周期管理,包括系统、模型、工具的注册和获取
|
||||
@ -1,6 +1,6 @@
|
||||
using GFramework.Core.Abstractions.properties;
|
||||
using GFramework.Core.Abstractions.Properties;
|
||||
|
||||
namespace GFramework.Core.Abstractions.architecture;
|
||||
namespace GFramework.Core.Abstractions.Architectures;
|
||||
|
||||
/// <summary>
|
||||
/// 定义架构配置的接口,提供日志工厂、日志级别和架构选项的配置功能
|
||||
@ -1,14 +1,14 @@
|
||||
using GFramework.Core.Abstractions.command;
|
||||
using GFramework.Core.Abstractions.environment;
|
||||
using GFramework.Core.Abstractions.events;
|
||||
using GFramework.Core.Abstractions.model;
|
||||
using GFramework.Core.Abstractions.query;
|
||||
using GFramework.Core.Abstractions.system;
|
||||
using GFramework.Core.Abstractions.utility;
|
||||
using GFramework.Core.Abstractions.Command;
|
||||
using GFramework.Core.Abstractions.Environment;
|
||||
using GFramework.Core.Abstractions.Events;
|
||||
using GFramework.Core.Abstractions.Model;
|
||||
using GFramework.Core.Abstractions.Query;
|
||||
using GFramework.Core.Abstractions.Systems;
|
||||
using GFramework.Core.Abstractions.Utility;
|
||||
using Mediator;
|
||||
using ICommand = GFramework.Core.Abstractions.command.ICommand;
|
||||
using ICommand = GFramework.Core.Abstractions.Command.ICommand;
|
||||
|
||||
namespace GFramework.Core.Abstractions.architecture;
|
||||
namespace GFramework.Core.Abstractions.Architectures;
|
||||
|
||||
/// <summary>
|
||||
/// 架构上下文接口,提供对系统、模型、工具类的访问以及命令、查询、事件的发送和注册功能
|
||||
@ -19,8 +19,8 @@ public interface IArchitectureContext
|
||||
/// 获取指定类型的服务实例
|
||||
/// </summary>
|
||||
/// <typeparam name="TService">服务类型</typeparam>
|
||||
/// <returns>服务实例,如果不存在则返回null</returns>
|
||||
TService? GetService<TService>() where TService : class;
|
||||
/// <returns>服务实例,如果不存在则抛出异常</returns>
|
||||
TService GetService<TService>() where TService : class;
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定类型的所有服务实例
|
||||
@ -33,8 +33,8 @@ public interface IArchitectureContext
|
||||
/// 获取指定类型的系统实例
|
||||
/// </summary>
|
||||
/// <typeparam name="TSystem">系统类型,必须继承自ISystem接口</typeparam>
|
||||
/// <returns>系统实例,如果不存在则返回null</returns>
|
||||
TSystem? GetSystem<TSystem>() where TSystem : class, ISystem;
|
||||
/// <returns>系统实例,如果不存在则抛出异常</returns>
|
||||
TSystem GetSystem<TSystem>() where TSystem : class, ISystem;
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定类型的所有系统实例
|
||||
@ -47,8 +47,8 @@ public interface IArchitectureContext
|
||||
/// 获取指定类型的模型实例
|
||||
/// </summary>
|
||||
/// <typeparam name="TModel">模型类型,必须继承自IModel接口</typeparam>
|
||||
/// <returns>模型实例,如果不存在则返回null</returns>
|
||||
TModel? GetModel<TModel>() where TModel : class, IModel;
|
||||
/// <returns>模型实例,如果不存在则抛出异常</returns>
|
||||
TModel GetModel<TModel>() where TModel : class, IModel;
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定类型的所有模型实例
|
||||
@ -61,8 +61,8 @@ public interface IArchitectureContext
|
||||
/// 获取指定类型的工具类实例
|
||||
/// </summary>
|
||||
/// <typeparam name="TUtility">工具类类型,必须继承自IUtility接口</typeparam>
|
||||
/// <returns>工具类实例,如果不存在则返回null</returns>
|
||||
TUtility? GetUtility<TUtility>() where TUtility : class, IUtility;
|
||||
/// <returns>工具类实例,如果不存在则抛出异常</returns>
|
||||
TUtility GetUtility<TUtility>() where TUtility : class, IUtility;
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定类型的所有工具类实例
|
||||
@ -115,7 +115,7 @@ public interface IArchitectureContext
|
||||
/// <typeparam name="TResult">命令执行结果类型</typeparam>
|
||||
/// <param name="command">要发送的命令</param>
|
||||
/// <returns>命令执行结果</returns>
|
||||
TResult SendCommand<TResult>(command.ICommand<TResult> command);
|
||||
TResult SendCommand<TResult>(Command.ICommand<TResult> command);
|
||||
|
||||
/// <summary>
|
||||
/// [Mediator] 发送命令的同步版本(不推荐,仅用于兼容性)
|
||||
@ -158,7 +158,7 @@ public interface IArchitectureContext
|
||||
/// <typeparam name="TResult">查询结果类型</typeparam>
|
||||
/// <param name="query">要发送的查询</param>
|
||||
/// <returns>查询结果</returns>
|
||||
TResult SendQuery<TResult>(query.IQuery<TResult> query);
|
||||
TResult SendQuery<TResult>(Query.IQuery<TResult> query);
|
||||
|
||||
/// <summary>
|
||||
/// [Mediator] 发送查询的同步版本(不推荐,仅用于兼容性)
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.Core.Abstractions.architecture;
|
||||
namespace GFramework.Core.Abstractions.Architectures;
|
||||
|
||||
/// <summary>
|
||||
/// 架构上下文提供者接口,用于解耦上下文获取逻辑
|
||||
@ -1,6 +1,6 @@
|
||||
using GFramework.Core.Abstractions.enums;
|
||||
using GFramework.Core.Abstractions.Enums;
|
||||
|
||||
namespace GFramework.Core.Abstractions.architecture;
|
||||
namespace GFramework.Core.Abstractions.Architectures;
|
||||
|
||||
/// <summary>
|
||||
/// 架构生命周期钩子接口,用于在架构的不同生命周期阶段执行自定义逻辑。
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.Core.Abstractions.architecture;
|
||||
namespace GFramework.Core.Abstractions.Architectures;
|
||||
|
||||
/// <summary>
|
||||
/// 架构模块接口,继承自架构生命周期接口。
|
||||
@ -1,6 +1,6 @@
|
||||
using GFramework.Core.Abstractions.enums;
|
||||
using GFramework.Core.Abstractions.Enums;
|
||||
|
||||
namespace GFramework.Core.Abstractions.architecture;
|
||||
namespace GFramework.Core.Abstractions.Architectures;
|
||||
|
||||
/// <summary>
|
||||
/// 架构阶段监听器接口,用于监听和响应架构生命周期中的不同阶段变化。
|
||||
@ -1,10 +1,10 @@
|
||||
using GFramework.Core.Abstractions.command;
|
||||
using GFramework.Core.Abstractions.events;
|
||||
using GFramework.Core.Abstractions.ioc;
|
||||
using GFramework.Core.Abstractions.query;
|
||||
using GFramework.Core.Abstractions.rule;
|
||||
using GFramework.Core.Abstractions.Command;
|
||||
using GFramework.Core.Abstractions.Events;
|
||||
using GFramework.Core.Abstractions.Ioc;
|
||||
using GFramework.Core.Abstractions.Query;
|
||||
using GFramework.Core.Abstractions.Rule;
|
||||
|
||||
namespace GFramework.Core.Abstractions.architecture;
|
||||
namespace GFramework.Core.Abstractions.Architectures;
|
||||
|
||||
/// <summary>
|
||||
/// 架构服务接口,定义了框架核心架构所需的服务组件
|
||||
@ -1,7 +1,7 @@
|
||||
using GFramework.Core.Abstractions.ioc;
|
||||
using GFramework.Core.Abstractions.lifecycle;
|
||||
using GFramework.Core.Abstractions.Ioc;
|
||||
using GFramework.Core.Abstractions.Lifecycle;
|
||||
|
||||
namespace GFramework.Core.Abstractions.architecture;
|
||||
namespace GFramework.Core.Abstractions.Architectures;
|
||||
|
||||
/// <summary>
|
||||
/// 服务模块接口,定义了服务模块的基本契约。
|
||||
@ -1,7 +1,6 @@
|
||||
using GFramework.Core.Abstractions.ioc;
|
||||
using GFramework.Core.Abstractions.properties;
|
||||
using GFramework.Core.Abstractions.Ioc;
|
||||
|
||||
namespace GFramework.Core.Abstractions.architecture;
|
||||
namespace GFramework.Core.Abstractions.Architectures;
|
||||
|
||||
/// <summary>
|
||||
/// 服务模块管理器接口,用于管理架构中的服务模块。
|
||||
@ -18,8 +17,7 @@ public interface IServiceModuleManager
|
||||
/// 注册内置的服务模块。
|
||||
/// </summary>
|
||||
/// <param name="container">IoC容器实例,用于解析依赖。</param>
|
||||
/// <param name="properties">架构属性配置,用于模块初始化。</param>
|
||||
void RegisterBuiltInModules(IIocContainer container, ArchitectureProperties properties);
|
||||
void RegisterBuiltInModules(IIocContainer container);
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有已注册的服务模块。
|
||||
@ -11,7 +11,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
namespace GFramework.Core.Abstractions.bases;
|
||||
namespace GFramework.Core.Abstractions.Bases;
|
||||
|
||||
/// <summary>
|
||||
/// 定义具有键值访问能力的接口契约
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.Core.Abstractions.bases;
|
||||
namespace GFramework.Core.Abstractions.Bases;
|
||||
|
||||
/// <summary>
|
||||
/// 表示键值对的接口,定义了通用的键值对数据结构契约
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.Core.Abstractions.bases;
|
||||
namespace GFramework.Core.Abstractions.Bases;
|
||||
|
||||
/// <summary>
|
||||
/// 定义具有优先级的对象接口。
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.Core.Abstractions.bases;
|
||||
namespace GFramework.Core.Abstractions.Bases;
|
||||
|
||||
/// <summary>
|
||||
/// 预定义的优先级分组常量
|
||||
@ -1,6 +1,6 @@
|
||||
using GFramework.Core.Abstractions.rule;
|
||||
using GFramework.Core.Abstractions.Rule;
|
||||
|
||||
namespace GFramework.Core.Abstractions.command;
|
||||
namespace GFramework.Core.Abstractions.Command;
|
||||
|
||||
/// <summary>
|
||||
/// 表示一个异步命令接口,该命令不返回结果
|
||||
@ -1,6 +1,6 @@
|
||||
using GFramework.Core.Abstractions.rule;
|
||||
using GFramework.Core.Abstractions.Rule;
|
||||
|
||||
namespace GFramework.Core.Abstractions.command;
|
||||
namespace GFramework.Core.Abstractions.Command;
|
||||
|
||||
/// <summary>
|
||||
/// 命令接口,定义了无返回值命令的基本契约
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.Core.Abstractions.command;
|
||||
namespace GFramework.Core.Abstractions.Command;
|
||||
|
||||
/// <summary>
|
||||
/// 定义命令执行器接口,提供同步和异步方式发送并执行命令的方法。
|
||||
@ -0,0 +1,49 @@
|
||||
// Copyright (c) 2025 GeWuYou
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
using GFramework.Core.Abstractions.Utility;
|
||||
|
||||
namespace GFramework.Core.Abstractions.Concurrency;
|
||||
|
||||
/// <summary>
|
||||
/// 异步键锁管理器接口,提供基于键的细粒度锁机制
|
||||
/// </summary>
|
||||
public interface IAsyncKeyLockManager : IUtility, IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// 异步获取指定键的锁(推荐使用)
|
||||
/// </summary>
|
||||
/// <param name="key">锁键</param>
|
||||
/// <param name="cancellationToken">取消令牌</param>
|
||||
/// <returns>锁句柄,使用 await using 自动释放</returns>
|
||||
ValueTask<IAsyncLockHandle> AcquireLockAsync(string key, CancellationToken cancellationToken = default);
|
||||
|
||||
/// <summary>
|
||||
/// 同步获取指定键的锁(兼容性方法)
|
||||
/// </summary>
|
||||
/// <param name="key">锁键</param>
|
||||
/// <returns>锁句柄,使用 using 自动释放</returns>
|
||||
IAsyncLockHandle AcquireLock(string key);
|
||||
|
||||
/// <summary>
|
||||
/// 获取锁管理器的统计信息
|
||||
/// </summary>
|
||||
/// <returns>统计信息快照</returns>
|
||||
LockStatistics GetStatistics();
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前活跃的锁信息(用于调试)
|
||||
/// </summary>
|
||||
/// <returns>键到锁信息的只读字典</returns>
|
||||
IReadOnlyDictionary<string, LockInfo> GetActiveLocks();
|
||||
}
|
||||
30
GFramework.Core.Abstractions/Concurrency/IAsyncLockHandle.cs
Normal file
30
GFramework.Core.Abstractions/Concurrency/IAsyncLockHandle.cs
Normal file
@ -0,0 +1,30 @@
|
||||
// Copyright (c) 2025 GeWuYou
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
namespace GFramework.Core.Abstractions.Concurrency;
|
||||
|
||||
/// <summary>
|
||||
/// 异步锁句柄接口,支持 await using 语法
|
||||
/// </summary>
|
||||
public interface IAsyncLockHandle : IAsyncDisposable, IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// 锁的键
|
||||
/// </summary>
|
||||
string Key { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 锁获取时的时间戳(Environment.TickCount64)
|
||||
/// </summary>
|
||||
long AcquiredTicks { get; }
|
||||
}
|
||||
43
GFramework.Core.Abstractions/Concurrency/LockInfo.cs
Normal file
43
GFramework.Core.Abstractions/Concurrency/LockInfo.cs
Normal file
@ -0,0 +1,43 @@
|
||||
// Copyright (c) 2025 GeWuYou
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
namespace GFramework.Core.Abstractions.Concurrency;
|
||||
|
||||
/// <summary>
|
||||
/// 锁信息(用于调试)
|
||||
/// </summary>
|
||||
public readonly struct LockInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 锁的键。
|
||||
/// </summary>
|
||||
public string Key { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前引用计数。
|
||||
/// </summary>
|
||||
public int ReferenceCount { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 最后访问时间戳(Environment.TickCount64)。
|
||||
/// </summary>
|
||||
public long LastAccessTicks { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 等待队列长度(近似值)。
|
||||
/// 注意:这是一个基于 SemaphoreSlim.CurrentCount 的近似指示器,
|
||||
/// 当 CurrentCount == 0 时表示锁被持有且可能有等待者,返回 1;
|
||||
/// 否则返回 0。这不是精确的等待者数量,仅用于调试参考。
|
||||
/// </summary>
|
||||
public int WaitingCount { get; init; }
|
||||
}
|
||||
43
GFramework.Core.Abstractions/Concurrency/LockStatistics.cs
Normal file
43
GFramework.Core.Abstractions/Concurrency/LockStatistics.cs
Normal file
@ -0,0 +1,43 @@
|
||||
// Copyright (c) 2025 GeWuYou
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace GFramework.Core.Abstractions.Concurrency;
|
||||
|
||||
/// <summary>
|
||||
/// 锁统计信息
|
||||
/// </summary>
|
||||
[StructLayout(LayoutKind.Auto)]
|
||||
public readonly struct LockStatistics
|
||||
{
|
||||
/// <summary>
|
||||
/// 当前活跃的锁数量
|
||||
/// </summary>
|
||||
public int ActiveLockCount { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 累计获取锁的次数
|
||||
/// </summary>
|
||||
public int TotalAcquired { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 累计释放锁的次数
|
||||
/// </summary>
|
||||
public int TotalReleased { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// 累计清理的锁数量
|
||||
/// </summary>
|
||||
public int TotalCleaned { get; init; }
|
||||
}
|
||||
@ -1,7 +1,7 @@
|
||||
using GFramework.Core.Abstractions.events;
|
||||
using GFramework.Core.Abstractions.utility;
|
||||
using GFramework.Core.Abstractions.Events;
|
||||
using GFramework.Core.Abstractions.Utility;
|
||||
|
||||
namespace GFramework.Core.Abstractions.configuration;
|
||||
namespace GFramework.Core.Abstractions.Configuration;
|
||||
|
||||
/// <summary>
|
||||
/// 配置管理器接口,提供类型安全的配置存储和访问
|
||||
38
GFramework.Core.Abstractions/Controller/IController.cs
Normal file
38
GFramework.Core.Abstractions/Controller/IController.cs
Normal file
@ -0,0 +1,38 @@
|
||||
namespace GFramework.Core.Abstractions.Controller;
|
||||
|
||||
/// <summary>
|
||||
/// 控制器标记接口,用于标识控制器组件
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// IController 是一个标记接口(Marker Interface),不包含任何方法或属性。
|
||||
/// 它的作用是标识一个类是控制器,用于协调 Model、System 和 UI 之间的交互。
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// 架构访问 :控制器通常需要访问架构上下文。使用 [ContextAware] 特性
|
||||
/// 自动生成上下文访问能力:
|
||||
/// </para>
|
||||
/// <code>
|
||||
/// using GFramework.SourceGenerators.Abstractions.Rule;
|
||||
///
|
||||
/// [ContextAware]
|
||||
/// public partial class PlayerController : IController
|
||||
/// {
|
||||
/// public void Initialize()
|
||||
/// {
|
||||
/// // [ContextAware] 实现 IContextAware 接口,可使用扩展方法
|
||||
/// var playerModel = this.GetModel<PlayerModel>();
|
||||
/// var gameSystem = this.GetSystem<GameSystem>();
|
||||
/// }
|
||||
/// }
|
||||
/// </code>
|
||||
/// <para>
|
||||
/// 注意:
|
||||
/// </para>
|
||||
/// <list type="bullet">
|
||||
/// <item>必须添加 partial 关键字</item>
|
||||
/// <item>[ContextAware] 特性会自动实现 IContextAware 接口</item>
|
||||
/// <item>可使用 this.GetModel()、this.GetSystem() 等扩展方法访问架构</item>
|
||||
/// </list>
|
||||
/// </remarks>
|
||||
public interface IController;
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.Core.Abstractions.coroutine;
|
||||
namespace GFramework.Core.Abstractions.Coroutine;
|
||||
|
||||
/// <summary>
|
||||
/// 协程优先级枚举
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.Core.Abstractions.coroutine;
|
||||
namespace GFramework.Core.Abstractions.Coroutine;
|
||||
|
||||
/// <summary>
|
||||
/// 表示协程的执行状态枚举
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.Core.Abstractions.coroutine;
|
||||
namespace GFramework.Core.Abstractions.Coroutine;
|
||||
|
||||
/// <summary>
|
||||
/// 协程统计信息接口
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.Core.Abstractions.coroutine;
|
||||
namespace GFramework.Core.Abstractions.Coroutine;
|
||||
|
||||
/// <summary>
|
||||
/// 时间源接口,提供当前时间、时间增量以及更新功能
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.Core.Abstractions.coroutine;
|
||||
namespace GFramework.Core.Abstractions.Coroutine;
|
||||
|
||||
/// <summary>
|
||||
/// 定义一个可等待指令的接口,用于协程系统中的异步操作控制
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.Core.Abstractions.cqrs.command;
|
||||
namespace GFramework.Core.Abstractions.Cqrs.Command;
|
||||
|
||||
/// <summary>
|
||||
/// 命令输入接口,定义命令模式中输入数据的契约
|
||||
@ -11,7 +11,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
namespace GFramework.Core.Abstractions.cqrs;
|
||||
namespace GFramework.Core.Abstractions.Cqrs;
|
||||
|
||||
/// <summary>
|
||||
/// 表示输入数据的标记接口。
|
||||
@ -11,7 +11,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
namespace GFramework.Core.Abstractions.cqrs.notification;
|
||||
namespace GFramework.Core.Abstractions.Cqrs.Notification;
|
||||
|
||||
/// <summary>
|
||||
/// 表示通知输入数据的标记接口。
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.Core.Abstractions.cqrs.query;
|
||||
namespace GFramework.Core.Abstractions.Cqrs.Query;
|
||||
|
||||
/// <summary>
|
||||
/// 查询输入接口,定义了查询操作的输入规范
|
||||
@ -11,7 +11,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
namespace GFramework.Core.Abstractions.cqrs.request;
|
||||
namespace GFramework.Core.Abstractions.Cqrs.Request;
|
||||
|
||||
/// <summary>
|
||||
/// 表示请求输入数据的标记接口。
|
||||
@ -11,7 +11,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
namespace GFramework.Core.Abstractions.data;
|
||||
namespace GFramework.Core.Abstractions.Data;
|
||||
|
||||
/// <summary>
|
||||
/// 定义从指定类型数据源加载数据的接口
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.Core.Abstractions.enums;
|
||||
namespace GFramework.Core.Abstractions.Enums;
|
||||
|
||||
/// <summary>
|
||||
/// 架构阶段枚举,定义了系统架构初始化和运行过程中的各个关键阶段
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.Core.Abstractions.environment;
|
||||
namespace GFramework.Core.Abstractions.Environment;
|
||||
|
||||
/// <summary>
|
||||
/// 定义环境接口,提供应用程序运行环境的相关信息
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.Core.Abstractions.events;
|
||||
namespace GFramework.Core.Abstractions.Events;
|
||||
|
||||
/// <summary>
|
||||
/// 事件上下文,包装事件数据并提供控制方法
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.Core.Abstractions.events;
|
||||
namespace GFramework.Core.Abstractions.Events;
|
||||
|
||||
/// <summary>
|
||||
/// 事件传播模式
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.Core.Abstractions.events;
|
||||
namespace GFramework.Core.Abstractions.Events;
|
||||
|
||||
/// <summary>
|
||||
/// 事件接口,定义了事件注册的基本功能
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.Core.Abstractions.events;
|
||||
namespace GFramework.Core.Abstractions.Events;
|
||||
|
||||
/// <summary>
|
||||
/// 事件总线接口,提供事件的发送、注册和注销功能
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.Core.Abstractions.events;
|
||||
namespace GFramework.Core.Abstractions.Events;
|
||||
|
||||
/// <summary>
|
||||
/// 事件过滤器接口
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.Core.Abstractions.events;
|
||||
namespace GFramework.Core.Abstractions.Events;
|
||||
|
||||
/// <summary>
|
||||
/// 事件统计信息接口
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.Core.Abstractions.events;
|
||||
namespace GFramework.Core.Abstractions.Events;
|
||||
|
||||
/// <summary>
|
||||
/// 提供注销功能的接口
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.Core.Abstractions.events;
|
||||
namespace GFramework.Core.Abstractions.Events;
|
||||
|
||||
/// <summary>
|
||||
/// 提供统一注销功能的接口,用于管理需要注销的对象列表
|
||||
@ -17,11 +17,11 @@
|
||||
<Using Include="GFramework.Core.Abstractions"/>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Update="Meziantou.Analyzer" Version="3.0.19">
|
||||
<PackageReference Update="Meziantou.Analyzer" Version="3.0.25">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Update="Meziantou.Polyfill" Version="1.0.103">
|
||||
<PackageReference Update="Meziantou.Polyfill" Version="1.0.104">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||
</PackageReference>
|
||||
|
||||
@ -1,18 +1,20 @@
|
||||
// IsExternalInit.cs
|
||||
// This type is required to support init-only setters and record types
|
||||
// when targeting netstandard2.0 or older frameworks.
|
||||
|
||||
#if !NET5_0_OR_GREATER
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace System.Runtime.CompilerServices;
|
||||
|
||||
/// <summary>
|
||||
/// 提供一个占位符类型,用于支持 C# 9.0 的 init 访问器功能。
|
||||
/// 该类型在 .NET 5.0 及更高版本中已内置,因此仅在较低版本的 .NET 中定义。
|
||||
/// </summary>
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
internal static class IsExternalInit
|
||||
{
|
||||
}
|
||||
// IsExternalInit.cs
|
||||
// This type is required to support init-only setters and record types
|
||||
// when targeting netstandard2.0 or older frameworks.
|
||||
|
||||
#if !NET5_0_OR_GREATER
|
||||
using System.ComponentModel;
|
||||
|
||||
// ReSharper disable CheckNamespace
|
||||
|
||||
namespace System.Runtime.CompilerServices;
|
||||
|
||||
/// <summary>
|
||||
/// 提供一个占位符类型,用于支持 C# 9.0 的 init 访问器功能。
|
||||
/// 该类型在 .NET 5.0 及更高版本中已内置,因此仅在较低版本的 .NET 中定义。
|
||||
/// </summary>
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
internal static class IsExternalInit
|
||||
{
|
||||
}
|
||||
#endif
|
||||
@ -1,8 +1,8 @@
|
||||
using GFramework.Core.Abstractions.rule;
|
||||
using GFramework.Core.Abstractions.system;
|
||||
using GFramework.Core.Abstractions.Rule;
|
||||
using GFramework.Core.Abstractions.Systems;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace GFramework.Core.Abstractions.ioc;
|
||||
namespace GFramework.Core.Abstractions.Ioc;
|
||||
|
||||
/// <summary>
|
||||
/// 依赖注入容器接口,定义了服务注册、解析和管理的基本操作
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.Core.Abstractions.lifecycle;
|
||||
namespace GFramework.Core.Abstractions.Lifecycle;
|
||||
|
||||
/// <summary>
|
||||
/// 定义异步销毁接口,用于需要异步清理资源的组件
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.Core.Abstractions.lifecycle;
|
||||
namespace GFramework.Core.Abstractions.Lifecycle;
|
||||
|
||||
/// <summary>
|
||||
/// 定义异步初始化接口,用于需要异步初始化的组件或服务
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.Core.Abstractions.lifecycle;
|
||||
namespace GFramework.Core.Abstractions.Lifecycle;
|
||||
|
||||
/// <summary>
|
||||
/// 定义异步生命周期接口,组合了异步初始化和异步销毁
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.Core.Abstractions.lifecycle;
|
||||
namespace GFramework.Core.Abstractions.Lifecycle;
|
||||
|
||||
/// <summary>
|
||||
/// 可销毁接口,为需要资源清理的组件提供标准销毁能力
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.Core.Abstractions.lifecycle;
|
||||
namespace GFramework.Core.Abstractions.Lifecycle;
|
||||
|
||||
/// <summary>
|
||||
/// 可初始化接口,为需要初始化的组件提供标准初始化能力
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.Core.Abstractions.lifecycle;
|
||||
namespace GFramework.Core.Abstractions.Lifecycle;
|
||||
|
||||
/// <summary>
|
||||
/// 完整生命周期接口,组合了初始化和销毁能力
|
||||
@ -0,0 +1,22 @@
|
||||
namespace GFramework.Core.Abstractions.Localization;
|
||||
|
||||
/// <summary>
|
||||
/// 本地化格式化器接口
|
||||
/// </summary>
|
||||
public interface ILocalizationFormatter
|
||||
{
|
||||
/// <summary>
|
||||
/// 格式化器名称
|
||||
/// </summary>
|
||||
string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 尝试格式化值
|
||||
/// </summary>
|
||||
/// <param name="format">格式字符串</param>
|
||||
/// <param name="value">要格式化的值</param>
|
||||
/// <param name="provider">格式提供者</param>
|
||||
/// <param name="result">格式化结果</param>
|
||||
/// <returns>是否成功格式化</returns>
|
||||
bool TryFormat(string format, object value, IFormatProvider? provider, out string result);
|
||||
}
|
||||
@ -0,0 +1,89 @@
|
||||
using System.Globalization;
|
||||
using GFramework.Core.Abstractions.Systems;
|
||||
|
||||
namespace GFramework.Core.Abstractions.Localization;
|
||||
|
||||
/// <summary>
|
||||
/// 本地化管理器接口
|
||||
/// </summary>
|
||||
public interface ILocalizationManager : ISystem
|
||||
{
|
||||
/// <summary>
|
||||
/// 当前语言代码
|
||||
/// </summary>
|
||||
string CurrentLanguage { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前文化信息
|
||||
/// </summary>
|
||||
CultureInfo CurrentCulture { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 可用语言列表
|
||||
/// </summary>
|
||||
IReadOnlyList<string> AvailableLanguages { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 设置当前语言
|
||||
/// </summary>
|
||||
/// <param name="languageCode">语言代码</param>
|
||||
void SetLanguage(string languageCode);
|
||||
|
||||
/// <summary>
|
||||
/// 获取本地化表
|
||||
/// </summary>
|
||||
/// <param name="tableName">表名</param>
|
||||
/// <returns>本地化表</returns>
|
||||
ILocalizationTable GetTable(string tableName);
|
||||
|
||||
/// <summary>
|
||||
/// 获取本地化文本
|
||||
/// </summary>
|
||||
/// <param name="table">表名</param>
|
||||
/// <param name="key">键名</param>
|
||||
/// <returns>本地化文本</returns>
|
||||
string GetText(string table, string key);
|
||||
|
||||
/// <summary>
|
||||
/// 获取本地化字符串(支持变量和格式化)
|
||||
/// </summary>
|
||||
/// <param name="table">表名</param>
|
||||
/// <param name="key">键名</param>
|
||||
/// <returns>本地化字符串</returns>
|
||||
ILocalizationString GetString(string table, string key);
|
||||
|
||||
/// <summary>
|
||||
/// 尝试获取本地化文本
|
||||
/// </summary>
|
||||
/// <param name="table">表名</param>
|
||||
/// <param name="key">键名</param>
|
||||
/// <param name="text">输出文本</param>
|
||||
/// <returns>是否成功获取</returns>
|
||||
bool TryGetText(string table, string key, out string text);
|
||||
|
||||
/// <summary>
|
||||
/// 注册格式化器
|
||||
/// </summary>
|
||||
/// <param name="name">格式化器名称</param>
|
||||
/// <param name="formatter">格式化器实例</param>
|
||||
void RegisterFormatter(string name, ILocalizationFormatter formatter);
|
||||
|
||||
/// <summary>
|
||||
/// 获取格式化器
|
||||
/// </summary>
|
||||
/// <param name="name">格式化器名称</param>
|
||||
/// <returns>格式化器实例,如果不存在则返回 null</returns>
|
||||
ILocalizationFormatter? GetFormatter(string name);
|
||||
|
||||
/// <summary>
|
||||
/// 订阅语言变化事件
|
||||
/// </summary>
|
||||
/// <param name="callback">回调函数</param>
|
||||
void SubscribeToLanguageChange(Action<string> callback);
|
||||
|
||||
/// <summary>
|
||||
/// 取消订阅语言变化事件
|
||||
/// </summary>
|
||||
/// <param name="callback">回调函数</param>
|
||||
void UnsubscribeFromLanguageChange(Action<string> callback);
|
||||
}
|
||||
@ -0,0 +1,50 @@
|
||||
namespace GFramework.Core.Abstractions.Localization;
|
||||
|
||||
/// <summary>
|
||||
/// 本地化字符串接口(支持变量和格式化)
|
||||
/// </summary>
|
||||
public interface ILocalizationString
|
||||
{
|
||||
/// <summary>
|
||||
/// 表名
|
||||
/// </summary>
|
||||
string Table { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 键名
|
||||
/// </summary>
|
||||
string Key { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 添加变量
|
||||
/// </summary>
|
||||
/// <param name="name">变量名</param>
|
||||
/// <param name="value">变量值</param>
|
||||
/// <returns>当前实例(支持链式调用)</returns>
|
||||
ILocalizationString WithVariable(string name, object value);
|
||||
|
||||
/// <summary>
|
||||
/// 批量添加变量
|
||||
/// </summary>
|
||||
/// <param name="variables">变量数组</param>
|
||||
/// <returns>当前实例(支持链式调用)</returns>
|
||||
ILocalizationString WithVariables(params (string name, object value)[] variables);
|
||||
|
||||
/// <summary>
|
||||
/// 格式化并返回最终文本
|
||||
/// </summary>
|
||||
/// <returns>格式化后的文本</returns>
|
||||
string Format();
|
||||
|
||||
/// <summary>
|
||||
/// 获取原始文本(不进行格式化)
|
||||
/// </summary>
|
||||
/// <returns>原始文本</returns>
|
||||
string GetRaw();
|
||||
|
||||
/// <summary>
|
||||
/// 检查键是否存在
|
||||
/// </summary>
|
||||
/// <returns>是否存在</returns>
|
||||
bool Exists();
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
namespace GFramework.Core.Abstractions.Localization;
|
||||
|
||||
/// <summary>
|
||||
/// 本地化表接口
|
||||
/// </summary>
|
||||
public interface ILocalizationTable
|
||||
{
|
||||
/// <summary>
|
||||
/// 表名
|
||||
/// </summary>
|
||||
string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 语言代码
|
||||
/// </summary>
|
||||
string Language { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 回退表(当前表中找不到键时使用)
|
||||
/// </summary>
|
||||
ILocalizationTable? Fallback { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取原始文本(不进行格式化)
|
||||
/// </summary>
|
||||
/// <param name="key">键名</param>
|
||||
/// <returns>原始文本</returns>
|
||||
string GetRawText(string key);
|
||||
|
||||
/// <summary>
|
||||
/// 检查是否包含指定键
|
||||
/// </summary>
|
||||
/// <param name="key">键名</param>
|
||||
/// <returns>是否包含</returns>
|
||||
bool ContainsKey(string key);
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有键
|
||||
/// </summary>
|
||||
/// <returns>键集合</returns>
|
||||
IEnumerable<string> GetKeys();
|
||||
|
||||
/// <summary>
|
||||
/// 合并覆盖数据
|
||||
/// </summary>
|
||||
/// <param name="overrides">覆盖数据</param>
|
||||
void Merge(IReadOnlyDictionary<string, string> overrides);
|
||||
}
|
||||
@ -0,0 +1,37 @@
|
||||
namespace GFramework.Core.Abstractions.Localization;
|
||||
|
||||
/// <summary>
|
||||
/// 本地化配置
|
||||
/// </summary>
|
||||
public class LocalizationConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// 默认语言代码
|
||||
/// </summary>
|
||||
public string DefaultLanguage { get; set; } = "eng";
|
||||
|
||||
/// <summary>
|
||||
/// 回退语言代码(当目标语言缺少键时使用)
|
||||
/// </summary>
|
||||
public string FallbackLanguage { get; set; } = "eng";
|
||||
|
||||
/// <summary>
|
||||
/// 本地化文件路径(Godot 资源路径)
|
||||
/// </summary>
|
||||
public string LocalizationPath { get; set; } = "res://localization";
|
||||
|
||||
/// <summary>
|
||||
/// 用户覆盖文件路径(用于热更新和自定义翻译)
|
||||
/// </summary>
|
||||
public string OverridePath { get; set; } = "user://localization_override";
|
||||
|
||||
/// <summary>
|
||||
/// 是否启用热重载(监视覆盖文件变化)
|
||||
/// </summary>
|
||||
public bool EnableHotReload { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// 是否在加载时验证本地化文件
|
||||
/// </summary>
|
||||
public bool ValidateOnLoad { get; set; } = true;
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
namespace GFramework.Core.Abstractions.Localization;
|
||||
|
||||
/// <summary>
|
||||
/// 本地化异常基类
|
||||
/// </summary>
|
||||
public class LocalizationException : Exception
|
||||
{
|
||||
/// <summary>
|
||||
/// 初始化本地化异常
|
||||
/// </summary>
|
||||
public LocalizationException()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化本地化异常
|
||||
/// </summary>
|
||||
/// <param name="message">异常消息</param>
|
||||
public LocalizationException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 初始化本地化异常
|
||||
/// </summary>
|
||||
/// <param name="message">异常消息</param>
|
||||
/// <param name="innerException">内部异常</param>
|
||||
public LocalizationException(string message, Exception innerException) : base(message, innerException)
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,29 @@
|
||||
namespace GFramework.Core.Abstractions.Localization;
|
||||
|
||||
/// <summary>
|
||||
/// 本地化键未找到异常
|
||||
/// </summary>
|
||||
public class LocalizationKeyNotFoundException : LocalizationException
|
||||
{
|
||||
/// <summary>
|
||||
/// 初始化键未找到异常
|
||||
/// </summary>
|
||||
/// <param name="tableName">表名</param>
|
||||
/// <param name="key">键名</param>
|
||||
public LocalizationKeyNotFoundException(string tableName, string key)
|
||||
: base($"Localization key '{key}' not found in table '{tableName}'")
|
||||
{
|
||||
TableName = tableName;
|
||||
Key = key;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 表名
|
||||
/// </summary>
|
||||
public string TableName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 键名
|
||||
/// </summary>
|
||||
public string Key { get; }
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
namespace GFramework.Core.Abstractions.Localization;
|
||||
|
||||
/// <summary>
|
||||
/// 本地化表未找到异常
|
||||
/// </summary>
|
||||
public class LocalizationTableNotFoundException : LocalizationException
|
||||
{
|
||||
/// <summary>
|
||||
/// 初始化表未找到异常
|
||||
/// </summary>
|
||||
/// <param name="tableName">表名</param>
|
||||
public LocalizationTableNotFoundException(string tableName)
|
||||
: base($"Localization table '{tableName}' not found")
|
||||
{
|
||||
TableName = tableName;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 表名
|
||||
/// </summary>
|
||||
public string TableName { get; }
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.Core.Abstractions.logging;
|
||||
namespace GFramework.Core.Abstractions.Logging;
|
||||
|
||||
/// <summary>
|
||||
/// 日志输出器接口,负责将日志条目写入特定目标
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.Core.Abstractions.logging;
|
||||
namespace GFramework.Core.Abstractions.Logging;
|
||||
|
||||
/// <summary>
|
||||
/// 日志过滤器接口,用于决定是否应该记录某条日志
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.Core.Abstractions.logging;
|
||||
namespace GFramework.Core.Abstractions.Logging;
|
||||
|
||||
/// <summary>
|
||||
/// 日志格式化器接口,用于将日志条目格式化为字符串
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.Core.Abstractions.logging;
|
||||
namespace GFramework.Core.Abstractions.Logging;
|
||||
|
||||
/// <summary>
|
||||
/// 定义日志记录接口,提供日志记录和级别检查功能
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.Core.Abstractions.logging;
|
||||
namespace GFramework.Core.Abstractions.Logging;
|
||||
|
||||
/// <summary>
|
||||
/// 定义日志工厂接口,用于创建日志记录器实例
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.Core.Abstractions.logging;
|
||||
namespace GFramework.Core.Abstractions.Logging;
|
||||
|
||||
/// <summary>
|
||||
/// 定义日志工厂提供者的接口,用于创建具有指定名称和最小日志级别的日志记录器
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.Core.Abstractions.logging;
|
||||
namespace GFramework.Core.Abstractions.Logging;
|
||||
|
||||
/// <summary>
|
||||
/// 支持结构化日志的日志记录器接口
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.Core.Abstractions.logging;
|
||||
namespace GFramework.Core.Abstractions.Logging;
|
||||
|
||||
/// <summary>
|
||||
/// 日志上下文,用于在异步流中传递结构化属性
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.Core.Abstractions.logging;
|
||||
namespace GFramework.Core.Abstractions.Logging;
|
||||
|
||||
/// <summary>
|
||||
/// 日志条目,包含完整的日志信息
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.Core.Abstractions.logging;
|
||||
namespace GFramework.Core.Abstractions.Logging;
|
||||
|
||||
/// <summary>
|
||||
/// 定义日志级别的枚举,用于标识不同严重程度的日志消息
|
||||
10
GFramework.Core.Abstractions/Model/IModel.cs
Normal file
10
GFramework.Core.Abstractions/Model/IModel.cs
Normal file
@ -0,0 +1,10 @@
|
||||
using GFramework.Core.Abstractions.Architectures;
|
||||
using GFramework.Core.Abstractions.Lifecycle;
|
||||
using GFramework.Core.Abstractions.Rule;
|
||||
|
||||
namespace GFramework.Core.Abstractions.Model;
|
||||
|
||||
/// <summary>
|
||||
/// 模型接口,定义了模型的基本行为和功能
|
||||
/// </summary>
|
||||
public interface IModel : IContextAware, IArchitecturePhaseListener, IInitializable;
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.Core.Abstractions.pause;
|
||||
namespace GFramework.Core.Abstractions.Pause;
|
||||
|
||||
/// <summary>
|
||||
/// 暂停处理器接口,由引擎层实现具体的暂停/恢复逻辑
|
||||
@ -1,6 +1,6 @@
|
||||
using GFramework.Core.Abstractions.utility;
|
||||
using GFramework.Core.Abstractions.Utility;
|
||||
|
||||
namespace GFramework.Core.Abstractions.pause;
|
||||
namespace GFramework.Core.Abstractions.Pause;
|
||||
|
||||
/// <summary>
|
||||
/// 暂停栈管理器接口,管理嵌套暂停状态
|
||||
@ -75,7 +75,9 @@ public interface IPauseStackManager : IContextUtility
|
||||
void UnregisterHandler(IPauseHandler handler);
|
||||
|
||||
/// <summary>
|
||||
/// 暂停状态变化事件
|
||||
/// 暂停状态变化事件。
|
||||
/// 事件遵循标准 .NET 事件模式,事件源为触发通知的暂停管理器实例,
|
||||
/// 事件数据由 <see cref="PauseStateChangedEventArgs"/> 提供。
|
||||
/// </summary>
|
||||
event Action<PauseGroup, bool>? OnPauseStateChanged;
|
||||
event EventHandler<PauseStateChangedEventArgs>? OnPauseStateChanged;
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.Core.Abstractions.pause;
|
||||
namespace GFramework.Core.Abstractions.Pause;
|
||||
|
||||
/// <summary>
|
||||
/// 暂停组枚举,定义不同的暂停作用域
|
||||
@ -0,0 +1,30 @@
|
||||
namespace GFramework.Core.Abstractions.Pause;
|
||||
|
||||
/// <summary>
|
||||
/// 表示暂停状态变化事件的数据。
|
||||
/// 该类型用于向事件订阅者传递暂停组以及该组变化后的暂停状态。
|
||||
/// </summary>
|
||||
public sealed class PauseStateChangedEventArgs : EventArgs
|
||||
{
|
||||
/// <summary>
|
||||
/// 初始化 <see cref="PauseStateChangedEventArgs"/> 的新实例。
|
||||
/// </summary>
|
||||
/// <param name="group">发生状态变化的暂停组。</param>
|
||||
/// <param name="isPaused">暂停组变化后的新状态。</param>
|
||||
public PauseStateChangedEventArgs(PauseGroup group, bool isPaused)
|
||||
{
|
||||
Group = group;
|
||||
IsPaused = isPaused;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取发生状态变化的暂停组。
|
||||
/// </summary>
|
||||
public PauseGroup Group { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取暂停组变化后的新状态。
|
||||
/// 为 <see langword="true"/> 表示进入暂停,为 <see langword="false"/> 表示恢复运行。
|
||||
/// </summary>
|
||||
public bool IsPaused { get; }
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.Core.Abstractions.pause;
|
||||
namespace GFramework.Core.Abstractions.Pause;
|
||||
|
||||
/// <summary>
|
||||
/// 暂停令牌,唯一标识一个暂停请求
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.Core.Abstractions.pool;
|
||||
namespace GFramework.Core.Abstractions.Pool;
|
||||
|
||||
/// <summary>
|
||||
/// 对象池系统接口,定义了对象池的基本操作
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.Core.Abstractions.pool;
|
||||
namespace GFramework.Core.Abstractions.Pool;
|
||||
|
||||
/// <summary>
|
||||
/// 定义可池化对象的接口,提供对象在池中的生命周期管理方法
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.Core.Abstractions.pool;
|
||||
namespace GFramework.Core.Abstractions.Pool;
|
||||
|
||||
/// <summary>
|
||||
/// 对象池统计信息
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.Core.Abstractions.properties;
|
||||
namespace GFramework.Core.Abstractions.Properties;
|
||||
|
||||
/// <summary>
|
||||
/// 架构选项配置类,用于定义架构行为的相关配置选项。
|
||||
@ -17,10 +17,4 @@ public sealed class ArchitectureProperties
|
||||
/// 默认值为 false,表示不启用严格验证。
|
||||
/// </summary>
|
||||
public bool StrictPhaseValidation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 启用 ECS(Entity Component System)功能的开关。
|
||||
/// 当设置为 true 时,架构将启用 ECS 相关功能。
|
||||
/// </summary>
|
||||
public bool EnableEcs { get; set; }
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
using GFramework.Core.Abstractions.logging;
|
||||
using GFramework.Core.Abstractions.Logging;
|
||||
|
||||
namespace GFramework.Core.Abstractions.properties;
|
||||
namespace GFramework.Core.Abstractions.Properties;
|
||||
|
||||
/// <summary>
|
||||
/// 日志配置选项类,用于配置日志系统的相关参数
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.Core.Abstractions.property;
|
||||
namespace GFramework.Core.Abstractions.Property;
|
||||
|
||||
/// <summary>
|
||||
/// 可绑定属性接口,继承自只读可绑定属性接口,提供可读写的属性绑定功能
|
||||
@ -1,6 +1,6 @@
|
||||
using GFramework.Core.Abstractions.events;
|
||||
using GFramework.Core.Abstractions.Events;
|
||||
|
||||
namespace GFramework.Core.Abstractions.property;
|
||||
namespace GFramework.Core.Abstractions.Property;
|
||||
|
||||
/// <summary>
|
||||
/// 只读可绑定属性接口,提供属性值的读取和变更监听功能
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.Core.Abstractions.query;
|
||||
namespace GFramework.Core.Abstractions.Query;
|
||||
|
||||
/// <summary>
|
||||
/// 异步查询接口,定义了执行异步查询操作的方法
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.Core.Abstractions.query;
|
||||
namespace GFramework.Core.Abstractions.Query;
|
||||
|
||||
|
||||
/// <summary>
|
||||
@ -1,6 +1,6 @@
|
||||
using GFramework.Core.Abstractions.rule;
|
||||
using GFramework.Core.Abstractions.Rule;
|
||||
|
||||
namespace GFramework.Core.Abstractions.query;
|
||||
namespace GFramework.Core.Abstractions.Query;
|
||||
|
||||
/// <summary>
|
||||
/// 查询接口,定义了执行查询操作的契约
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.Core.Abstractions.query;
|
||||
namespace GFramework.Core.Abstractions.Query;
|
||||
|
||||
|
||||
/// <summary>
|
||||
@ -1,6 +1,6 @@
|
||||
using GFramework.Core.Abstractions.bases;
|
||||
using GFramework.Core.Abstractions.Bases;
|
||||
|
||||
namespace GFramework.Core.Abstractions.registries;
|
||||
namespace GFramework.Core.Abstractions.Registries;
|
||||
|
||||
/// <summary>
|
||||
/// 表示一个通用的注册表接口,用于根据键类型T获取值类型TR的对象
|
||||
@ -1,7 +1,7 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using GFramework.Core.Abstractions.bases;
|
||||
using GFramework.Core.Abstractions.Bases;
|
||||
|
||||
namespace GFramework.Core.Abstractions.registries;
|
||||
namespace GFramework.Core.Abstractions.Registries;
|
||||
|
||||
/// <summary>
|
||||
/// 基于Dictionary的通用键值注册表基类
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.Core.Abstractions.resource;
|
||||
namespace GFramework.Core.Abstractions.Resource;
|
||||
|
||||
/// <summary>
|
||||
/// 资源句柄接口,用于管理资源的生命周期和引用
|
||||
@ -1,4 +1,4 @@
|
||||
namespace GFramework.Core.Abstractions.resource;
|
||||
namespace GFramework.Core.Abstractions.Resource;
|
||||
|
||||
/// <summary>
|
||||
/// 资源加载器接口,用于加载特定类型的资源
|
||||
@ -1,6 +1,6 @@
|
||||
using GFramework.Core.Abstractions.utility;
|
||||
using GFramework.Core.Abstractions.Utility;
|
||||
|
||||
namespace GFramework.Core.Abstractions.resource;
|
||||
namespace GFramework.Core.Abstractions.Resource;
|
||||
|
||||
/// <summary>
|
||||
/// 资源管理器接口,提供资源加载、缓存和卸载功能
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user