| 
<?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;
 }
 
 
 
 }
 
 
 
 |