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);
      if (property == null) property = Binding.fromString(caller)?.key ?? property;

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

      // set the variable
      scope.setObservable(property, value != null ? value.toString() : null);
      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 (this.children != null && index == null)
      {
        // dispose of the last item
        this.children!.last.dispose();

        // check if the list is greater than 0, remove at the final index.
        if (this.children!.length > 0) this.children!.removeLast();
      }

      else if (this.children != null && index != null)
      {
        // check if index is in range, then dispose of the child at that index.
        if (index >= 0 && this.children!.length > index) {
          this.children![index].dispose();
          this.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
      this.children?.forEach((child) => child.dispose());
      this.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 (this.children != null && index == null)
      {
        // dispose of the last item
        this.children!.last.dispose();

        // check if the list is greater than 0, remove at the final index.
        if(this.children!.length > 0) this.children!.removeAt(children!.length - 1);
        print(index.toString());
      }

      else if (this.children != null && index != null)
      {
        // check if index is in range, then dispose of the child at that index.
        if (index >= 0 && this.children!.length > index)
        {
          this.children![index].dispose();
          this.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 (this.children != null)
      {
        this.children!.forEach((child)
        {
          child.dispose();
        });
        this.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
        this.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
        this.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;
}