diff --git a/Documentation/ofxProgrammingGuide.xml b/Documentation/ofxProgrammingGuide.xml index ba936a220..a12f1a7b0 100644 --- a/Documentation/ofxProgrammingGuide.xml +++ b/Documentation/ofxProgrammingGuide.xml @@ -338,7 +338,7 @@ pluginMain(const char *action, const void *handle, OfxPropertySetHandle inArgs, OfxImageEffectSuiteV1 *gEffectSuite = 0; OfxPropertySuiteV1 *gPropertySuite = 0; - +bool supportsNullSuiteFunctionPointers = false; //////////////////////////////////////////////////////////////////////////////// // Called at load static OfxStatus @@ -347,8 +347,8 @@ onLoad(void) // fetch the host suites out of the global host pointer if(!gHost) return kOfxStatErrMissingHostFeature; - gEffectSuite = (OfxImageEffectSuiteV1 *) gHost->fetchSuite(gHost->host, kOfxImageEffectSuite, 1); - gPropertySuite = (OfxPropertySuiteV1 *) gHost->fetchSuite(gHost->host, kOfxPropertySuite, 1); + gEffectSuite = (OfxImageEffectSuiteV1 *) gHost->fetchSuite(gHost->host, kOfxImageEffectSuite, 1, supportsNullSuiteFunctionPointers); + gPropertySuite = (OfxPropertySuiteV1 *) gHost->fetchSuite(gHost->host, kOfxPropertySuite, 1, supportsNullSuiteFunctionPointers); if(!gEffectSuite || !gPropertySuite) return kOfxStatErrMissingHostFeature; return kOfxStatOK; diff --git a/HostSupport/include/ofxhHost.h b/HostSupport/include/ofxhHost.h index e77a13ad1..922352622 100644 --- a/HostSupport/include/ofxhHost.h +++ b/HostSupport/include/ofxhHost.h @@ -70,7 +70,7 @@ namespace OFX { /// The base class returns the following suites /// PropertySuite /// MemorySuite - virtual const void *fetchSuite(const char *suiteName, int suiteVersion); + virtual const void *fetchSuite(const char *suiteName, int suiteVersion, bool allowNullFunctionPointers); /// get the C API handle that is passed across the API to represent this host OfxHost *getHandle(); diff --git a/HostSupport/include/ofxhImageEffect.h b/HostSupport/include/ofxhImageEffect.h index 179f4dcfc..f1a90fa95 100755 --- a/HostSupport/include/ofxhImageEffect.h +++ b/HostSupport/include/ofxhImageEffect.h @@ -72,7 +72,7 @@ namespace OFX { Host(); /// fetch a suite - virtual const void *fetchSuite(const char *suiteName, int suiteVersion); + virtual const void *fetchSuite(const char *suiteName, int suiteVersion, bool allowNullFunctionPointers); /// Create a new instance of an image effect plug-in. /// diff --git a/HostSupport/src/ofxhHost.cpp b/HostSupport/src/ofxhHost.cpp index f4ade989a..763b2f871 100644 --- a/HostSupport/src/ofxhHost.cpp +++ b/HostSupport/src/ofxhHost.cpp @@ -91,14 +91,14 @@ namespace OFX { Property::propSpecEnd }; - static const void *fetchSuite(OfxPropertySetHandle hostProps, const char *suiteName, int suiteVersion) + static const void *fetchSuite(OfxPropertySetHandle hostProps, const char *suiteName, int suiteVersion, bool allowNullFunctionPointers) { Property::Set* properties = reinterpret_cast(hostProps); Host* host = (Host*)properties->getPointerProperty(kOfxHostSupportHostPointer); if(host) - return host->fetchSuite(suiteName,suiteVersion); + return host->fetchSuite(suiteName,suiteVersion,allowNullFunctionPointers); else return 0; } @@ -133,7 +133,7 @@ namespace OFX { } } - const void *Host::fetchSuite(const char *suiteName, int suiteVersion) + const void *Host::fetchSuite(const char *suiteName, int suiteVersion,bool /*allowNullFunctionPointers*/) { if (strcmp(suiteName, kOfxPropertySuite)==0 && suiteVersion == 1) { return Property::GetSuite(suiteVersion); diff --git a/HostSupport/src/ofxhImageEffect.cpp b/HostSupport/src/ofxhImageEffect.cpp index 7ee05d6a1..f75cc7f28 100644 --- a/HostSupport/src/ofxhImageEffect.cpp +++ b/HostSupport/src/ofxhImageEffect.cpp @@ -2714,6 +2714,7 @@ namespace OFX { #endif { kOfxImageEffectPropRenderQualityDraft, Property::eInt, 1, true, "0" }, // OFX 1.4 { kOfxImageEffectHostPropNativeOrigin, Property::eString, 0, true, kOfxHostNativeOriginBottomLeft }, // OFX 1.4 + { kOfxPropHostSupportsNullSuiteFunctionPointers, Property::eInt, 0, true, 0 }, Property::propSpecEnd }; @@ -2757,7 +2758,7 @@ namespace OFX { } /// our suite fetcher - const void *Host::fetchSuite(const char *suiteName, int suiteVersion) + const void *Host::fetchSuite(const char *suiteName, int suiteVersion,bool allowNullFunctionPointers) { if (strcmp(suiteName, kOfxImageEffectSuite)==0) { if(suiteVersion==1) @@ -2812,7 +2813,7 @@ namespace OFX { } # endif else /// otherwise just grab the base class one, which is props and memory - return OFX::Host::Host::fetchSuite(suiteName, suiteVersion); + return OFX::Host::Host::fetchSuite(suiteName, suiteVersion,allowNullFunctionPointers); } } // ImageEffect diff --git a/Support/Library/ofxsImageEffect.cpp b/Support/Library/ofxsImageEffect.cpp index 6cf43e011..c1b8442ca 100644 --- a/Support/Library/ofxsImageEffect.cpp +++ b/Support/Library/ofxsImageEffect.cpp @@ -1923,8 +1923,12 @@ namespace OFX { if(!gHost) throw OFX::Exception::Suite(kOfxStatErrBadHandle); if(gLoadCount == 1) { + gPropSuite = (OfxPropertySuiteV1 *) fetchSuite(kOfxPropertySuite, 1, true /*allowNullSuiteFunctionPointers*/); + + // OK check and fetch host information now that we have access to the property suite + fetchHostDescription(gHost); + gEffectSuite = (OfxImageEffectSuiteV1 *) fetchSuite(kOfxImageEffectSuite, 1); - gPropSuite = (OfxPropertySuiteV1 *) fetchSuite(kOfxPropertySuite, 1); gParamSuite = (OfxParameterSuiteV1 *) fetchSuite(kOfxParameterSuite, 1); gMemorySuite = (OfxMemorySuiteV1 *) fetchSuite(kOfxMemorySuite, 1); gThreadSuite = (OfxMultiThreadSuiteV1 *) fetchSuite(kOfxMultiThreadSuite, 1); @@ -1938,8 +1942,7 @@ namespace OFX { gOpenGLRenderSuite = (OfxImageEffectOpenGLRenderSuiteV1*) fetchSuite(kOfxOpenGLRenderSuite, 1, true); #endif - // OK check and fetch host information - fetchHostDescription(gHost); + /// and set some dendent flags OFX::gHostDescription.supportsMessageSuiteV2 = gMessageSuiteV2 != NULL; @@ -2943,9 +2946,9 @@ namespace OFX { }; // namespace Private /** @brief Fetch's a suite from the host and logs errors */ - const void * fetchSuite(const char *suiteName, int suiteVersion, bool optional) + const void * fetchSuite(const char *suiteName, int suiteVersion, bool optional, bool allowNullSuiteFunctionPointers) { - const void *suite = Private::gHost->fetchSuite(Private::gHost->host, suiteName, suiteVersion); + const void *suite = Private::gHost->fetchSuite(Private::gHost->host, suiteName, suiteVersion, (int)allowNullSuiteFunctionPointers); if(suite==0) { if(optional) diff --git a/Support/include/ofxsImageEffect.h b/Support/include/ofxsImageEffect.h index 9c88a0250..2d8201d2b 100644 --- a/Support/include/ofxsImageEffect.h +++ b/Support/include/ofxsImageEffect.h @@ -251,7 +251,7 @@ namespace OFX { All the standard suites are fetched by the support code, you should use this to fetch any extra non-standard suites. */ - const void * fetchSuite(const char *suiteName, int suiteVersion, bool optional = false); + const void * fetchSuite(const char *suiteName, int suiteVersion, bool optional = false, bool allowNullSuiteFunctionPointers = false); //////////////////////////////////////////////////////////////////////////////// /** @brief A class that lists all the properties of a host */ diff --git a/include/ofxCore.h b/include/ofxCore.h index 5dad99ab5..03b3449a6 100644 --- a/include/ofxCore.h +++ b/include/ofxCore.h @@ -77,6 +77,18 @@ typedef struct OfxHost { \arg \e suiteName - ASCII string labelling the host supplied API \arg \e suiteVersion - version of that suite to fetch + \arg \e allowNullFunctionPointers - Boolean Value: Whether the plug-in supports NULL function pointers in the suite fetched from the host. + This enable the host to indicate one or more unsupported function in a suite, without the plug-in to have first to call each suite + function to determine if which are actually supported. + + Note: + + The plug-in can check if the Host can actually return NULL function pointers in a suite structure by inspecting the kOfxPropHostSupportsNullSuiteFunctionPointers + property of the host descriptor. + Since inspecting this property requires the kOfxPropertySuite suite to be loaded first, it is expected that the host returns + NULL function pointers for unsupported functions of the kOfxPropertySuite and that the plug-in set allowNullFunctionPointers to 1 when fetching + this suite. + Any API fetched will be valid while the binary containing the plug-in is loaded. Repeated calls to fetchSuite with the same parameters will return the same pointer. @@ -85,7 +97,7 @@ typedef struct OfxHost { - NULL if the API is unknown (either the api or the version requested), - pointer to the relevant API if it was found */ - const void *(*fetchSuite)(OfxPropertySetHandle host, const char *suiteName, int suiteVersion); + const void *(*fetchSuite)(OfxPropertySetHandle host, const char *suiteName, int suiteVersion, int allowNullFunctionPointers); } OfxHost; @@ -434,6 +446,23 @@ Some plug-in vendor want raw OS specific handles back from the host so they can */ #define kOfxPropHostOSHandle "OfxPropHostOSHandle" +/** @brief Whether the host can return NULL function pointers in a suite fetched from the fetchSuite function in the OfxHost structure. + This enable the host to indicate one or more unsupported function in a suite, without the plug-in to have first to call each suite + function to determine if which are actually supported. + + - Type - int X 1 + - Property Set - host descriptor. + - Valid values - 0 or 1 + - Default Value - 0 + + When set to 1, the host may return NULL instead of a function pointer on a suite returned by fetchSuite, only if the plug-in called + fetchSuite with the argument allowNullFunctionPointers set to 1 + + Hosts without this property or with the property set to 0 are still expected to return suites without any NULL functions, + thus forcing the plug-in to inspect the return status of the functions to check if they are supported. + */ +#define kOfxPropHostSupportsNullSuiteFunctionPointers "OfxPropHostSupportsNullSuiteFunctionPointers" + /*@}*/ /*@}*/