File: README.md
QFramework 简介 Intro
QFramework 是提供一套简单、强大、易上手、符合 SOLID 原则、支持领域驱动设计(DDD)、事件驱动、数据驱动、分层、MVC 、CQRS、模块化、易扩展的架构,她的源码只有不到 1000 行,你可以完全把她放在你的笔记应用里保存。
提供的架构图
举个例子(一图胜千言😂)
各种情况的示意图
架构使用规范
QFramework系统设计架构分为四层及其规则:
- 表现层:ViewController层。IController接口,负责接收输入和状态变化时的表现,一般情况下,MonoBehaviour 均为表现层
- 可以获取System
- 可以获取Model
- 可以发送Command
- 可以监听Event
- 系统层:System层。ISystem接口,帮助IController承担一部分逻辑,在多个表现层共享的逻辑,比如计时系统、商城系统、成就系统等
- 可以获取System
- 可以获取Model
- 可以监听Event
- 可以发送Event
- 数据层:Model层。IModel接口,负责数据的定义、数据的增删查改方法的提供
- 可以获取Utility
- 可以发送Event
- 工具层:Utility层。IUtility接口,负责提供基础设施,比如存储方法、序列化方法、网络连接方法、蓝牙方法、SDK、框架继承等。啥都干不了,可以集成第三方库,或者封装API
- 除了四个层级,还有一个核心概念——Command
- 可以获取System
- 可以获取Model
- 可以发送Event
- 可以发送Command
- 层级规则:
- IController 更改 ISystem、IModel 的状态必须用Command
- ISystem、IModel状态发生变更后通知IController必须用事件或BindableProperty
- IController可以获取ISystem、IModel对象来进行数据查询
- ICommand不能有状态
- 上层可以直接获取下层,下层不能获取上层对象
- 下层向上层通信用事件
- 上层向下层通信用方法调用(只是做查询,状态变更用Command),IController的交互逻辑为特别情况,只能用Command
(照抄自:学生课堂笔记1)
运行环境
- Unity 2018.4.x ~ Unity 6.x
安装
QFramework.cs
- 直接复制此代码到自己项目中的任意脚本中
QFramework.cs 与 官方示例
QFramework.ToolKits
QFramework.ToolKitsPro
- 从 AssetStore 安装
资源
| 版本 | ||
|---|---|---|
| QFramework.cs | QFramework 本体架构的实现 | 文件 |
| QFramework.cs 示例 | QFramework.cs 与官方示例: CounterApp、《点点点》、FlappyBird、CubeMaster、ShootingEditor2D、贪吃蛇等 | 点此下载 unitypackage |
| QFramework.Toolkits | QFramework 集成 CoreKit/UIKit/ActionKit/ResKit/PackageKit/AudioKit 等全部官方工具(已包含 QFramework.cs 和 示例) | 点此下载 unitypackage |
| QFramework.Toolkits.Demo.WuZiQi | 使用 QFramework.Toolkits 开发的五子棋 Demo(需要安装好 QFramework.Toolkits) | 点此下载 unitypackage |
| QFramework.Toolkits.Demo.Saolei | 使用 QFramework.Toolkits 开发的扫雷 Demo(需要安装好 QFramework.Toolkits) | 点此下载 unitypackage |
| QFramework.ToolKitsPro | 在 ToolKits 基础上集成更多好用的工具的版本(已包含 QFramework.Toolkits) | AssetStore |
| 群友案例 | ||
| 赛车游戏《Crazy Car》 | 群友 TastSong 使用 QF 进行重构的开源赛车游戏 | 游戏主页(Github) |
| 社区 | ||
| QQ 群1(已满):623597263 | 交流群 | 点击加群 |
| QQ 群2:541745166 | 交流群 | 点击加群 |
| 腾讯频道 | 中文社区 | 点击加入频道 |
| Discord | 英文社区 | 点击加入频道 |
| 教程 | ||
| 《框架搭建 决定版》 | 教程 QFramework 的核心架构是怎么演化过来的? | 课程主页|学生课堂笔记1|学生课堂笔记2 |
| 产品案例 | 如果用了 qf 并且想要在如下列表中登记,可以在 github/gitee 的 issue 里发帖子,也可以加 qq 群,也可以用邮箱联系凉鞋 [email protected],当然如果看到使用 qf 的项目,我也会先去尝试征得同意再放到如下列表。 | |
| 精选置顶 | ||
| 独立游戏《盒子面包坊》 | TapTap | Steam | |
| 独立游戏《观鸟笔记》 | Steam | |
| 独立游戏《乌合之众》 | Steam | |
| 按登记时间 | ||
| 独立游戏《三国掷:崛起》 | Steam | |
| 独立游戏《银河摸鱼人》 | Steam | |
| 独立游戏《ScaleBox》 | Steam | |
| 独立游戏《我的玫瑰》 | Steam | |
| 独立游戏《蚀界档案》 | TapTap |Steam | |
| 独立游戏《X-teriods》 | Steam | |
| 独立游戏《你好茄子:精灵的诞生》 | Steam | |
| 独立游戏《当火车鸣笛三秒》 | Steam|TapTap | |
| 独立游戏《你好茄子》 | Steam | |
| 独立游戏《第一座山》 | Steam | |
| 独立游戏《推灭泡泡姆》 | TapTap | |
| 独立游戏《鬼山之下》 | Steam | |
| 手机游戏《谐音梗挑战》 | TapTap | |
| 其他相关教程 | ||
| 《原创独立游戏制作:类星露谷》(凉鞋) | 原创独立游戏制作教程,有用到 PlayMaker、QFramework.Tookits | b 站 |
| 《QFramework 教程年会员》 | QFramework 相关的课程案例 | GamePix |
| 《QFramework 教程永久会员》 | QFramework 相关的课程案例 | GamePix |
Star 趋势(如果项目有帮到您欢迎点赞)
作者
贡献者
New一天
幽飞冷凝雪~冷
优秀的 Unity 库、框架
- YokiFrame: 支持i Unity 与 Godot 的 C# 游戏框架,提供架构分层、事件系统、状态机、对象池、资源管理、UI 工具和编辑器扩展,帮助开发者构建更清晰的游戏项目。
- StellarFramework: 一套专为独立开发者项目打造的高性能 Unity 开发框架
- ET:ET Unity3D Client And C# Server Framework
- IFramework(OnClick) Simple Unity Tools
- JEngine 使Unity开发的游戏支持热更新的解决方案。
- TinaX Framework “开箱即用”的Unity独立游戏开发工具
代码规范完全遵循:
赞助 Donate:
- 如果觉得不错可以在 这里 Asset Store 给个 5 星哦~ give 5 star
- 或者给此仓库一个小小的 Star~ star this repository
- 以上这些都会转化成我们的动力,提供更好的技术服务!
鸣谢
感谢 JetBrains 公司提供的使用许可证!
感谢 OpenAI 通过 Codex for OSS 计划对本项目的开源维护提供支持。
感谢 GitHub Copilot 对本项目开源维护提供支持。
感谢小米 MiMo 对本项目开源维护提供 Token 赞助。
本开源项目由 QFramework 教程年会员 提供资助
File: QFramework.Unity2018+/Assets/QFramework/Toolkits/_CoreKit/JsonKit/readme.md
Author
Matt Schoen [email protected] of Defective Studios
Intro
I came across the need to send structured data to and from a server on one of my projects, and figured it would be worth my while to use JSON. When I looked into the issue, I tried a few of the C# implementations listed on http://json.org, but found them to be too complicated to work with and expand upon. So, I've written a very simple JSONObject class, which can be generically used to encode/decode data into a simple container. This page assumes that you know what JSON is, and how it works. It's rather simple, just go to json.org for a visual description of the encoding format.
Usage
Users should not have to modify the JSONObject class themselves, and must follow the very simple procedures outlined below:
Sample data (in JSON format):
{
"TestObject": {
"SomeText": "Blah",
"SomeObject": {
"SomeNumber": 42,
"SomeBool": true,
"SomeNull": null
},
"SomeEmptyObject": { },
"SomeEmptyArray": [ ],
"EmbeddedObject": "{\"field\":\"Value with \\\"escaped quotes\\\"\"}"
}
}The test classes provide the best examples for how the API is intended to be used.
Features
- Decode JSON-formatted strings into a usable data structure
- Encode structured data into a JSON-formatted string
- Interoperable with
DictionaryandWWWForm - Optimized
parse/stringifyfunctions -- minimal (unavoidable) garbage creation - Asynchronous
stringifyfunction for serializing lots of data without frame drops MaxDepthparsing will skip over nested data that you don't need- Special (non-compliant)
Bakedobject type can store stringified data within parsed objects - Copy to new
JSONObject - Merge with another
JSONObject(experimental) - Random access (with
intorstring) ToString()returns JSON data with optional "pretty" flag to include newlines and tabs- Switch between double and float for numeric storage depending on level of precision needed (and to ensure that numbers are parsed/stringified correctly)
- Supports
InfinityandNaNvalues JSONTemplatesstatic class provides serialization functions for common classes likeVector3,Matrix4x4- Object pool implementation (experimental)
- Handy
JSONCheckerwindow to test parsing on sample data
It should be pretty obvious what this parser can and cannot do. If anyone reading this is a JSON buff (is there such a thing?) please feel free to expand and modify the parser to be more compliant. Currently I am using the .NET System.Convert namespace functions for parsing the data itself. It parses strings and numbers, which was all that I needed of it, but unless the formatting is supported by System.Convert, it may not incorporate all proper JSON strings. Also, having never written a JSON parser before, I don't doubt that I could improve the efficiency or correctness of the parser. It serves my purpose, and hopefully will help you with your project! Let me know if you make any improvements :)
Also, you JSON buffs (really, who would admit to being a JSON buff...) might also notice from my feature list that this thing isn't exactly to specifications. Here is where it differs:
- "a string" is considered valid JSON. There is an optional "strict" parameter to the parser which will bomb out on such input, in case that matters to you.
- The
Bakedmode is totally made up. - The
MaxDepthparsing is totally made up. NaNandInfinitywere introduced in a later version of the standard, and some linters will report them as errors
Encoding
Encoding is something of a hard-coded process. This is because I have no idea what your data is! It would be great if this were some sort of interface for taking an entire class and encoding it's number/string fields, but it's not. I've come up with a few clever ways of using loops and/or recursive methods to cut down of the amount of code I have to write when I use this tool, but they're pretty project-specific.
The constructor, Add, and AddField functions now support a nested delegate structure. This is useful if you need to create a nested JSONObject in a single line. For example:
void DoRequest(string url, string jsonString) {
// Web Request logic
}
void Test(string url) {
DoRequest(url, new JSONObject(request => {
request.AddField("sort", sort => sort.AddField("_timestamp", "desc"));
request.AddField("query", new JSONObject(query => query.AddField("match_all", JSONObject.emptyObject)));
request.AddField("fields", fields => fields.Add("_timestamp"));
}).ToString());
}Decoding
Decoding is much simpler on the input end, and again, what you do with the JSONObject will vary on a per-project basis. One of the more complicated way to extract the data is with a recursive function, as drafted below. Calling the constructor with a properly formatted JSON string will return the root object (or array) containing all of its children, in one neat reference! The data is in a public ArrayList called list, with a matching key list (called keys!) if the root is an Object. If that's confusing, take a glance over the following code and the print() method in the JSONObject class. If there is an error in the JSON formatting (or if there's an error with my code!) the debug console will read "improper JSON formatting".
void Test() {
var encodedString = "{\"field1\": 0.5,\"field2\": \"sampletext\",\"field3\": [1,2,3]}";
var jsonObject = new JSONObject(encodedString);
AccessData(jsonObject);
}
void AccessData(JSONObject jsonObject) {
switch (jsonObject.type) {
case JSONObject.Type.Object:
for (var i = 0; i < jsonObject.list.Count; i++) {
var key = jsonObject.keys[i];
var value = jsonObject.list[i];
Debug.Log(key);
AccessData(value);
}
break;
case JSONObject.Type.Array:
foreach (JSONObject element in jsonObject.list) {
AccessData(element);
}
break;
case JSONObject.Type.String:
Debug.Log(jsonObject.stringValue);
break;
case JSONObject.Type.Number:
Debug.Log(jsonObject.floatValue);
break;
case JSONObject.Type.Bool:
Debug.Log(jsonObject.boolValue);
break;
case JSONObject.Type.Null:
Debug.Log("Null");
break;
case JSONObject.Type.Baked:
Debug.Log(jsonObject.stringValue);
break;
}
}Decoding also supports a delegate format which will automatically check if a field exists before processing the data, providing an optional parameter for an OnFieldNotFound response. For example:
void Test(string jsonString) {
var list = new JSONObject(jsonString);
list.GetField("users", users => {
foreach (var user in users.list) {
var thisUser = user;
users.GetField("sessions", sessions => {
foreach (JSONObject gameSession in sessions.list) {
Debug.Log(gameSession);
}
}, name => Debug.LogWarning(string.Format("No sessions for user {0}", thisUser["name"].stringValue)));
}
});
}`(O(n))` Random access
I've added a string and int [] index to the class, so you can now retrieve data as such (from above):
void Test() {
var jsonObject = new JSONObject("{\"field\":[0,1,2]");
var array = jsonObject["field"];
Debug.Log(array[2].intValue); //Should output "2"
}Change Log
v2.1.3
- Fix exception where input is just an empty array or object
- Pool and null out list and keys field when clearing JSONObject for consistency with a fresh object;
This was causing the MaxDepthWithExcessLevels test to fail randomly when checking results because some pooled objects had list but not keys - Update JSONChecker with information about pools and a note about not validating standard JSON
v2.1.2
- Fix issue parsing json strings with whitespace after colon characters
v2.1.1
- Fix issue parsing nested arrays with multiple elements
- Refactor MaxDepth tests
- Fix issues with MaxDepth
v2.1
- Add async parsing method
- Rewrite and optimize parser
- Fix parsing errors
- Refactor VectorTemplates to use extension methods
- Add more tests
v2.0
- Add JSONObject to Defective.JSON namespace
- Update APIs to be more descriptive
- Fix parsing errors
- Add tests
v1.4
Big update!
- Better GC performance. Enough of that garbage!
- Remaining culprits are internal garbage from
StringBuilder.Append/AppendFormat,String.Substring,List.Add/GrowIfNeeded,Single.ToString
- Remaining culprits are internal garbage from
- Added asynchronous
Stringifyfunction for serializing large amounts of data at runtime without frame drops - Added
Bakedtype - Added
MaxDepthto parsing function - Various cleanup refactors recommended by ReSharper
v1.3.2
- Added support for
NaN - Added strict mode to fail on purpose for improper formatting. Right now this just means that if the parse string doesn't start with
[or{, it will print a warning and return anullJSONObject. - Changed
infinityandNaNimplementation to usefloatanddoubleinstead ofMathf - Handles empty objects/arrays better
- Added a flag to print and
ToStringto turn on/off pretty print. The define on top is now an override to system-wide disable
File: README_EN.md
QFramework Intro
QFramework is a framework. she support solid pricinple、domain design driven、event-driven、data-driven、layered、mvc、cqrs、modulization、extendable、scalable architecture. Simple but powerful! she only has 1000 lines of code.can save to a note-taking app.
Architecture diagram
For Example
Schematic diagram of various situations
Architecture Rule
QFramework System Design Architecture has 4 layers:
- Presentation Layer:ViewController Layer. Using IController interface,recive input from user and state changed event from model. In unity MonoBehaviour is on presentation layer
- Can get System
- Can get Model
- Can send Command
- Can listen Event
- System Layer:Using ISystem interface. share IController's part of responsibility. Sharing logic shared across multiple presentation layers,suchas time system、shop system、archivement system.
- Can get System
- Can get Model
- Can listen Event
- Can send Event
- Model Layer:Using IModel interface.Responsible for data definition, data addition, deletion, query and modification methods.
- Can get Utility
- Can send Event
- Utility Layer:Using IUtility interface.Responsible for providing infrastructure, such as storage method, serialization method, network connection method, Bluetooth method, SDK, framework inheritance, etc. Nothing can be done. You can integrate third-party libraries or encapsulate APIs
- In addition to the four layers, there is a core concept - command
- Can get System
- Can get Model
- Can send Event
- Can send Command
- Layer Rule:
- IController change ISystem、IModel's state by Command
- Notify icontroller after the change of ISystem and IModel must use event or bindableproperty
- IController can get ISystem、IModel for data query
- ICommand cannot have state
- The upper layer can directly obtain the lower layer, and the lower layer cannot obtain the upper object
- Events for lower layer to upper layer communication
- The communication between the upper layer and the lower layer is called by method (only for query and command for state change). The interaction logic of IController is special, and command can only be used
(照抄自:学生课堂笔记1)
Environment
- Unity 2018.4.x ~ 2021.x
Install
QFramework.cs
- copy this code to your project
QFramework.cs With Examples
QFramework.ToolKits
QFramework.ToolkitsPro
- install by Asset Store
Resources
| Version | ||
|---|---|---|
| QFramework.cs | Implementation of qframework ontology architecture | code file |
| QFramework.cs With Examples | QFramework.cs and Examples:CounterApp、Point Point Point、CubeMaster、FlappyBird、ShootingEditor2D、SnakeGame etc (QFramework.cs included) | downlowd unitypackage |
| QFramework.ToolKits | QFramework.cs with UIKit/ActionKit/ResKit/PackageKit/AudioKit (QFramework.cs and examples included) | downlowd unity package |
| QFramework.Toolkits.Demo.WuZiQi | Gobang Demo by QFramework.Toolkits(Need Install QFramework.Toolkits) | download unitypackage |
| QFramework.Toolkits.Demo.Saolei | Mine clearance Demo by QFramework.Toolkits(Need Install QFramework.Toolkits) | download unitypackage |
| QFramework.ToolKitsPro | More Powerful Tools version based on QFramework.ToolKits (QFramework.Toolkits included) | AssetStore |
| Community | ||
| github issue | github community | link |
| gitee issue | gitee community | link |
| discord | link | |
| ShowCase | email me or publish on github's issue. My email: [email protected] | |
| Indie Game《Cast of the Three Kingdoms: Rise》 | Steam | |
| Indie Game《Birdwatching Notebook》 | Steam | |
| 《Fools, Maniacs and Liars》 | Steam | |
| 《Skulker》 | Steam | |
| 《ScaleBox》 | Steam | |
| 《MyRose》 | Steam | |
| 《蚀界档案》 | TapTap |Steam | |
| 《Box Bakery》 | Steam | |
| 《X-teroids》 | Steam | |
| 《The last day of Han dynasty》 | Steam | |
| 《Hi Eggplant:The Birth Of Sprites》 | Steam | |
| 《When The Train Buzzes For Three Seconds》 | Steam|TapTap | |
| 《Hi Eggplant》 | Steam | |
| 《The First Mountain》 | Steam | |
| 《Hi Eggplant》 | Steam | |
| 《Under The Ghost Mountain》 | Steam |
Star Trends
Author
Contributors
New一天
幽飞冷凝雪~冷
Other Awesome Framework
YokiFrame: C# Game Framework Support Unity And Godot Engine
StellarFramework: Unity Framework For Indie Developer With High Performance
ET:ET Unity3D Client And C# Server Framework
JEngine The solution that allows unity games update in runtime.
Code Style:
Donate:
- 如果觉得不错可以在 Asset Store 给个 5 星哦~ give 5 star
- 或者给此仓库一个小小的 Star~ star this repository
- 以上这些都会转化成我们的动力,提供更好的技术服务!
Credits:
Thanks for Licenses Supporting by JetBrains Company
This project is supported by OpenAI's Codex for OSS program for open-source maintenance.
This project is also supported by GitHub Copilot for open-source maintenance.
This project is also supported by Xiaomi MiMo with token sponsorship for open-source maintenance.