Skip to main content

类型 (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))可以通过不同的方式来实现(例如 BoxColliderSphereCollider 等)。

另见:枚举 (Enums),它是值类型的一个子类别。

世界模型 (World Model)

Resonite 的世界模型需要为多个用户保持一致。值在本地被存储在哪里,远没有它在网络中如何进行通信来得重要。

实际上,这意味着在处理组件及其属性时,我们必须区分以下类别:

类别 包含的所有类型 描述
值 (Values) 值类型 (Value Types)字符串 (strings)URIsNullableIEncodable 值将按原样写入网络消息中,并按原样从中读取。
引用 (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) 中的说明进行操作!