1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
//! Behavior tree nodes and internal node logic.

use std::fmt;
use status::Status;

/// Represents a generic node
///
/// The logic of the node is controlled by the supplied `Internals` object.
/// Nodes are considered to have been run to completion when they return either
/// `Status::Succeeded` or `Status::Failed` when ticked. If they are ticked after
/// completion, they will be reset before the tick logic is executed.
///
/// This class is largely just a wrapper around an `Internals` object. This is
/// to enforce some runtime behavior.
pub struct Node
{
	/// The status from the last time this node was ticked
	status: Status,

	/// The internal logic for this node
	internals: Box<Internals>,
}
impl Node
{
	/// Creates a new `Node` with the given `Internals`.
	///
	/// The internals are used to govern the tick logic of the node.
	pub fn new<I>(internals: I) -> Node
		where I: Internals + 'static
	{
		Node {
			status: Status::Initialized,
			internals: Box::new(internals),
		}
	}

	/// Ticks the node a single time.
	///
	/// If the node is currently considered to have run to completion, this
	/// will call `Node::reset` on the node before calling the internal tick
	/// logic.
	pub fn tick(&mut self) -> Status
	{
		// Reset the node if it has already been completed
		if self.status.is_done() {
			self.reset();
		}

		// Tick the internals
		self.status = (*self.internals).tick();
		return self.status;
	}

	/// Resets the node.
	///
	/// This returns the node to a state that is identical to when it was first
	/// created.
	pub fn reset(&mut self)
	{
		self.status = Status::Initialized;
		(*self.internals).reset();
	}

	/// Gets the current status of the node.
	///
	/// This value will match the return value of the last call to `Node::tick`.
	pub fn status(&self) -> Status
	{
		self.status
	}

	/// Returns a vector containing references to all of this node's children.
	pub fn children(&self) -> Option<Vec<&Node>>
	{
		(*self.internals).children()
	}

	/// Returns the name of this node.
	///
	/// This will usually be the type of the node, e.g. "Sequence". There are
	/// plans to allow nodes to have unique names.
	pub fn name(&self) -> &'static str
	{
		(*self.internals).type_name()
	}

	#[cfg(feature = "lcm")]
	/// Creates a new `NodeMsg` from this node
	pub fn as_message(&self) -> ::node_message::NodeMsg
	{
		let kids = if let Some(kids) = self.children() {
			kids.iter().map(|c| c.as_message() ).collect()
		} else { Vec::new() };

		::node_message::NodeMsg {
			num_children: kids.len() as i32,
			children: kids,
			status: self.status as i8,
			name: self.name().to_string(),
		}
	}
}
impl fmt::Display for Node
{
	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
	{
		write!(f, "{}:( status = {:?}", self.name(), self.status())?;
		if let Some(children) = self.children() {
			for child in children {
				write!(f, ", {}", child)?;
			}
		}
		write!(f, " )")
	}
}

/// The internal logic of a node.
///
/// This is the object that controls the tick behavior of the `Node`, with
/// `Node` just being a wrapper to enforce some runtime behavior.
pub trait Internals
{
	/// Ticks the internal state of the node a single time.
	///
	/// Node internals should not automatically reset themselves. If a node has
	/// been run to completion, the `Node` that holds this object will call
	/// `reset` before ticking the node.
	///
	/// In other words, the `Internals` will only ever be ticked when the node
	/// state is either `Status::Running` or `Status::Initialized`.
	fn tick(&mut self) -> Status;

	/// Resets the internal state of the node.
	///
	/// This sets the node to a state that is identical to a newly constructed
	/// node. Note that this could be called when the node is in any state.
	fn reset(&mut self);

	/// Returns a vector of references to this node's children.
	///
	/// Default behavior is to return `None`, which should be suitable for any
	/// leaf node.
	fn children(&self) -> Option<Vec<&Node>>
	{
		None
	}

	/// Returns the type of the node as a string literal.
	///
	/// In general, this should be the name of the node type. However, there
	/// are plans to add a "name" property to the `Node` struct, at which point
	/// this function will be depricated.
	fn type_name(&self) -> &'static str;
}