/* SEEXPR SOFTWARE Copyright 2011 Disney Enterprises, Inc. All rights reserved Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * 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. * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation Studios" or the names of its contributors may NOT be used to endorse or promote products derived from this software without specific prior written permission from Walt Disney Pictures. Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED. IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 BASED 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 DAMAGES. */ #ifndef SeExprFunc_h #define SeExprFunc_h #include "seexpr/src/SeExpr/SeVec3d.h" #include #include "porting/XgWinExport.h" class SeExpression; class SeExprFuncNode; //! Extension function spec, used for complicated argument custom functions. /** Provides the ability to handle all argument type checking and processing manually. Derive from this class and then make your own SeExprFunc that takes this object. This is necessary if you need string arguments or you have variable numbers of arguments. See SeExprBuiltins.h for some examples */ class XGEN_SEEXPR_EXPORT SeExprFuncX { public: //! Create an SeExprFuncX. If the functions and type checking you implement //! is thread safe your derived class should call this with true. If not, //! then false. If you mark a function as thread unsafe, and it is used //! in an expression then bool SeExpression::isThreadSafe() will return false //! and the controlling software should not attempt to run multiple threads //! of an expression. SeExprFuncX(const bool threadSafe) :_threadSafe(threadSafe) {} /** prep the expression by doing all type checking argument checking, etc. */ virtual bool prep(SeExprFuncNode* node, bool wantVec); /** evaluate the expression. the given node is where in the parse tree the evaluation is for */ virtual void eval(const SeExprFuncNode* node, SeVec3d& result) const = 0; virtual ~SeExprFuncX(){} /** return file paths used in the function. */ virtual void getExternalPath(std::vector &paths, SeExprFuncNode* node) {} bool isThreadSafe() const {return _threadSafe;} private: bool _threadSafe; }; //! Function Definition, used in parse tree and func table. /** This class in a static setting manages all builtin functions defined by SeExpr internally or through the use of shared object plugins. These can be queried by name for documentation. Users can create their own custom functions by creating one of these with the appropriate argument template. Any function that doesn't work within the given templates can be written using a SeExprFuncX template instead Note: If you use the convenience prototypes instead of SeExprFuncX, the user defined function will be assumed to be thread safe. If you have a thread unsafe function be sure to use SeExprFuncX and call the base constructor with false. */ class XGEN_SEEXPR_EXPORT SeExprFunc { static void initInternal(); // call to define built-in funcs and load standard plugins public: //! call to define built-in funcs and load standard plugins /** In addition to initializing all builtins, this loads all plugins given in a a colon delimited SE_EXPR_PLUGINS environment variable **/ static void init(); //! load all plugins in a given path static void loadPlugins(const char* path); //! load a given plugin static void loadPlugin(const char* path); /* A pointer to the define func is passed to the init method of expression plugins. This should be called instead of calling the static method directly so that the plugin will work if the expression library is statically linked. */ static void define(const char* name, SeExprFunc f,const char* docString); static void define(const char* name, SeExprFunc f); typedef void (*Define) (const char* name, SeExprFunc f); typedef void (*Define3) (const char* name, SeExprFunc f,const char* docString); //! Lookup a builtin function by name static const SeExprFunc* lookup(const std::string& name); //! Get a list of registered builtin and DSO generated functions static void getFunctionNames(std::vector& names); //! Get doc string for a specific function static std::string getDocString(const char* functionName); typedef double Func0(); typedef double Func1(double); typedef double Func2(double, double); typedef double Func3(double, double, double); typedef double Func4(double, double, double, double); typedef double Func5(double, double, double, double, double); typedef double Func6(double, double, double, double, double, double); typedef double Func1v(const SeVec3d&); typedef double Func2v(const SeVec3d&, const SeVec3d&); typedef SeVec3d Func1vv(const SeVec3d&); typedef SeVec3d Func2vv(const SeVec3d&, const SeVec3d&); typedef double Funcn(int n, double* params); typedef double Funcnv(int n, const SeVec3d* params); typedef SeVec3d Funcnvv(int n, const SeVec3d* params); enum FuncType { NONE=0, // scalar args and result FUNC0, FUNC1, FUNC2, FUNC3, FUNC4, FUNC5, FUNC6, FUNCN, // vector args, scalar result VEC, FUNC1V=VEC, FUNC2V, FUNCNV, // vector args and result VECVEC, FUNC1VV=VECVEC, FUNC2VV, FUNCNVV, // extension type FUNCX }; bool hasVecArgs() const { return _type >= VEC; } bool isVec() const { return _type >= VECVEC; } SeExprFunc() : _type(NONE), _func(0), _minargs(0), _maxargs(0) {} //! No argument function SeExprFunc(Func0* f) : _type(FUNC0), _func((void*)f), _minargs(0), _maxargs(0) {} //! User defined function with prototype double f(double) SeExprFunc(Func1* f) : _type(FUNC1), _func((void*)f), _minargs(1), _maxargs(1) {} //! User defined function with prototype double f(double,double) SeExprFunc(Func2* f) : _type(FUNC2), _func((void*)f), _minargs(2), _maxargs(2) {} //! User defined function with prototype double f(double,double,double) SeExprFunc(Func3* f) : _type(FUNC3), _func((void*)f), _minargs(3), _maxargs(3) {} //! User defined function with prototype double f(double,double,double,double) SeExprFunc(Func4* f) : _type(FUNC4), _func((void*)f), _minargs(4), _maxargs(4) {} //! User defined function with prototype double f(double,double,double,double,double) SeExprFunc(Func5* f) : _type(FUNC5), _func((void*)f), _minargs(5), _maxargs(5) {} //! User defined function with prototype double f(double,double,double,double,double,double) SeExprFunc(Func6* f) : _type(FUNC6), _func((void*)f), _minargs(6), _maxargs(6) {} //! User defined function with prototype double f(vector) SeExprFunc(Func1v* f) : _type(FUNC1V), _func((void*)f), _minargs(1), _maxargs(1) {} //! User defined function with prototype double f(vector,vector) SeExprFunc(Func2v* f) : _type(FUNC2V), _func((void*)f), _minargs(2), _maxargs(2) {} //! User defined function with prototype vector f(vector) SeExprFunc(Func1vv* f) : _type(FUNC1VV), _func((void*)f), _minargs(1), _maxargs(1) {} //! User defined function with prototype vector f(vector,vector) SeExprFunc(Func2vv* f) : _type(FUNC2VV), _func((void*)f), _minargs(2), _maxargs(2) {} //! User defined function with arbitrary number of arguments double f(double,...) SeExprFunc(Funcn* f, int minargs, int maxargs) : _type(FUNCN), _func((void*)f), _minargs(minargs), _maxargs(maxargs) {} //! User defined function with arbitrary number of arguments double f(vector,...) SeExprFunc(Funcnv* f, int minargs, int maxargs) : _type(FUNCNV), _func((void*)f), _minargs(minargs), _maxargs(maxargs) {} //! User defined function with arbitrary number of arguments vector f(vector,...) SeExprFunc(Funcnvv* f, int minargs, int maxargs) : _type(FUNCNVV), _func((void*)f), _minargs(minargs), _maxargs(maxargs) {} //! User defined function with custom argument parsing SeExprFunc(SeExprFuncX& f, int minargs=1, int maxargs=1) : _type(FUNCX), _func((void*)&f), _minargs(minargs), _maxargs(maxargs) {} int type() const { return _type; } int minArgs() const { return _minargs; } int maxArgs() const { return _maxargs; } Func0* func0() const { return (Func0*)_func; } Func1* func1() const { return (Func1*)_func; } Func2* func2() const { return (Func2*)_func; } Func3* func3() const { return (Func3*)_func; } Func4* func4() const { return (Func4*)_func; } Func5* func5() const { return (Func5*)_func; } Func6* func6() const { return (Func6*)_func; } Func1v* func1v() const { return (Func1v*)_func; } Func2v* func2v() const { return (Func2v*)_func; } Func1vv* func1vv() const { return (Func1vv*)_func; } Func2vv* func2vv() const { return (Func2vv*)_func; } Funcn* funcn() const { return (Funcn*)_func; } Funcnv* funcnv() const { return (Funcnv*)_func; } Funcnvv* funcnvv() const { return (Funcnvv*)_func; } SeExprFuncX* funcx() const { return (SeExprFuncX*)_func; } private: FuncType _type; void* _func; int _minargs; int _maxargs; }; #endif