<?php
/**
*
* Copyright (c) 2017, Till Wehowski
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the frdl/webfan.
* 4. Neither the name of frdl/webfan nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY frdl/webfan ''AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL frdl/webfan BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/**
* EventEmitter javascript like event based final state object :
* https://github.com/frdl/-Flow/blob/master/api-d/4/js-api/library.js/core/plugin.core.js#L4501
*/
namespace frdl\Flow;
class EventEmitter extends Element{
public function hasListeners($event){
return (isset($this->events[$event]) && 0 < count($this->events[$event])) ? true : false;
}
public function required($eventsArrayIn, $callback, $multiple = false){
$that = &$this;
$eventArray = $eventsArrayIn;
$eventData = array();
$updateData = array();
$called = false;
$listen = function (&$obj, $multiple){
if(true===$multiple)
{
// return $events->on || $events->addListener;
return array($obj, 'on');
}
else
{
return array($obj, 'once');
}
};
$listen = $listen($that, $multiple);
$silence= array($that, 'off');
$isOn = $listen === array($that, 'on');
$clear = function () use ( &$eventArray, &$updateData, $silence, &$that){
// foreach($eventArray as $event){
foreach($that->Iterator('Array', $eventArray) as $event){
call_user_func_array($silence, array($event, $updateData[array_search($event, $eventArray)]));
}
$eventData = array();
}
;
$stateCheck = function () use ( &$eventArray, &$eventData, &$called, &$multiple, &$isOn, $clear, &$that, &$callback)
{
$waiting = false;
$ready = false;
foreach($that->Iterator('Array', $eventArray) as $event){
$k = array_search($event, $eventArray);
if(false===$k || null===$eventData[$k]){
$waiting = true;
break;
}
}
$ready = (false === $waiting) ? true : false;
if(true===$ready && true!==$called)
{
call_user_func_array($callback, array($eventData));
if(true!==$multiple)
{
$called = true;
if(true===$isOn)
{
$clear();
}
}
}
}
;
$updateState = function ($eventName) use ( &$eventArray, &$eventData, &$stateCheck){
$index = array_search($eventName, $eventArray);
return function ($data = null) use ( &$eventData, &$index, &$stateCheck){
if(null===$data)
{
$data = true;
}
$eventData[$index] = $data;
call_user_func_array($stateCheck, array());
// $stateCheck();
}
;
}
;
$stateReady = function ($s) use ( &$eventData, &$eventArray)
{
$k = array_search($s, $eventArray);
return (false===$k || null===$eventData[$k]) ? false : true;
}
;
$stateGet = function ($s) use ( &$eventData, &$eventArray)
{
return $eventData[array_search($s, $eventArray)];
}
;
$addState = function () use ( &$eventArray, &$updateData, $updateState, $listen, &$that, $addState)
{
$events = func_get_args();
foreach($that->Iterator('Array', $events) as $event){
if(is_array($event)){
foreach($event as $ev){
call_user_func_array($addState, array($ev));
}
}else{
$index = array_search($event, $eventArray);
if($index === false)
{
array_push($eventArray, $event);
$index = count($eventArray) - 1;
}
$updateData[$index] = $updateState($event);
call_user_func_array($listen, array($event,$updateData[$index]));
}
}
};
foreach($that->Iterator('Array', $eventArray) as $event){
$addState($event);
}
/* $finStateObj = new \O; */
$fo = new \O;
$fo->cancel = $clear;
$fo->add = $addState;
$fo->events = $eventArray;
$fo->status = $eventData;
$fo->stateReady = $stateReady;
$fo->stateGet = $stateGet;
return $fo;
}
}
|