Hi,
As you know we have been working with reaby on eXpansion plugin pack(specially reaby). We have a slight problem with manialive itself.
First of all the last version is really great, it is very stable and there is no memory leaks, fantastic work.
The problem comes from the generated actions being deleted automatically when they shouldn't. To optimize the number of actions generated you check if an action with the same callbacks exist already, if it do exist then you return that one.
By consequence multiple different windows of different players will use same action's which is nice.
But when a window of another player is destroyed you will destroy all it's actions as well as the actions that are used in other windows and by doing so make that window unusable. What do we do to prevent this?
We may add another parameter in order to make sure that every one of them are unique but that's not very practical and beyond the point. We came up with 2 solutions :
First we are counting the number of times the same action is created and destroy it only if it is destroyed the same amount of time. In a way it allows to count the different places where the action is used and when used in 0 place then destroy :
Code: Select all
<?php
namespace ManiaLive\Gui;
use ManiaLive\Event\Dispatcher;
use ManiaLive\DedicatedApi\Callback\Listener as ServerListener;
use ManiaLive\DedicatedApi\Callback\Event as ServerEvent;
/**
 * Description of ActionHandler
 */
final class ActionHandler extends \ManiaLib\Utils\Singleton implements ServerListener
{
    const NONE = 0xFFFFFFFF;
   Â
    protected $callbacks = array();
    protected $usage = array();
   Â
    protected $lastAction = 0;
   Â
    protected function __construct()
    {
        Dispatcher::register(ServerEvent::getClass(), $this, ServerEvent::ON_PLAYER_MANIALINK_PAGE_ANSWER);
    }
   Â
    function createAction($callback)
    {
        if(!is_array($callback) || !is_callable($callback))
            throw new \InvalidArgumentException('Invalid callback');
       Â
        $args = func_get_args();
        array_shift($args);
        $callback = array($callback, $args);
       Â
        $action = array_search($callback, $this->callbacks, true);
        if($action !== false){
            $this->usage[$action]++;
            return $action;
        }
        $this->lastAction++;
        $action = $this->lastAction;
        $this->usage[$action] = 1;
        $this->callbacks[action ] = $callback;
       Â
        return $this->lastAction;
    }
   Â
    // TODO this should be done automatically but PHP has no refcount function
    // nor weak references yet... so please don't forget to call this method
    // to avoid memory leaks !!!!
    function deleteAction($action)
    {
        if(isset($this->usage[$action])){
            $this->usage[$action]--;
            if($this->usage[$action] == 0){
                unset($this->callbacks[$action]);
                unset($this->usage[$action]);
           }
        }
    }
Â
    //...
}
?>
This do work but, as old plugins used to destroy their actions manually many does 2 destruction which causes the action to be still destroyed to fast. We might say it isn't compatible with current plugins but is a working solution.
The second solution would be to generate a new action always without checking if the old ones exist :
Code: Select all
Â
<?php
namespace ManiaLive\Gui;
use ManiaLive\Event\Dispatcher;
use ManiaLive\DedicatedApi\Callback\Listener as ServerListener;
use ManiaLive\DedicatedApi\Callback\Event as ServerEvent;
/**
 * Description of ActionHandler
 */
final class ActionHandler extends \ManiaLib\Utils\Singleton implements ServerListener
{
   const NONE = 0xFFFFFFFF;
  Â
   protected $callbacks = array();
   protected $usage = array();
   Â
   protected $lastAction = 0;
  Â
   protected function __construct()
   {
      Dispatcher::register(ServerEvent::getClass(), $this, ServerEvent::ON_PLAYER_MANIALINK_PAGE_ANSWER);
   }
  Â
   function createAction($callback)
   {
      if(!is_array($callback) || !is_callable($callback))
         throw new \InvalidArgumentException('Invalid callback');
     Â
      $args = func_get_args();
      array_shift($args);
      $callback = array($callback, $args);
     Â
      $action = ++$this->lastAction;
      $this->callbacks[$action] = $callback;
       Â
      return $this->lastAction;
   }
  Â
   // TODO this should be done automatically but PHP has no refcount function
   // nor weak references yet... so please don't forget to call this method
   // to avoid memory leaks !!!!
   function deleteAction($action)
   {
        unset($this->callbacks[$action]);
   }
   //....
?>
This works fine with all our current plugins, we are testing it to see if it causes any memory issues.
It would be nice to have a fix on this issue, at least if we knew what the fix will be so that we can start making changes it necessary
Reaby has also found a version of ManiaLive on github? What is the plans in the future, do you intend to switch to github? it would allow us to help in fixing some small bugs at least in order to make manialive development faster.
Thanks,