# Propagating Layer Activations in Async Method Calls

- [webwerkstatt demo page](https://lively-kernel.org/repository/webwerkstatt/demos/contextjs/AsyncLayerActivation.xhtml)

## Simple Implementation: Self Activation

The SpecialSyntaxWorkspaceLayer refines the delay method to activate itself. This allows the propagation of Layer Activation. 

```javascript  
  // when this is called
  cop.withLayers([L1], function() {
      (function() {
          $morph('Joe').foo() 
      }).bind(this).delay(2)
  })

  cop.create("SpecialSyntaxWorkspaceLayer").refineClass(Function, {
      delay: function() {
          var __method = this,
              args = Array.from(arguments),
              timeout = args.shift() * 1000;
          return window.setTimeout(function delayed() {
              return cop.withLayers([SpecialSyntaxWorkspaceLayer], function() {
                   return __method.apply(__method, args);
               })
          }, timeout);
      }
  })

  // SpecialSyntaxWorkspaceLayer.uninstall()
```

## Framework

Similar to Appeltauer's propagation of the layer activation through a service call, we can build the layer activation into our async call framework.


```javascript
log = function(s) {
   $morph("Log").textString += s +"\n" 
}

this.get("Joe").addScript(function foo() {
    log("Base>>foo")
    this.setFill(Color.red)
})

cop.create("L1").refineObject(this.get("Joe"), {
    foo: function() {
        log("L1>>foo")
        this.setFill(Color.green)
    }
});

cop.replayStack = function(layerStack, index, func) {
    if (index >= layerStack.length) { 
        return func()
    }
    var comp = layerStack[index](comp = layerStack[index)
    var cont = function() {
        cop.replayStack(layerStack, index + 1, func)
    }
    if (comp.withLayers)
        return cop.withLayers(comp.withLayers, cont)
    if (comp.withoutLayers)
        return cop.withoutLayers(comp.withLayers, cont)
    throw new Error("unknown layer composition")
};

// cop.withoutLayers([L1], function() {
    // return cop.withLayers([L1], function() {
        // return cop.LayerStack.clone()
    // })
// })

cop.create("DelayedLayerActivationLayer").refineClass(Function, {
    delay: function() {
        var __method = this,
            args = Array.from(arguments),
            timeout = args.shift() * 1000;
        var layerStack = cop.LayerStack.clone()
        return window.setTimeout(function delayed() {
            return cop.replayStack(layerStack, 1, function() {
                return __method.apply(__method, args)
            });
        }, timeout);
    }
});

DelayedLayerActivationLayer.beGlobal();

$morph('Joe').foo();

cop.withLayers([L1], function() {
    (function() {
        $morph('Joe').foo()
    }).bind(this).delay(2);
})

```