From 3c6305c121f26ca103192fd941103dcd5736c050 Mon Sep 17 00:00:00 2001 From: Jeremiah VALERIE Date: Tue, 19 Apr 2016 21:16:09 +0200 Subject: [PATCH] * Optimized implementation to interfaces using lazy loader * Union types now accepting callback --- src/Schema.php | 2 ++ src/Type/Definition/InterfaceType.php | 25 +++++++++++++++++++++---- src/Type/Definition/Type.php | 2 +- src/Type/Definition/UnionType.php | 2 +- src/Types.php | 9 --------- 5 files changed, 25 insertions(+), 15 deletions(-) delete mode 100644 src/Types.php diff --git a/src/Schema.php b/src/Schema.php index a3e9246..134d9f8 100644 --- a/src/Schema.php +++ b/src/Schema.php @@ -33,6 +33,8 @@ class Schema $this->mutationSchema = $mutationSchema; $this->subscriptionSchema = $subscriptionSchema; + InterfaceType::loadImplementationToInterfaces(); + // Build type map now to detect any errors within this schema. $map = []; foreach ([$this->getQueryType(), $this->getMutationType(), Introspection::_schema()] as $type) { diff --git a/src/Type/Definition/InterfaceType.php b/src/Type/Definition/InterfaceType.php index 4ef8b54..8ba859b 100644 --- a/src/Type/Definition/InterfaceType.php +++ b/src/Type/Definition/InterfaceType.php @@ -18,6 +18,11 @@ class InterfaceType extends Type implements AbstractType, OutputType, CompositeT */ private $_implementations = []; + /** + * @var \Closure[] + */ + private static $_lazyLoadImplementations = []; + /** * @var {[typeName: string]: boolean} */ @@ -34,18 +39,30 @@ class InterfaceType extends Type implements AbstractType, OutputType, CompositeT public $config; /** - * Update the interfaces to know about this implementation. + * Queue the update of the interfaces to know about this implementation. * This is an rare and unfortunate use of mutation in the type definition * implementations, but avoids an expensive "getPossibleTypes" * implementation for Interface types. * * @param ObjectType $impl - * @param InterfaceType[] $interfaces */ public static function addImplementationToInterfaces(ObjectType $impl) { - foreach ($impl->getInterfaces() as $interface) { - $interface->_implementations[] = $impl; + self::$_lazyLoadImplementations[] = function() use ($impl) { + foreach ($impl->getInterfaces() as $interface) { + $interface->_implementations[] = $impl; + } + }; + } + + /** + * Process ImplementationToInterfaces Queue + */ + public static function loadImplementationToInterfaces() + { + foreach (self::$_lazyLoadImplementations as $i => &$lazyLoadImplementation) { + call_user_func($lazyLoadImplementation); + unset(self::$_lazyLoadImplementations[$i]); } } diff --git a/src/Type/Definition/Type.php b/src/Type/Definition/Type.php index 22e90d9..123bb5e 100644 --- a/src/Type/Definition/Type.php +++ b/src/Type/Definition/Type.php @@ -98,7 +98,7 @@ GraphQLNonNull; } /** - * @return Type + * @return Type[] */ public static function getInternalTypes() { diff --git a/src/Type/Definition/UnionType.php b/src/Type/Definition/UnionType.php index d6151f1..cd6cfcf 100644 --- a/src/Type/Definition/UnionType.php +++ b/src/Type/Definition/UnionType.php @@ -29,7 +29,7 @@ class UnionType extends Type implements AbstractType, OutputType, CompositeType { Config::validate($config, [ 'name' => Config::STRING | Config::REQUIRED, - 'types' => Config::arrayOf(Config::OBJECT_TYPE, Config::REQUIRED), + 'types' => Config::arrayOf(Config::OBJECT_TYPE, Config::MAYBE_THUNK | Config::REQUIRED), 'resolveType' => Config::CALLBACK, // function($value, ResolveInfo $info) => ObjectType 'description' => Config::STRING ]); diff --git a/src/Types.php b/src/Types.php deleted file mode 100644 index da85983..0000000 --- a/src/Types.php +++ /dev/null @@ -1,9 +0,0 @@ -