<commit_before><?php
	declare(strict_types = 1);

	namespace Edde\Common\Runtime;

	use Edde\Api\Container\IContainer;
	use Edde\Api\Container\IFactory;
	use Edde\Api\Runtime\ISetupHandler;
	use Edde\Api\Usable\IUsable;
	use Edde\Common\AbstractObject;
	use Edde\Common\Container\Factory\FactoryFactory;

	abstract class AbstractSetupHandler extends AbstractObject implements ISetupHandler {
		/**
		 * @var IFactory[]
		 */
		protected $factoryList = [];
		/**
		 * @var callable
		 */
		protected $factoryFallback;

		public function registerFactoryList(array $fatoryList) {
			$this->factoryList = FactoryFactory::createList(array_merge($this->factoryList, $fatoryList));
			return $this;
		}

		public function registerFactoryFallback(callable $callback) {
			$this->factoryFallback = $callback;
			return $this;
		}

		public function onSetup($name, callable $onSetup) {
			if (isset($this->factoryList[$name]) === false) {
				return $this;
			}
			$this->onFactorySetup($this->factoryList[$name], $onSetup);
			return $this;
		}

		private function onFactorySetup(IFactory $factory, callable $callback) {
			$factory->onSetup(function (IContainer $container, $instance) use ($callback) {
				if ($instance instanceof IUsable) {
					$instance->onSetup(function () use ($container, $callback, $instance) {
						return $container->call($callback, $instance);
					});
					return;
				}
				$container->call($callback);
			});
		}

		protected function factory($class, callable $onSetup) {
			return [
				$class,
				function (IFactory $factory) use ($onSetup) {
					$this->onFactorySetup($factory, $onSetup);
				},
			];
		}
	}<commit_msg>- onFactorySetup must implement IUsable; new exception to prevent not so nice bugs<commit_after><?php
	declare(strict_types = 1);

	namespace Edde\Common\Runtime;

	use Edde\Api\Container\IContainer;
	use Edde\Api\Container\IFactory;
	use Edde\Api\Runtime\ISetupHandler;
	use Edde\Api\Runtime\RuntimeException;
	use Edde\Api\Usable\IUsable;
	use Edde\Common\AbstractObject;
	use Edde\Common\Container\Factory\FactoryFactory;

	abstract class AbstractSetupHandler extends AbstractObject implements ISetupHandler {
		/**
		 * @var IFactory[]
		 */
		protected $factoryList = [];
		/**
		 * @var callable
		 */
		protected $factoryFallback;

		public function registerFactoryList(array $fatoryList) {
			$this->factoryList = FactoryFactory::createList(array_merge($this->factoryList, $fatoryList));
			return $this;
		}

		public function registerFactoryFallback(callable $callback) {
			$this->factoryFallback = $callback;
			return $this;
		}

		public function onSetup($name, callable $onSetup) {
			if (isset($this->factoryList[$name]) === false) {
				return $this;
			}
			$this->onFactorySetup($this->factoryList[$name], $onSetup);
			return $this;
		}

		private function onFactorySetup(IFactory $factory, callable $callback) {
			$factory->onSetup(function (IContainer $container, $instance) use ($callback) {
				if (($instance instanceof IUsable) === false) {
					throw new RuntimeException(sprintf('Deffered class must implement [%s] interface.', IUsable::class));
				}
				/** @var $instance IUsable */
				$instance->onSetup(function () use ($container, $callback, $instance) {
					return $container->call($callback, $instance);
				});
			});
		}

		protected function factory($class, callable $onSetup) {
			return [
				$class,
				function (IFactory $factory) use ($onSetup) {
					$this->onFactorySetup($factory, $onSetup);
				},
			];
		}
	}
{'fraction_non_alphanumeric': 0.13728282540586728, 'fraction_numerical': 0.0005696382796923954, 'mean_word_length': 4.1875923190546525, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 24, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1881175', 'n_tokens_mistral': 1255, 'n_tokens_neox': 1069, 'n_words': 231}