类型 (Type) 介绍
类型 (Type) 介绍
“类型(Type)”描述了一组可能的值。这不仅包括数字或其他基本原生类型,还涵盖更抽象的概念,从 文本(String)、用户(User)、加入请求(JoinRequestHandle),一直到单纯的“世界的一部分(IWorldElement)”。
分类
类型可以被划分为不同的类别。在很多情况下,“简单(Simple)”类型和“复杂(Complex)”类型之间存在着某种区别。
具体的分类细节取决于你所讨论的上下文环境。
ProtoFlux
ProtoFlux 的执行是一种本地现象,它在启动它的计算机上运行。事实上,ProtoFlux 的实现被设计为独立于 FrooxEngine 的。[需补充引用:如果能指出关于 ProtoFlux 设计理念的官方信息会更好]
总之,它紧密遵循底层的 C# 标准。C# 根据值的存储位置来区分类型:
| 类别 (ProtoFlux) | 类别 (C#) | 描述 |
|---|---|---|
| 值类型 (Value Type) |
值类型 (Value Type) |
值直接存储在变量/属性内部。 |
| 对象类型 (Object Type) |
引用类型 (Reference Type) |
值存在于内存中的某个位置。变量/属性包含对该内存位置的引用。 对象类型还构成了一个层次结构,其中“子类型(sub-type)”的实例始终是“父类型(super-type)”的实例。这使得一个通用概念(例如 碰撞体 (ICollider))可以通过不同的方式来实现(例如 BoxCollider、SphereCollider 等)。 |
另见:枚举 (Enums),它是值类型的一个子类别。
世界模型 (World Model)
Resonite 的世界模型需要为多个用户保持一致。值在本地被存储在哪里,远没有它在网络中如何进行通信来得重要。
实际上,这意味着在处理组件及其属性时,我们必须区分以下类别:
| 类别 | 包含的所有类型 | 描述 |
|---|---|---|
| 值 (Values) | 值类型 (Value Types)、字符串 (strings)、URIs、Nullable 和 IEncodable | 值将按原样写入网络消息中,并按原样从中读取。 |
| 引用 (References) | IWorldElement 及其所有派生类(例如 Slot) | 被引用的对象可以通过将通过网络发送的 引用ID (RefID) 进行唯一标识。然后接收方将执行查找,以确定他们自己拥有的该对象实例。 |
| 类型 (Types) | Type | 类型不仅用于属性中。它们在内部也非常重要,用于通知其他用户新创建的组件 (components)。因此,为了避免浪费网络流量,通常优先将它们编码为简单的数字。如果这种简写(数字代号)尚不可用,则将传输完整的类型名称。 从 2024.4.3.1170 版本开始,该简写由主机(Host)延迟且异步地生成。每个房间 (Session) 都有一个查找表。(猜测:对房间信息的需求可能是为什么它具有与“值(Values)”不同的独立实现的原因。) |
| 委托 (Delegates) | WorldDelegate | 委托引用特定对象实例的方法。网络消息包含用于标识实例的 RefID,以及该方法的名称/声明类型。 |
提示: 请注意,字符串(strings)、URIs 和 Nullable 在 ProtoFlux 中是“对象(objects)”,但在世界模型中是“值(values)”!
在处理 动态变量 (Dynamic Variables) 时这一点尤为明显。
泛型 (Generic Types)
泛型(Generic types)的特殊之处在于它们具有“类型参数(type arguments)”,在你使用它们之前,必须用另一种类型来填充(指定)这些参数。泛型允许程序员编写能够专门用于特定用例,而无需额外实现的代码。(编写一次,适用于多种类型)
它们通常用于存储或处理值的组件 (Components)。属性 (Properties) 和许多 ProtoFlux 节点也是通过泛型实现的。在节点浏览器、组件附加器或 场景检查器 (Scene Inspector Dialog) 中,可以通过类型名称后面的尖括号(<>)来识别它们。
提示: 必须在节点浏览器或组件附加器中指定类型参数,才能创建泛型节点或组件。
如果你想将泛型类型用作参数,请按照文章 组件中的复杂类型 (Complex Types in Components) 中的说明进行操作!
No comments to display
No comments to display