oagnodes 0.0.1 copy "oagnodes: ^0.0.1" to clipboard
oagnodes: ^0.0.1 copied to clipboard

outdated

A collection of classes to create and manage behavior trees and state machines.

A library for Dart developers.

Created from templates made available by Stagehand under a BSD-style license.

Usage #

A simple usage example:

import 'dart:math';
import 'package:oagnodes/oagnodes.dart';

void main() {
  final counter = Counter(1);
  final incrementer = RandomIncrementer(upperBound: 59);
  final sm = StateMachine(CounterState.values);

  final counterIncrementer = IncrementCounter(counter, incrementer);

  // the add state repeatedly calls `counterIncrementer`.
  sm.define(
    CounterState.add,
    update: Sequence(
      [
        counterIncrementer,
        makeClosure(action: () => print('counter.value = ${counter.value}'))
      ],
      isPartial: false,
    ),
    enter: makeClosure(
        action: () =>
            print('ENTER ${CounterState.add} @ counter = ${counter.value}')),
    exit: makeClosure(
        action: () =>
            print('EXIT ${CounterState.add} @ counter = ${counter.value}')),
  );

  // the subtract state repeatedly calls `counterIncrementer`.
  sm.define(
    CounterState.subtract,
    update: Sequence(
      [
        counterIncrementer,
        makeClosure(action: () => print('counter.value = ${counter.value}'))
      ],
      isPartial: false,
    ),
    enter: makeClosure(
        action: () => print(
            'ENTER ${CounterState.subtract} @ counter = ${counter.value}')),
    exit: makeClosure(
        action: () => print(
            'EXIT ${CounterState.subtract} @ counter = ${counter.value}')),
  );

  /// define a transition from the add state to the subtract state
  /// condition is `counter.value >= 512`
  sm.transition(
    from: CounterState.add,
    to: CounterState.subtract,
    on: Closure(() => counter.value > 512 ? Status.success : Status.failure),
  );

  const interval = 5;
  final intervalMonitor = DurationMonitor(
    counterIncrementer,
    interval: interval,
    expecting: Status.success,
    waiting: Status.failure,
  );

  /// define a transition from the subtract state to the add state
  /// condition is `counter.value <= 0 || `or the state machine has been in the add state
  /// for at least `interval` milliseconds.
  /// the subtract continually decrements the counter.value in every
  /// call to `update()`.
  sm.transition(
    from: CounterState.subtract,
    to: CounterState.add,
    on: Selector(
      [
        Sequence([intervalMonitor, Print('transitioned due to time')],
            isPartial: false),
        Closure(() => counter.value <= 0 ? Status.success : Status.failure),
      ],
      isPartial: true,
    ),
  );

  // set the current state machine state
  sm.set(to: CounterState.add);

  // get the current state of the state machine
  var previousState = sm.current;

  // update until state switch occurs
  while (sm.current == previousState) {
    sm.update();
  }

  previousState = sm.current;

  // update until state switch occurs
  while (sm.current == previousState) {
    sm.update();
  }
}

/// Two state machine states for [Counter] instances: adding and subtracting
enum CounterState { add, subtract }

/// Simple data structure to pass `value` around different nodes/states.
class Counter {
  int value;

  Counter(final this.value);
}

/// Base class/interface for a class that returns some integer value.
abstract class Incrementer {
  int getValue();
}

/// Concrete implementation of [Incrementer] that returns a random
/// positive or negative integer from the `getValue()` method up to
/// the argument `upperBound` (exclusive).
class RandomIncrementer implements Incrementer {
  final Random _random = Random();
  final int _upperBound;

  RandomIncrementer({required int upperBound}) : _upperBound = upperBound;

  @override
  int getValue() => _random.nextBool()
      ? _random.nextInt(_upperBound)
      : -_random.nextInt(_upperBound);
}

/// Concrete [DataNode] subclass that computes on an instance of the [Counter]
/// class using a dependency injected [Incrementer] instance.
///
/// A call to the `update()` method of this [Node] subtype will add to the
/// `value` data member of its [Counter] instance.
class IncrementCounter extends DataNode<Counter> {
  final Incrementer _incrementer;

  IncrementCounter(Counter data, this._incrementer) : super(data);

  @override
  Status update() {
    data.value += _incrementer.getValue();
    return Status.success;
  }
}

Features and bugs #

Please file feature requests and bugs at the github repository.

0
likes
0
pub points
0%
popularity

Publisher

unverified uploader

A collection of classes to create and manage behavior trees and state machines.

Repository (GitHub)
View/report issues

License

unknown (LICENSE)

More

Packages that depend on oagnodes