Tuesday, April 17, 2007

Why does Delegate use Manager?

XCube_Delegate is a core feature of Cube layer as well as XCube_Service. (But, XCube_Service is not completed in 0.9.)

XCube_Delegate is based on the delegate type of C#. And, The delegate type of C# is based on function pointers of C. And, function pointers are based on jmp operation of machine language...

XCube_Delegate is uniforming callback methods. You have to understand that XCube_Delegate wants to be TYPE. But, we can not extend PHP grammer by PHP script. So XCube_Delegate is a class.

You may understand XCube_Delegate with C# delegate, because function pointers of C are difficult a little. I say the following code is there;

class Foo {
  private int mVal = 0;

  public Foo() {}

  int Add(int dest)  {
    mVal += dest;
    return mVal;
  }

When you hope to exchange Add(), you may use delegate.

class Foo {
  private int mVal = 0;

  public delegate int Calculate(int src, int dest);
  public Calculate AddEx;

  public Foo() {}

  public int Add(int dest) {
    return mVal = AddEx(mVal, dest);
  }
}

The method was changed to another member type. One who uses this class can add one's method to this delegate.

Foo instance = new Foo();
instance.AddEx += myAddg
instance.Add(20); //< instance.mVal = 20

But, XCube_Delegate can not have return values. So let's modify this a little.

class Foo {
  private int mVal = 0;

  public delegate void Calculate(int src, int dest, ref int out);
  public Calculate AddEx;

  public Foo() {}

  public int Add(int dest) {
    int ret;
    AddEx(mVal, dest, ret);
    return mVal = ret;
  }
}

OK, you may rewrite this code on XOOPS Cube with PHP.

class Foo {
  val $mVal = 0;

  val $AddEx

  function Foo() {
    $this->AddEx =& new XCube_Delegate("int, int, int&");
  }

  function Add($dest) {
    $ret = 0;
    $this->AddEx($this->mVal, $dest, new XCube_Ref($ret));
    return $this->mVal = $ret;
  }
}

If delegate members of a certain instance are visible for you, you don't need to think about the existence of XCube_DelegateManager. You may access members directly as well as C# example. But, in PHP, it's impossible to assure that you can access all of members of all classes anywhere. Because PHP is dynamic language not compile language. Classes which you hope to use may not have been loaded, when you hope to access them. This is a problem before scope. If you know all members of a certain class, you can not use the class which is not defined!

XCube_DelegateManager can solve this timing problem by the lazy mechanism.

But, registered delegates to the manager have to have shared functions. See the following:

case 1)
class Foo {
  var $mFunc;

  function Foo() {
    $this->mFunc =& new XCube_Delegate();
  }
}

$instanceA =& new Foo();
$instanceB =& new Foo();

$instanceA->add("myAddA");
$instanceB->add("myAddB");

// call myAddA
$instanceA->mFunc->Call();

// call myAddB
$instanceB->mFunc->Call();

In this case, it's possible to add different functions to each instance. But, if that delegate is registered to the manager, your two functions are added all instances.

case 1)
class Foo {
  var $mFunc;

  function Foo() {
    $this->mFunc =& new XCube_Delegate();
    $this->mFunc->register("Foo.Func");
  }
}

$instanceA =& new Foo();
$instanceB =& new Foo();

$instanceA->add("myAddA");
$instanceB->add("myAddB");

// call myAddA & myAddB
$instanceA->mFunc->Call();
$instanceB->mFunc->Call();

Therefore, registered delegates are like static members.

No comments: