/** * This method executes the tasks define in the pipeline. * * @access public * @param BT\Exchange $exchange the given exchange to process * @param string $id the id of behavior tree to run * @return integer the status code */ public function run(BT\Exchange $exchange, $id = 'BEHAVE') { // http://aigamedev.com/open/article/popular-behavior-tree-design/ $factory = new Spring\XMLObjectFactory(Spring\Data\XML::load($this->file)); $registry = $factory->getParser()->getRegistry(); $registry->putEntry(array('action', BT\Task::NAMESPACE_URI), new BT\Object\Factory\ActionElement()); $registry->putEntry(array('blackboard', BT\Task::NAMESPACE_URI), new BT\Object\Factory\BlackboardElement()); $registry->putEntry(array('branch', BT\Task::NAMESPACE_URI), new BT\Object\Factory\BranchElement()); $registry->putEntry(array('breakpoint', BT\Task::NAMESPACE_URI), new BT\Object\Factory\BreakpointElement()); $registry->putEntry(array('composite', BT\Task::NAMESPACE_URI), new BT\Object\Factory\CompositeElement()); $registry->putEntry(array('condition', BT\Task::NAMESPACE_URI), new BT\Object\Factory\ConditionElement()); $registry->putEntry(array('decorator', BT\Task::NAMESPACE_URI), new BT\Object\Factory\DecoratorElement()); $registry->putEntry(array('entry', BT\Task::NAMESPACE_URI), new BT\Object\Factory\EntryElement()); $registry->putEntry(array('leaf', BT\Task::NAMESPACE_URI), new BT\Object\Factory\LeafElement()); $registry->putEntry(array('logger', BT\Task::NAMESPACE_URI), new BT\Object\Factory\LoggerElement()); $registry->putEntry(array('parallel', BT\Task::NAMESPACE_URI), new BT\Object\Factory\ParallelElement()); $registry->putEntry(array('picker', BT\Task::NAMESPACE_URI), new BT\Object\Factory\PickerElement()); $registry->putEntry(array('ref', BT\Task::NAMESPACE_URI), new BT\Object\Factory\RefElement()); $registry->putEntry(array('resetter', BT\Task::NAMESPACE_URI), new BT\Object\Factory\ResetterElement()); $registry->putEntry(array('selector', BT\Task::NAMESPACE_URI), new BT\Object\Factory\SelectorElement()); $registry->putEntry(array('semaphore', BT\Task::NAMESPACE_URI), new BT\Object\Factory\SemaphoreElement()); $registry->putEntry(array('sequence', BT\Task::NAMESPACE_URI), new BT\Object\Factory\SequenceElement()); $registry->putEntry(array('policy', BT\Task::NAMESPACE_URI), new BT\Object\Factory\PolicyElement()); $registry->putEntry(array('stub', BT\Task::NAMESPACE_URI), new BT\Object\Factory\StubElement()); $registry->putEntry(array('tasks', BT\Task::NAMESPACE_URI), new BT\Object\Factory\TasksElement()); $registry->putEntry(array('ticker', BT\Task::NAMESPACE_URI), new BT\Object\Factory\TickerElement()); $registry->putEntry(array('timer', BT\Task::NAMESPACE_URI), new BT\Object\Factory\TimerElement()); if ($factory->hasObject($id)) { $object = $factory->getObject($id); if ($object instanceof BT\Task) { return BT\Task\Handler::process($object, $exchange); } } return BT\Task\Status::ERROR; }
/** * This method retypes any objects matching either the type mappings or name mappings. * * @access public * @static * @param \SimpleXMLElement $xml the Spring XML to be processed * @param array $mappings the type and name mappings */ public static function retype(\SimpleXMLElement $xml, array $mappings) { if (!empty($mappings)) { $xml->registerXPathNamespace('spring', Spring\Data\XML::NAMESPACE_URI); $objects = $xml->xpath('//spring:object'); array_walk($objects, function (\SimpleXMLElement &$object) use($mappings) { $attributes = $object->attributes(); if (isset($attributes['type'])) { $type = Spring\Data\XML::valueOf($attributes['type']); if (isset($mappings['types'][$type])) { $attributes['type'] = $mappings['types'][$type]; } } if (isset($attributes['name'])) { $names = preg_split('/(,|;|\\s)+/', Spring\Data\XML::valueOf($attributes['name'])); foreach ($names as $name) { if (isset($mappings['ids'][$name])) { $attributes['type'] = $mappings['ids'][$name]; } } } if (isset($attributes['id'])) { $id = Spring\Data\XML::valueOf($attributes['id']); if (isset($mappings['ids'][$id])) { $attributes['type'] = $mappings['ids'][$id]; } } }); } }
/** * This method adds a "value" node to the DOM structure. * * @access protected * @param \SimpleXMLElement $root a reference to the root node * @param \SimpleXMLElement $node a reference to the current node * @param mixed $data the data to be added to the node * @param string $type the type of data */ protected function addValue($root, $node, $data, $type) { switch ($type) { case 'boolean': $value = !$data ? 'false' : 'true'; $child = $node->addChild('value', $value); $child->addAttribute('type', 'boolean'); break; case 'integer': case 'double': $child = $node->addChild('value', $data); $child->addAttribute('type', $type); break; case 'string': case 'unknown type': default: $value = '' . $data; $value = Core\Data\Charset::encode($value, $this->encoding[0], $this->encoding[1]); $value = Spring\Data\XML::entities($value); $child = $node->addChild('value', $value); $child->addAttribute('type', 'string'); if (strlen(trim($value)) < strlen($value)) { $child->addAttribute('xml:space', 'preserve', 'http://www.w3.org/XML/1998/namespace'); } break; } }
/** * This method returns the processed resource as a collection. * * @access public * @param string $path the path to the value to be returned * @return mixed the resource as a collection */ public function read($path = null) { $root = Spring\Data\XML::load($this->file); $collection = $this->parseOuterObjectElements($root, $root); if ($path !== null) { $collection = Config\Helper::factory($collection)->getValue($path); } return $collection; }
/** * This method evaluates whether the specified string is a valid idref. * * @access public * @static * @param string $token the string to be evaluated * @param \SimpleXMLElement $resource the resource to query * @return boolean whether the specified string is a valid * idref * @throws Throwable\InvalidArgument\Exception indicates that an argument is incorrect * * @see http://stackoverflow.com/questions/1257867/regular-expressions-and-xpath-query */ public static function isIdref($token, \SimpleXMLElement $resource = null) { if ($resource !== null) { if (!static::isId($token)) { throw new Throwable\InvalidArgument\Exception('Invalid argument detected (id: :id).', array(':id' => $token)); } $resource->registerXPathNamespace('spring', Spring\Data\XML::NAMESPACE_URI); $nodes = $resource->xpath("/spring:objects/spring:object[@id='{$token}' or contains(@name,'{$token}')]"); $nodes = array_filter($nodes, function (\SimpleXMLElement &$node) use($token) { $attributes = $node->attributes(); return isset($attributes['id']) && Spring\Data\XML::valueOf($attributes['id']) == $token || isset($attributes['name']) && in_array($token, preg_split('/(,|;|\\s)+/', Spring\Data\XML::valueOf($attributes['name']))); }); return !empty($nodes); } return static::isId($token); }
/** * This method returns the first value associated with the specified object. * * @access public * @param mixed $value the object to be processed * @param string $source_encoding the source encoding * @param string $target_encoding the target encoding * @return mixed the value that was wrapped by * the object */ public function valueOf($value, $source_encoding = 'UTF-8', $target_encoding = 'UTF-8') { return Spring\Data\XML::valueOf($value, $source_encoding, $target_encoding); }