startup classage expr201 { main(String[] args) { create X(); } } classage X { X() { ::t(); } singleton plugger A { import void t0() import void t1() export void t1() { print("OK from export t1 of A"); } export void t2() { print("OK from export t2 of A"); print("now passive call for t1 from inside t2 of A"); t1(); print("passive call ends"); } } void t() { A x1, x2; print("[1]"); // if the following line is not commented out, runtime exception // will be thrown because the plugger is currently not satisfied. // A::t0(); print("[2]"); // now the t1 defined by A should be invoked, overriding case but // the plugger is currently not satisfied A::t1(); print("[3]"); // now the t2 defined by A should be invoked, pure export case A::t2(); print("[4]"); // the following line should have no effect, since currently // A is not satisfied by any plugins forall(h::A) {print("now inside forall before plugin:"); h..t2();} print("[5]"); //plugin happens here x1 = plugin Y with A >> B; print("[6]"); // now the t0 defined by B should be invoked, pure import case A::t0(); print("[7]"); // the following line has the same effect as above for the // singleton case x1..t0(); print("[8]"); // now the t1 defined by B should be invoked, overriding case A::t1(); print("[9]"); // the following line has the same effect as above for the // singleton case x1..t1(); print("[10]"); // now the t2 defined by A should be invoked, pure export case A::t2(); print("[11]"); // the following line has the same effect as above for the // singleton case x1..t2(); print("[12]"); // the following line should now invoke t2 defined by A, since // currently A is satisfied by one plugin forall(h::A) {print("now inside forall after plugin:"); h..t2(); } print("[13]"); // if the following line is not commented out, runtime exception // will be thrown because the plugger is singleton and can not be // plugged in with more than one plugee. // x2 = plugin Y with A >> B; print("[14]"); //unplug unplug x1; print("[15]"); // the following line should have no effect, since currently // A is not satisfied by any plugins forall(h::A) {print("now inside forall after unplug:"); h..t2();} print("[16]"); // if the following line is not commented out, runtime exception // will be thrown because the plugger is currently not satisfied. // A::t0(); print("[17]"); // However, this does not affect invocation for exports. We do allow // invocation on exports even if a plugger is currently not satisfied. A::t1(); A::t2(); print("[18]"); // if the following lines are not commented out, runtime exception // will be thrown because x1 is currently stale. // x1..t0(); // x1..t1(); // x1..t2(); print("[19]"); //cascaded plugin/unplug unplug (plugin Y with A >> B); return; } } classage Y { mixer B { export void t0() { print("OK from export t0 of Y"); return; } export void t1() { print("OK from export t1 of Y"); return; } } }