Class TSFNode

Unit

Declaration

type TSFNode = class(TX3DSingleField)

Description

X3D field holding a reference to a single node. It's defined in this unit, not in X3DFields, since it uses TX3DNode definition. NULL value of the field is indicated by Value field = nil.

Note that we store AllowedChildren list, which is a list of classes allowed as a Value (also nil is always allowed). But this is used only to produce warnings for a user. You should never assert that Value actually is one the requested classes. We want to keep here even not allowed items, because we want operation "read from VRML file + write to VRML file" to be as non-destructible as possible. So if user wrote invalid class hierarchy, we will output this invalid class hierarchy.

Hierarchy

Overview

Methods

Public constructor CreateUndefined(const AParentNode: TX3DFileItem; const AExposed: boolean; const AName: string); override;
Public constructor Create(const AParentNode: TX3DNode; const AExposed: boolean; const AName: string; const AAllowedChildrenClasses: array of TX3DNodeClass; const AValue: TX3DNode = nil); overload;
Public constructor Create(const AParentNode: TX3DNode; const AExposed: boolean; const AName: string; const AAllowedChildrenClasses: TX3DNodeClassesList; const AValue: TX3DNode = nil); overload;
Public constructor Create(const AParentNode: TX3DNode; const AExposed: boolean; const AName: string; const AnAllowedChildrenFunctionality: TNodeFunctionalityClass; const AValue: TX3DNode = nil); overload;
Public destructor Destroy; override;
Public procedure ParseValue(Lexer: TX3DLexer; Reader: TX3DReader); override;
Public procedure ParseXMLAttribute(const AttributeValue: string; Reader: TX3DReader); override;
Public procedure ParseXMLElement(Element: TDOMElement; Reader: TX3DReader); override;
Public function EqualsDefaultValue: boolean; override;
Public function Equals(SecondValue: TX3DField): boolean; override;
Public procedure Assign(Source: TPersistent); override;
Public procedure AssignValue(Source: TX3DField); override;
Public procedure AssignDefaultValueFromValue; override;
Public procedure UnassignDefaultValue; override;
Public class function X3DType: string; override;
Public class function CreateEvent(const AParentNode: TX3DFileItem; const AName: string; const AInEvent: boolean): TX3DEvent; override;
Public procedure WarningIfChildNotAllowed(Child: TX3DNode);
Public function ChildAllowed(Child: TX3DNode): boolean;
Public function CurrentChildAllowed: boolean;
Public function Enumerate(Func: TEnumerateChildrenFunction): Pointer;
Public procedure Send(const AValue: TX3DNode); overload;

Properties

Public property DefaultValue: TX3DNode read FDefaultValue write SetDefaultValue;
Public property DefaultValueExists: boolean read FDefaultValueExists write SetDefaultValueExists default false;
Public property Value: TX3DNode read FValue write SetValue;
Public property ParentNode: TX3DNode read FParentNode;
Public property WeakLink: boolean read FWeakLink write SetWeakLink default false;
Public property AutomaticWeakLink: Boolean read FAutomaticWeakLink write FAutomaticWeakLink default false;

Description

Methods

Public constructor CreateUndefined(const AParentNode: TX3DFileItem; const AExposed: boolean; const AName: string); override;

Construct a field allowing any children class. Suitable only for special cases. For example, in instantiated prototypes, we must initially just allow all children, otherwise valid prototypes with SFNode/MFNode would cause warnings when parsing.

Public constructor Create(const AParentNode: TX3DNode; const AExposed: boolean; const AName: string; const AAllowedChildrenClasses: array of TX3DNodeClass; const AValue: TX3DNode = nil); overload;
 
Public constructor Create(const AParentNode: TX3DNode; const AExposed: boolean; const AName: string; const AAllowedChildrenClasses: TX3DNodeClassesList; const AValue: TX3DNode = nil); overload;

Constructor that takes a list of allowed children classes. Note that we copy the contents of AAllowedChildrenClasses, not the reference.

Public constructor Create(const AParentNode: TX3DNode; const AExposed: boolean; const AName: string; const AnAllowedChildrenFunctionality: TNodeFunctionalityClass; const AValue: TX3DNode = nil); overload;

Constructor that allows as children any implementor of given functionality.

Public destructor Destroy; override;
 
Public procedure ParseValue(Lexer: TX3DLexer; Reader: TX3DReader); override;
 
Public procedure ParseXMLAttribute(const AttributeValue: string; Reader: TX3DReader); override;
 
Public procedure ParseXMLElement(Element: TDOMElement; Reader: TX3DReader); override;
 
Public function EqualsDefaultValue: boolean; override;
 
Public function Equals(SecondValue: TX3DField): boolean; override;
 
Public procedure Assign(Source: TPersistent); override;
 
Public procedure AssignValue(Source: TX3DField); override;
 
Public procedure AssignDefaultValueFromValue; override;
 
Public procedure UnassignDefaultValue; override;
 
Public class function X3DType: string; override;
 
Public class function CreateEvent(const AParentNode: TX3DFileItem; const AName: string; const AInEvent: boolean): TX3DEvent; override;
 
Public procedure WarningIfChildNotAllowed(Child: TX3DNode);

Checks is the Child allowed as a value of this SFNode, and makes WritelnWarning if not.

Check is allowed is done looking at AllowedChildrenAll and AllowedChildren properties.

Child must not be Nil.

WritelnWarning message will suggest that this Child is used as value of this node. In other words, you should only pass as Child a node that you want to assign as Value to this field, otherwise WritelnWarning message will be a little unsensible.

Public function ChildAllowed(Child: TX3DNode): boolean;
 
Public function CurrentChildAllowed: boolean;
 
Public function Enumerate(Func: TEnumerateChildrenFunction): Pointer;

Calls Func for our Value, assuming it's set (non-nil). The main use for this is to simplify implementation of TX3DNode.DirectEnumerateActive overrides in TX3DNode descendants.

Public procedure Send(const AValue: TX3DNode); overload;
 

Properties

Public property DefaultValue: TX3DNode read FDefaultValue write SetDefaultValue;

Default value of SFNode field.

While X3D specification says for all SFNode fields that their default value is NULL, this is not necessarily true for PROTO SFNode fiels. So we have to take into account that any DefaultValue is possible.

Note that this doesn't have to be Nil, but will be irrelevant if not DefaultValueExists. (Once I had an idea to automatically set DefaultValue to Nil when DefaultValueExists is set to False, but this was uncomfortable (like "what to do when DefaultValue is assigned non-nil when DefaultValueExists is false?").)

Freeing of this is automatically managed, just like the normal Value property. This means that you can simply set DefaultValue to Nil or some existing node, and eventual memory deallocation of previous DefaultValue node (if unused) will happen automatically.

Public property DefaultValueExists: boolean read FDefaultValueExists write SetDefaultValueExists default false;
 
Public property Value: TX3DNode read FValue write SetValue;
 
Public property ParentNode: TX3DNode read FParentNode;

VRML node containing this field. May be Nil if unknown, in special cases.

Note that this property is exactly the same as TX3DFieldOrEvent.ParentNode, contains always the same value. But this is declared as TX3DNode, so it's more comfortable.

Public property WeakLink: boolean read FWeakLink write SetWeakLink default false;

Use weak links to deal with cycles in the X3D graph.

Marking a field as a weak link can only be done when the field value is empty, right when the field is created, in TX3DNode.CreateNode descendant.

Being a weak link means two things:

  1. The nodes inside a weak link are not enumerated when traversing the X3D graph in any way. This includes TX3DNode.EnumerateNodes, TX3DNode.Traverse and all others. Nodes implementing TX3DNode.DirectEnumerateActive should also omit these fields.

  2. A weak link does not create a reference count preventing the node from being freed (or freeing it automatically when ref count drops to zero). Instead, weak links merely observe the nodes, and automatically set their value to Nil when the node gets freed.

If effect, this avoids loops when enumerating (and avoids recursive loops in reference counts, which would cause memory leaks), but use this only when you know that the node must occur somewhere else in the X3D graph anyway (or it's OK to ignore it). For example, this is useful for TGeneratedShadowMapNode.Light, as we know that the light must occur somewhere else in the graph anyway to be useful.

Public property AutomaticWeakLink: Boolean read FAutomaticWeakLink write FAutomaticWeakLink default false;

Automatically use WeakLink if field would contain a node cycle. Using WeakLink=true allows to handle node cycles, like common in VRML/X3D

DEF Xxx Transform {
  children [
    ...
    Script {
      ...
      inputOutput SFNode someField USE Xxx
    }
  ]
}

When AutomaticWeakLink, the given field contents may, but don't have to, be a node cycle – we only use WeakLink when necessary.

Use this only for fields that are not enumerated by DirectEnumerateActive, Traverse etc., otherwise you create a cycle in nodes that we generally cannot handle.


Generated by PasDoc 0.16.0.