1/*
2 * Copyright 2015, Rene Gollent, rene@gollent.com.
3 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
4 * Distributed under the terms of the MIT License.
5 */
6#ifndef VALUE_NODE_H
7#define VALUE_NODE_H
8
9
10#include <String.h>
11
12#include <Referenceable.h>
13
14
15class TeamTypeInformation;
16class Type;
17class Value;
18class ValueLoader;
19class ValueLocation;
20class ValueNodeChild;
21class ValueNodeContainer;
22
23
24enum {
25	VALUE_NODE_UNRESOLVED	= 1
26};
27
28
29class ValueNode : public BReferenceable {
30public:
31								ValueNode(ValueNodeChild* nodeChild);
32	virtual						~ValueNode();
33
34			ValueNodeChild*		NodeChild() const	{ return fNodeChild; }
35
36	virtual	const BString&		Name() const;
37	virtual	Type*				GetType() const = 0;
38
39	virtual	status_t			ResolvedLocationAndValue(
40									ValueLoader* valueLoader,
41									ValueLocation*& _location,
42									Value*& _value) = 0;
43									// returns references, a NULL value can be
44									// returned
45
46			// locking required
47
48			ValueNodeContainer*	Container() const
49									{ return fContainer; }
50			void				SetContainer(ValueNodeContainer* container);
51
52			virtual bool		ChildCreationNeedsValue() const
53									{ return false; }
54			bool				ChildrenCreated() const
55									{ return fChildrenCreated; }
56
57	virtual	status_t			CreateChildren(TeamTypeInformation* info) = 0;
58	virtual	int32				CountChildren() const = 0;
59	virtual	ValueNodeChild*		ChildAt(int32 index) const = 0;
60
61	// optional virtual hooks for container type value nodes such as
62	// arrays that may contain a variable (and potentially quite large)
63	// number of children. The calls below should be implemented for such
64	// node types to allow the upper layers to be aware of this, and to be
65	// able to request that only a subset of children be created.
66	virtual	bool				IsRangedContainer() const;
67	virtual	bool				IsContainerRangeFixed() const;
68									// indicates that the user can't
69									// arbitrarily go outside of the
70									// specified/supported range.
71	virtual	void				ClearChildren();
72	virtual	status_t			CreateChildrenInRange(
73									TeamTypeInformation* info,
74									int32 lowIndex, int32 highIndex);
75	virtual	status_t			SupportedChildRange(int32& lowIndex,
76									int32& highIndex) const;
77
78			status_t			LocationAndValueResolutionState() const
79									{ return fLocationResolutionState; }
80			void				SetLocationAndValue(ValueLocation* location,
81									Value* value, status_t resolutionState);
82			ValueLocation*		Location() const	{ return fLocation; }
83			Value*				GetValue() const	{ return fValue; }
84									// immutable after SetLocationAndValue()
85
86protected:
87			ValueNodeContainer*	fContainer;
88			ValueNodeChild*		fNodeChild;
89			ValueLocation*		fLocation;
90			Value*				fValue;
91			status_t			fLocationResolutionState;
92			bool				fChildrenCreated;
93};
94
95
96class ValueNodeChild : public BReferenceable {
97public:
98								ValueNodeChild();
99	virtual						~ValueNodeChild();
100
101	virtual	const BString&		Name() const = 0;
102	virtual	Type*				GetType() const = 0;
103	virtual	ValueNode*			Parent() const = 0;
104
105	virtual	bool				IsInternal() const;
106	virtual	status_t			CreateInternalNode(ValueNode*& _node);
107
108	virtual	status_t			ResolveLocation(ValueLoader* valueLoader,
109									ValueLocation*& _location) = 0;
110									// returns a reference
111
112			// locking required
113
114			ValueNodeContainer*	Container() const
115									{ return fContainer; }
116			void				SetContainer(ValueNodeContainer* container);
117
118			ValueNode*			Node() const	{ return fNode; }
119			void				SetNode(ValueNode* node);
120
121			status_t			LocationResolutionState() const
122									{ return fLocationResolutionState; }
123			ValueLocation*		Location() const;
124									// immutable after SetLocation()
125			void				SetLocation(ValueLocation* location,
126									status_t resolutionState);
127
128protected:
129			ValueNodeContainer*	fContainer;
130			ValueNode*			fNode;
131			ValueLocation*		fLocation;
132			status_t			fLocationResolutionState;
133};
134
135
136class ChildlessValueNode : public ValueNode {
137public:
138								ChildlessValueNode(ValueNodeChild* nodeChild);
139
140	virtual	status_t			CreateChildren(TeamTypeInformation* info);
141	virtual	int32				CountChildren() const;
142	virtual	ValueNodeChild*		ChildAt(int32 index) const;
143};
144
145
146#endif	// VALUE_NODE_H
147