Minahito
minah****@users*****
2006年 6月 26日 (月) 12:22:54 JST
Index: xoops2jp/html/kernel/XCube_Delegate.class.php diff -u xoops2jp/html/kernel/XCube_Delegate.class.php:1.1.2.2 xoops2jp/html/kernel/XCube_Delegate.class.php:1.1.2.3 --- xoops2jp/html/kernel/XCube_Delegate.class.php:1.1.2.2 Fri Jun 23 10:27:49 2006 +++ xoops2jp/html/kernel/XCube_Delegate.class.php Mon Jun 26 12:22:54 2006 @@ -1,6 +1,6 @@ <?php /** - * @version $Id + * @version $Id: XCube_Delegate.class.php,v 1.1.2.3 2006/06/26 03:22:54 minahito Exp $ */ @@ -22,9 +22,22 @@ } } +define("XCUBE_DELEGATE_PRIORITY_FIRST", 0); +define("XCUBE_DELEGATE_PRIORITY_NORMAL", 50); +define("XCUBE_DELEGATE_PRIORITY_FINAL", 100); + /** * This is simple mechanism for common delegation in XCube. * + * A delegate can have $callback as connected function, $filepath for lazy + * loading and $priority as order indicated. + * + * "Priority" + * Default of this parameter is XCUBE_DELEGATE_PRIORITY_NORMAL. Usually, this + * parameter isn't specified. Plus, the magic number should be used to specify + * priority. Use XCUBE_DELEGATE_PRIORITY_FIRST or XCUBE_DELEGATE_PRIORITY_FINAL + * with Addition and Subtraction. (e.x. XCUBE_DELEGATE_PRIORITY_NORMAL - 1 ) + * * [Notice] * This is the candidate as new delegate style, which has foolish name to escape * conflict with old XCube_Delegate. After replacing, we'll change all. @@ -32,18 +45,66 @@ class XCube_NewDelegate { var $_mSignatures = array(); + + /** + * This is ID for $_mCallbacks and $_mPriorities, and counted up at add(). + * + * @var int + */ + var $_mCurrentID = 0; + + /** + * This is Array for callback type data. + * + * @var array + */ var $_mCallbacks = array(); - var $_mCallbackInstances = array(); - var $_mCallbackPaths = array(); + /** + * This is Array that has priorities for _mCallbacks. The key is the key of + * _mCallbacks. The value is priority. + * + * @var array for int + */ + var $_mPriorities = array(); + + /** + * This is Array that has file path for _mCallbacks. + * + * @var array for string + */ + var $_mCallbackPaths = array(); + + /** + * @var bool + */ var $_mHasCheckSignatures = false; /** - * If register() is failed, this flag become true. + * If register() is failed, this flag become true. That problem is raised, + * when register() is called before $root come to have the delegate + * manager. + * + * @var bool */ var $_mIsLazyRegister = false; + + /** + * This is register name for lazy registering. + */ var $_mLazyRegisterName = null; + /** + * Constructor. The parameter of the constructor is a variable argument + * style to specify the sigunature of this delegate. If the argument is + * empty, signature checking doesn't work. Empty arguments are good to + * use in many cases. But, that's important to accent a delegate for making + * rightly connected functions. + * + * [Sample] + * $delegate =& new XCube_Delegate("string", "string"); + * + */ function XCube_NewDelegate() { if (func_num_args() > 0) { @@ -51,6 +112,13 @@ } } + /** + * Set signatures for this delegate. By this member function, this function + * will come to check arguments with following signatures at call(). + * + * @access privated + * @param $args array + */ function _setSignatures($args) { $this->_mSignatures = $args; @@ -60,6 +128,7 @@ $this->_mSignatures[$i] = substr($this->_mSignatures[$i], 0, $idx); } } + $this->_mHasCheckSignatures = true; } /** @@ -86,41 +155,36 @@ } /** - * Connect static functions or static member functions to this object. + * Connect any functions to this object. This member function is virtual + * overload by sigunatures. + * + * add(callback $callback, int priority = XCUBE_DELEGATE_PRIORITY_NORMAL); + * add(callback $callback, string filepath = null); + * add(callback $callback, int priority =... , string filepath=...); * * @access public - * @param $func callback + * @return void */ - function add($func, $path = null) + function add($callback, $param2 = null, $param3 = null) { - if (strstr($func, "::")) { - $tmp = explode("::", $func); - $this->_mCallbackInstances[] = $tmp[0]; - $this->_mCallbacks[] = $tmp[1]; - $this->_mCallbackPaths[] = $path; + $priority = XCUBE_DELEGATE_PRIORITY_NORMAL; + $filepath = null; + if ($param2 !== null && is_int($param2)) { + $priority = XCUBE_DELEGATE_PRIORITY_NORMAL; + $filepath = ($param3 !== null && is_string($param3)) ? $param3 : null; } - else { - $this->_mCallbackInstances[] = null; - $this->_mCallbacks[] = $func; - $this->_mCallbackPaths[] = $path; + elseif ($param2 !== null && is_string($param2)) { + $filepath = $param2; } + + $this->_mCallbacks[$this->_mCurrentID] = $callback; + $this->_mPriorities[$this->_mCurrentID] = $priority; + $this->_mCallbackPaths[$this->_mCurrentID] = $filepath; + + $this->_mCurrentID++; } /** - * Conect member functions(=instance method) to this object. - * - * @access public - * @param $obj Object - * @param $method string - */ - function addMethod(&$obj, $method) - { - $this->_mCallbackInstances[] =& $obj; - $this->_mCallbacks[] = $method; - $this->_mCallbackPaths[] = null; - } - - /** * Call connected functions. * * @access public @@ -174,13 +238,13 @@ case "string": if (!empty($args[$i]) && is_string($args[$i])) { - return; + return false; } break; default: if (!is_a($args[$i], $this->_mSignatures[$i])) { - return; + return false; } } } @@ -195,24 +259,30 @@ $argstr = "()"; } + asort($this->_mPriorities); + // // We have to use eval in the case of an instance method because // call_user_func() can't handle references rightly. // - foreach (array_keys($this->_mCallbackInstances) as $key) { - if (is_object($this->_mCallbackInstances[$key]) && method_exists($this->_mCallbackInstances[$key], $this->_mCallbacks[$key])) { - eval('$this->_mCallbackInstances[$key]->' . $this->_mCallbacks[$key] . $argstr); + foreach (array_keys($this->_mPriorities) as $id) { + $callback =& $this->_mCallbacks[$id]; + + $staticFlag = true; + + if (is_array($callback) && count($callback) == 2) { + if (is_object($callback[0]) && method_exists($callback[0], $callback[1])) { + eval('$callback[0]->' . $callback[1] . $argstr); + $staticFlag = false; + } } - else { - $path = $this->_mCallbackPaths[$key]; - if ($path != null && file_exists($path)) { - require_once $path; + + if ($staticFlag) { + if ($this->_mCallbackPaths[$id] != null && file_exists($this->_mCallbackPaths[$id])) { + require_once $this->_mCallbackPaths[$id]; } - if ($this->_mCallbackInstances[$key] != null && is_callable(array($this->_mCallbackInstances[$key], $this->_mCallbacks[$key]))) { - call_user_func_array(array($this->_mCallbackInstances[$key], $this->_mCallbacks[$key]), $args); - } - else if(function_exists($this->_mCallbacks[$key])) { - call_user_func_array($this->_mCallbacks[$key], $args); + if (is_callable($callback)) { + call_user_func_array($callback, $args); } } } @@ -220,13 +290,17 @@ } /** - * This is the proxy for un-registed delegate objects. + * This is the agent of un-registered delegate objects. Usually, connected + * functions can't be added to un-registered delegates. When destination + * delegates are un-registered yet, this manager is keeping those functions + * and parameters until the destination delegate will be registered. + * + * In other words, this class realizes lazy delegate registering. */ class XCube_DelegateManager { var $_mCallbacks = array(); - var $_mCallbackInstances = array(); - var $_mCallbackPaths = array(); + var $_mCallbackParameters = array(); var $_mDelegates = array(); @@ -234,21 +308,28 @@ { } + /** + * Add $delegate as Delegate to the list of this manager. If some functions + * that want to connect to $delegate, have been entrusted yet, this object + * calls add() of $delegate with their parameters. + * + * Usually this member function isn't used as Cube's API by developers. In + * many cases, XCube_Delegate::register() calls this. + * + * @access public + * + */ function register($name, &$delegate) { if (!isset($this->_mDelegates[$name])) { $this->_mDelegates[$name] =& $delegate; - if (isset($this->_mCallbackInstances[$name])) { - foreach (array_keys($this->_mCallbackInstances[$name]) as $key => $val) { - if ($val != null) { - $delegate->addMethod($this->_mCallbackInstances[$name][$key], $this->_mCallbacks[$name][$key], $this->_mCallbackPaths[$name][$key]); - } - else { - $delegate->add($this->_mCallbacks[$name][$key], $this->_mCallbackPaths[$name][$key]); - } + if (count($this->_mCallbacks[$name]) > 0) { + foreach (array_keys($this->_mCallbacks[$name]) as $key) { + $delegate->add($this->_mCallbacks[$name][$key], $this->_mCallbackParameters[$name][$key][0], $this->_mCallbackParameters[$name][$key][1]); } - unset($this->_mCallbackInstances[$name]); + unset($this->_mCallbacks[$name]); + unset($this->_mCallbackParameters[$name]); } return true; @@ -259,40 +340,25 @@ } /** - * Connect static functions or static member functions to this object. - * - * @access public - * @param $func callback - * @param $path string If $path is specified, load first it before execute callback. - */ - function add($name, $func, $path = null) - { - if (isset($this->_mDelegates[$name])) { - $this->_mDelegates[$name]->add($func, $path); - } - else { - $this->_mCallbackInstances[$name][] = null; - $this->_mCallbacks[$name][] = $func; - $this->_mCallbackPaths[$name][] = $path; - } - } - - /** - * Conect member functions(=instance method) to this object. + * Connect any functions to the delegate that have the specified name. If + * there aren't any delegates that have the specified name, this manager + * entrust parameters to member properties. Then, when the delegate that + * have the specified name will be registered, this manager will set these + * parameters to the delegate. * * @access public - * @param $obj Object - * @param $method string + * @param $name register name + * + * @see XCube_NewDelegate::add() */ - function addMethod($name, &$obj, $method) + function add($name, $callback, $param3 = null, $param4 = null) { if (isset($this->_mDelegates[$name])) { - $this->_mDelegates[$name]->addMethod($obj, $method); + $this->_mDelegates[$name]->add($callback, $param3, $param4); } else { - $this->_mCallbackInstances[$name][] =& $obj; - $this->_mCallbacks[$name][] = $method; - $this->_mCallbackPaths[$name][] = null; + $this->_mCallbacks[$name][] = $callback; + $this->_mCallbackParameters[$name][] = array('0' => $param3, '1' => $param4); } } }