execute method

Future<bool?> execute(
  1. String caller,
  2. String propertyOrFunction,
  3. List arguments
)

Implementation

Future<bool?> execute(
    String caller, String propertyOrFunction, List<dynamic> arguments) async {
  if (scope == null) return null;
  var function = propertyOrFunction.toLowerCase().trim();

  switch (function) {
    case 'set':
      // value
      var value = S.item(arguments, 0);

      // property - default is value
      // we can now use dot notation to specify the property
      // rather than pass it as an attribute
      var property = S.item(arguments, 1);
      property ??= Binding.fromString(caller)?.key ?? property;

      Scope? scope = Scope.of(this);
      if (scope == null) return false;

      // set the variable
      scope.setObservable(property, value?.toString());
      return true;

    case 'addchild':

      // fml
      var xml = S.item(arguments, 0);

      // if index is null, add to end of list.
      int? index = S.toInt(S.item(arguments, 1));

      // silent
      bool silent = S.toBool(S.item(arguments, 2)) ?? true;

      if (xml == null || xml is! String) return true;

      // append
      await _appendXml(xml, index, silent);

      // force rebuild
      notifyListeners("rebuild", "true");

      return true;

    case 'removechild':

      // if index is null, remove all children before replacement.
      int? index = S.toInt(S.item(arguments, 0));

      // check for children then remove them
      if (children != null && index == null) {
        // dispose of the last item
        children!.last.dispose();

        // check if the list is greater than 0, remove at the final index.
        if (children!.isNotEmpty) children!.removeLast();
      } else if (children != null && index != null) {
        // check if index is in range, then dispose of the child at that index.
        if (index >= 0 && children!.length > index) {
          children![index].dispose();
          children!.removeAt(index);
        }
        // Could add handling for negative index removing from the end?
      }

      // force rebuild
      notifyListeners("rebuild", "true");
      return true;

    case 'removechildren':

      // dispose of existing children
      children?.forEach((child) => child.dispose());
      children = [];

      // force parent rebuild
      parent?.notifyListeners("rebuild", "true");
      return true;

    case 'replacechild':

      // fml
      var xml = S.item(arguments, 0);

      // if index is null, remove last child before replacement.
      int? index = S.toInt(S.item(arguments, 1));

      // silent
      bool silent = S.toBool(S.item(arguments, 2)) ?? true;

      if (xml == null || xml is! String) return true;

      // check for children then remove them
      if (children != null && index == null) {
        // dispose of the last item
        children!.last.dispose();

        // check if the list is greater than 0, remove at the final index.
        if (children!.isNotEmpty) children!.removeAt(children!.length - 1);
        print(index.toString());
      } else if (children != null && index != null) {
        // check if index is in range, then dispose of the child at that index.
        if (index >= 0 && children!.length > index) {
          children![index].dispose();
          children!.removeAt(index);
        }
        // Could add handling for negative index removing from the end?
      }

      // add elements
      await _appendXml(xml, index, silent);

      // force rebuild
      notifyListeners("rebuild", "true");

      return true;

    case 'replacechildren':

      // fml
      var xml = S.item(arguments, 0);

      // silent
      bool silent = S.toBool(S.item(arguments, 1)) ?? true;

      if (xml == null || xml is! String) return true;

      // check for children then remove them
      if (children != null) {
        for (var child in children!) {
          child.dispose();
        }
        children = [];
      }

      // add elements
      await _appendXml(xml, null, silent);

      // force rebuild
      notifyListeners("rebuild", "true");

      return true;

    case 'removewidget':

      // ineex
      int? index = (parent?.children?.contains(this) ?? false)
          ? parent?.children?.indexOf(this)
          : null;

      // index should never be null
      if (index != null) {
        // dispose of this model
        dispose();
        parent?.children?.removeAt(index);
      }

      // force parent rebuild
      parent?.notifyListeners("rebuild", "true");
      return true;

    case 'replacewidget':

      // fml
      var xml = S.item(arguments, 0);

      // get my position in my parents child list
      int? index = (parent?.children?.contains(this) ?? false)
          ? parent?.children?.indexOf(this)
          : null;

      // silent
      bool silent = S.toBool(S.item(arguments, 1)) ?? true;

      if (xml == null || xml is! String) return true;

      // index should never be null
      if (index != null) {
        // dispose of myself
        dispose();

        // remove myself from the list
        parent?.children?.removeAt(index);

        // add new fml
        await _appendXml(xml, index, silent);
      }

      // force parent rebuild
      parent?.notifyListeners("rebuild", "true");
      return true;
  }

  return false;
}