diff --git a/Common/Bindings.h b/Common/Bindings.h index ce97aa4f3ffa57f7e18abd5364a39d38b69825f6..2a02084ef04701e8219987a3b3f7f05254f64893 100644 --- a/Common/Bindings.h +++ b/Common/Bindings.h @@ -1,521 +1,41 @@ #ifndef _BINDINGS_H_ #define _BINDINGS_H_ +#include <string> +#include <list> +#include <typeinfo> -#ifndef HAVE_LUA //no bindings - -class methodBinding{}; -class constructorBinding{}; -template <class objectType, class returnType=void, class arg0Type=void, class arg1Type=void, class arg2Type=void, class arg3Type=void> -class methodBindingTemplate:public methodBinding { - typedef returnType (objectType::*callback)(arg0Type,arg1Type,arg2Type,arg3Type); - public: - methodBindingTemplate(const std::string luaname,callback f){} -}; -template <class objectType, class returnType, class arg0Type, class arg1Type, class arg2Type> -class methodBindingTemplate<objectType,returnType,arg0Type,arg1Type,arg2Type,void>:public methodBinding { - typedef returnType (objectType::*callback)(arg0Type,arg1Type,arg2Type); - public: - methodBindingTemplate(const std::string luaname,callback f){} -}; -template <class objectType, class returnType, class arg0Type, class arg1Type> -class methodBindingTemplate<objectType,returnType,arg0Type,arg1Type,void,void>:public methodBinding { - typedef returnType (objectType::*callback)(arg0Type,arg1Type); - public: - methodBindingTemplate(const std::string luaname,callback f){} -}; -template <class objectType, class returnType, class arg0Type> -class methodBindingTemplate<objectType,returnType,arg0Type,void,void,void>:public methodBinding { - typedef returnType (objectType::*callback)(arg0Type); - public: - methodBindingTemplate(const std::string luaname,callback f){} -}; -template <class objectType, class returnType> -class methodBindingTemplate<objectType,returnType,void,void,void,void>:public methodBinding { - typedef returnType (objectType::*callback)(); - public: - methodBindingTemplate(const std::string luaname,callback f){} -}; -template <class objectType, class arg0Type, class arg1Type, class arg2Type> -class methodBindingTemplate<objectType,void,arg0Type,arg1Type,arg2Type,void>:public methodBinding { - typedef void (objectType::*callback)(arg0Type,arg1Type,arg2Type); - public: - methodBindingTemplate(const std::string luaname,callback f){} -}; -template <class objectType, class arg0Type, class arg1Type> -class methodBindingTemplate<objectType,void,arg0Type,arg1Type,void,void>:public methodBinding { - typedef void (objectType::*callback)(arg0Type,arg1Type); - public: - methodBindingTemplate(const std::string luaname,callback f){} -}; -template <class objectType, class arg0Type> -class methodBindingTemplate<objectType,void,arg0Type,void,void,void>:public methodBinding { - typedef void (objectType::*callback)(arg0Type); +class methodBinding{ public: - methodBindingTemplate(const std::string luaname,callback f){} + void setArgNames(std::string arg1, ...){} + void setDescription(std::string description){} }; -template <class objectType> -class methodBindingTemplate<objectType,void,void,void,void,void>:public methodBinding { - typedef void (objectType::*callback)(); - public: - methodBindingTemplate(const std::string luaname,callback f){} -}; -template<class objectType, class arg0Type=void, class arg1Type=void, class arg2Type=void, class arg3Type=void> -class constructorBindingTemplate:public constructorBinding {}; - -#else // HAVE_LUA -extern "C" { -#include "lua.h" -#include "lauxlib.h" +// c++ does not allow to take pointer to constructor. We wrap the constructor with those function so that pointer to constructor-function are available. +template <typename tObj, typename t0, typename t1, typename t2, typename t3> +tObj *constructorPtr(t0 a0, t1 a1, t2 a2, t3 a3){ + return new tObj(a0,a1,a2,a3); +} +template <typename tObj, typename t0, typename t1, typename t2> +tObj *constructorPtr(t0 a0, t1 a1, t2 a2){ + return new tObj(a0,a1,a2); +} +template <typename tObj, typename t0, typename t1> +tObj *constructorPtr(t0 a0, t1 a1){ + return new tObj(a0,a1); +} +template <typename tObj, typename t0> +tObj *constructorPtr(t0 a0){ + return new tObj(a0); +} +template <typename tObj> +tObj *constructorPtr(){ + return new tObj(); } -#include <vector> - - -class methodBinding { - public: - std::string _luaname; - virtual int call (lua_State *L)=0; - methodBinding(const std::string luaname){ - _luaname=luaname; - } -}; - -class constructorBinding { - public: - virtual int call (lua_State *L)=0; -}; - - -// this class is largely copied from luna -// todo : add reference to luna and check luna licence -template <typename T> class classBinding { - typedef struct { T *pT; bool owned;} userdataType; -public: - static void push(lua_State *L, T* obj, bool owned) { - userdataType *ud = static_cast<userdataType*>(lua_newuserdata(L, sizeof(userdataType))); - ud->pT=obj; - ud->owned=owned; - luaL_getmetatable(L, T::className); // lookup metatable in Lua registry - lua_setmetatable(L, -2); - } - static void Register(lua_State *L) { - lua_newtable(L); - int methods = lua_gettop(L); //-- create methods , i.e. the class itself - - luaL_newmetatable(L, T::className); - int metatable = lua_gettop(L); // -- create metatable of methods - - // store method table in globals so that - // scripts can add functions written in Lua. - lua_pushstring(L, T::className); - lua_pushvalue(L, methods); - lua_settable(L, LUA_GLOBALSINDEX); // -- global[T::className] = methods - -// lua_pushliteral(L, "__metatable"); -// lua_pushvalue(L, methods); -// lua_settable(L, metatable); // hide metatable from Lua getmetatable() - - lua_pushliteral(L, "__index"); - lua_pushvalue(L, methods); - lua_settable(L, metatable); // metatable.__index=methods - - lua_pushliteral(L, "__tostring"); - lua_pushcfunction(L, tostring_T); - lua_settable(L, metatable); - - lua_pushliteral(L, "__gc"); - lua_pushcfunction(L, gc_T); - lua_settable(L, metatable); - - lua_newtable(L); // mt for method table - int mt = lua_gettop(L); - lua_pushliteral(L, "__call"); - lua_pushlightuserdata(L,(void*)T::constructorMethod); - lua_pushcclosure(L, callConstructor, 1); - - lua_pushliteral(L, "new"); - lua_pushvalue(L, -2); // dup new_T function - lua_settable(L, methods); // add new_T to method table - lua_settable(L, mt); // mt.__call = new_T - - if(T::parentClassName!=std::string("")){ - lua_pushliteral(L,"__index"); - lua_pushstring(L,T::parentClassName); - lua_gettable(L,LUA_GLOBALSINDEX); - lua_settable(L,mt); // mt.__index = global[T::parentClassName] // this is the inheritance bit - } - lua_setmetatable(L, methods); // setmetatable(methods, mt) - - // fill method table with methods from class T - for (methodBinding **l = T::methods; *l; l++) { - lua_pushstring(L, (*l)->_luaname.c_str()); - lua_pushlightuserdata(L, (void*)*l); - lua_pushcclosure(L, callMethod, 1); - lua_settable(L, methods); //methods.(l->name) = callMethod(l) - } - lua_pop(L, 2); // drop metatable and method table - } - - // get userdata from Lua stack and return pointer to T object - static T *check(lua_State *L, int narg) { - userdataType *ud = static_cast<userdataType*>(lua_touserdata(L, narg)); - if(!ud) luaL_typerror(L, narg, T::className); - return ud->pT; // pointer to T object*/ - } - -private: - classBinding(); // hide default constructor - - // member function dispatcher - static int callMethod(lua_State *L) { - methodBinding *l = static_cast<methodBinding*>(lua_touserdata(L, lua_upvalueindex(1))); - return l->call(L); // call member function - } - static int callConstructor(lua_State *L) { - constructorBinding *l = static_cast<constructorBinding*>(lua_touserdata(L, lua_upvalueindex(1))); - if(!l){ - printf("this class does not have constructor\n"); - //throw(); - } - return l->call(L); // call member function - } - - // garbage collection metamethod - static int gc_T(lua_State *L) { - userdataType *ud = static_cast<userdataType*>(lua_touserdata(L, 1)); - /*if(ud->owned) //disable gc - delete ud->pT; // call destructor for T objects*/ - return 0; - } - - static int tostring_T (lua_State *L) { - char buff[32]; - userdataType *ud = static_cast<userdataType*>(lua_touserdata(L, 1)); - T *t = static_cast<T*>(lua_touserdata(L, 1)); - sprintf(buff, "%p", ud->pT); - lua_pushfstring(L, "%s (%s)", T::className, buff); - return 1; - } -}; - -template<class type> -class lua_template { - public: - static type get(lua_State *L, int ia){ - printf("error cannot get generic class in lua, only pointers are implemented\n"); - } - static void push(lua_State *L, type obj){ - printf("error cannot push generic class in lua, only pointers are implemented\n"); - } -}; - -template <class type> -class lua_template<type*>{ - public: - static type* get(lua_State *L, int ia){ - type *a=classBinding<type>::check(L,ia); - return a; - - } - static void push(lua_State *L, type *obj){ - classBinding<type>::push(L,obj,false); - } -}; - -template<> -class lua_template<lua_State *>{ - public: - static lua_State *get(lua_State *L, int ia){ - return L; - } - static void push(lua_State *L, int i){ - printf("error cannot push a lua_State in lua\n"); - } -}; - -template<> -class lua_template<int>{ - public: - static int get(lua_State *L, int ia){ - int a= luaL_checkint(L,ia); - return a; - } - static void push(lua_State *L, int i){ - lua_pushinteger(L,i); - } -}; - -template<class type> -class lua_template<std::vector<type > >{ - public: - static std::vector<type> get(lua_State *L, int ia){ - std::vector<type> v; - size_t size=lua_objlen(L,ia); - v.resize(size); - for(size_t i=0;i<size;i++){ - lua_pushinteger(L,i+1); - lua_gettable(L,ia); - v[i]=lua_template<type>::get(L,-1); - lua_pop(L,1); - } - return v; - } - static void push(lua_State *L, std::vector<type> a){ - } -}; - -template<> -class lua_template<double>{ - public: - static double get(lua_State *L, int ia){ - return luaL_checknumber(L,ia); - } - static void push(lua_State *L, double v){ - lua_pushnumber(L,v); - } -}; - -template<> -class lua_template<std::string>{ - public: - static std::string get(lua_State *L, int ia){ - return luaL_checkstring(L,ia); - } - static void push(lua_State *L, std::string s){ - lua_pushstring(L,s.c_str()); - } -}; - -//full : 4 args with return -template <class objectType, class returnType=void, class arg0Type=void, class arg1Type=void, class arg2Type=void, class arg3Type=void> -class methodBindingTemplate:public methodBinding { - typedef returnType (objectType::*callback)(arg0Type,arg1Type,arg2Type,arg3Type); - callback _f; - public: - methodBindingTemplate(const std::string luaname,callback f):methodBinding(luaname){ - _f=f; - } - int call (lua_State *L) { - objectType *obj = classBinding<objectType>::check(L,1); - arg0Type a0 = lua_template<arg0Type>::get(L,2); - arg1Type a1 = lua_template<arg1Type>::get(L,3); - arg2Type a2 = lua_template<arg2Type>::get(L,4); - arg3Type a3 = lua_template<arg3Type>::get(L,5); - returnType r=(obj->*(_f))(a0,a1,a2,a3); - lua_template<returnType>::push(L,r); - return 1; - } -}; -//3 args with return -template <class objectType, class returnType, class arg0Type, class arg1Type, class arg2Type> -class methodBindingTemplate<objectType,returnType,arg0Type,arg1Type,arg2Type,void>:public methodBinding { - typedef returnType (objectType::*callback)(arg0Type,arg1Type,arg2Type); - callback _f; - public: - methodBindingTemplate(const std::string luaname,callback f):methodBinding(luaname){ - _f=f; - } - int call (lua_State *L) { - objectType *obj = classBinding<objectType>::check(L,1); - arg0Type a0 = lua_template<arg0Type>::get(L,2); - arg1Type a1 = lua_template<arg1Type>::get(L,3); - arg2Type a2 = lua_template<arg2Type>::get(L,4); - returnType r=(obj->*(_f))(a0,a1,a2); - lua_template<returnType>::push(L,r); - return 1; - } -}; -//2 args with return -template <class objectType, class returnType, class arg0Type, class arg1Type> -class methodBindingTemplate<objectType,returnType,arg0Type,arg1Type,void,void>:public methodBinding { - typedef returnType (objectType::*callback)(arg0Type,arg1Type); - callback _f; - public: - methodBindingTemplate(const std::string luaname,callback f):methodBinding(luaname){ - _f=f; - } - int call (lua_State *L) { - objectType *obj = classBinding<objectType>::check(L,1); - arg0Type a0 = lua_template<arg0Type>::get(L,2); - arg1Type a1 = lua_template<arg1Type>::get(L,3); - returnType r=(obj->*(_f))(a0,a1); - lua_template<returnType>::push(L,r); - return 1; - } -}; -//1 arg with return -template <class objectType, class returnType, class arg0Type> -class methodBindingTemplate<objectType,returnType,arg0Type,void,void,void>:public methodBinding { - typedef returnType (objectType::*callback)(arg0Type); - callback _f; - public: - methodBindingTemplate(const std::string luaname,callback f):methodBinding(luaname){ - _f=f; - } - int call (lua_State *L) { - objectType *obj = classBinding<objectType>::check(L,1); - arg0Type a0 = lua_template<arg0Type>::get(L,2); - returnType r=(obj->*(_f))(a0); - lua_template<returnType>::push(L,r); - return 1; - } -}; -//0 arg with return -template <class objectType, class returnType> -class methodBindingTemplate<objectType,returnType,void,void,void,void>:public methodBinding { - typedef returnType (objectType::*callback)(); - callback _f; - public: - methodBindingTemplate(const std::string luaname,callback f):methodBinding(luaname){ - _f=f; - } - int call (lua_State *L) { - objectType *obj = classBinding<objectType>::check(L,1); - returnType r=(obj->*(_f))(); - lua_template<returnType>::push(L,r); - return 1; - } -}; -//4 args without return -template <class objectType, class arg0Type, class arg1Type, class arg2Type, class arg3Type> -class methodBindingTemplate<objectType,void,arg0Type,arg1Type,arg2Type,arg3Type>:public methodBinding { - typedef void (objectType::*callback)(arg0Type,arg1Type,arg2Type,arg3Type); - callback _f; - public: - methodBindingTemplate(const std::string luaname,callback f):methodBinding(luaname){ - _f=f; - } - int call (lua_State *L) { - objectType *obj = classBinding<objectType>::check(L,1); - arg0Type a0 = lua_template<arg0Type>::get(L,2); - arg1Type a1 = lua_template<arg1Type>::get(L,3); - arg2Type a2 = lua_template<arg2Type>::get(L,4); - arg3Type a3 = lua_template<arg3Type>::get(L,5); - (obj->*(_f))(a0,a1,a2,a3); - return 0; - } -}; -//3 args without return -template <class objectType, class arg0Type, class arg1Type, class arg2Type> -class methodBindingTemplate<objectType,void,arg0Type,arg1Type,arg2Type,void>:public methodBinding { - typedef void (objectType::*callback)(arg0Type,arg1Type,arg2Type); - callback _f; - public: - methodBindingTemplate(const std::string luaname,callback f):methodBinding(luaname){ - _f=f; - } - int call (lua_State *L) { - objectType *obj = classBinding<objectType>::check(L,1); - arg0Type a0 = lua_template<arg0Type>::get(L,2); - arg1Type a1 = lua_template<arg1Type>::get(L,3); - arg2Type a2 = lua_template<arg2Type>::get(L,4); - (obj->*(_f))(a0,a1,a2); - return 0; - } -}; -//2 args without return -template <class objectType, class arg0Type, class arg1Type> -class methodBindingTemplate<objectType,void,arg0Type,arg1Type,void,void>:public methodBinding { - typedef void (objectType::*callback)(arg0Type,arg1Type); - callback _f; - public: - methodBindingTemplate(const std::string luaname,callback f):methodBinding(luaname){ - _f=f; - } - int call (lua_State *L) { - objectType *obj = classBinding<objectType>::check(L,1); - arg0Type a0 = lua_template<arg0Type>::get(L,2); - arg1Type a1 = lua_template<arg1Type>::get(L,3); - (obj->*(_f))(a0,a1); - return 0; - } -}; -//1 arg without return -template <class objectType, class arg0Type> -class methodBindingTemplate<objectType,void,arg0Type,void,void,void>:public methodBinding { - typedef void (objectType::*callback)(arg0Type); - callback _f; - public: - methodBindingTemplate(const std::string luaname,callback f):methodBinding(luaname){ - _f=f; - } - int call (lua_State *L) { - objectType *obj = classBinding<objectType>::check(L,1); - arg0Type a0 = lua_template<arg0Type>::get(L,2); - (obj->*(_f))(a0); - return 0; - } -}; -//0 arg without return -template <class objectType> -class methodBindingTemplate<objectType,void,void,void,void,void>:public methodBinding { - typedef void (objectType::*callback)(); - callback _f; - public: - methodBindingTemplate(const std::string luaname,callback f):methodBinding(luaname){ - _f=f; - } - int call (lua_State *L) { - objectType *obj = classBinding<objectType>::check(L,1); - (obj->*(_f))(); - return 0; - } -}; -//constructor 4 args -template<class objectType, class arg0Type=void, class arg1Type=void, class arg2Type=void, class arg3Type=void> -class constructorBindingTemplate:public constructorBinding { - int call (lua_State *L){ - lua_remove(L,1); - arg0Type a0 = lua_template<arg0Type>::get(L,1); - arg1Type a1 = lua_template<arg1Type>::get(L,2); - arg2Type a2 = lua_template<arg2Type>::get(L,3); - arg3Type a3 = lua_template<arg3Type>::get(L,4); - classBinding<objectType>::push(L, new objectType(a0,a1,a2,a3),true); - return 1; - } -}; -//constructor 3 args -template<class objectType, class arg0Type, class arg1Type, class arg2Type> -class constructorBindingTemplate<objectType,arg0Type,arg1Type,arg2Type,void>:public constructorBinding { - int call (lua_State *L){ - lua_remove(L,1); - arg0Type a0 = lua_template<arg0Type>::get(L,1); - arg1Type a1 = lua_template<arg1Type>::get(L,2); - arg2Type a2 = lua_template<arg2Type>::get(L,3); - classBinding<objectType>::push(L, new objectType(a0,a1,a2),true); - return 1; - } -}; -//constructor 2 args -template<class objectType, class arg0Type, class arg1Type> -class constructorBindingTemplate<objectType,arg0Type,arg1Type,void,void>:public constructorBinding { - int call (lua_State *L){ - lua_remove(L,1); - arg0Type a0 = lua_template<arg0Type>::get(L,1); - arg1Type a1 = lua_template<arg1Type>::get(L,2); - classBinding<objectType>::push(L,new objectType(a0,a1),true); - return 1; - } -}; -//constructor 1 args -template<class objectType, class arg0Type> -class constructorBindingTemplate<objectType,arg0Type,void,void,void>:public constructorBinding { - int call (lua_State *L){ - lua_remove(L,1); - arg0Type a0 = lua_template<arg0Type>::get(L,1); - classBinding<objectType>::push(L, new objectType(a0),true); - return 1; - } -}; -//constructor 0 args -template<class objectType> -class constructorBindingTemplate<objectType,void,void,void,void>:public constructorBinding { - int call (lua_State *L){ - lua_remove(L,1); - classBinding<objectType>::push(L, new objectType(),true); - return 1; - } -}; +#ifdef HAVE_LUA //no bindings +#include "LuaBindings.h" +#else +#include "DummyBindings.h" #endif + #endif diff --git a/Common/DummyBindings.h b/Common/DummyBindings.h new file mode 100644 index 0000000000000000000000000000000000000000..1d5eceb5ec811e518353212b2cd86ae5d5335d8b --- /dev/null +++ b/Common/DummyBindings.h @@ -0,0 +1,25 @@ +#ifndef _DUMMY_BINDINGS_H_ +#define _DUMMY_BINDINGS_H_ +class classBinding { +public: + void setDescription(std::string description){}; + template<typename parentType> + void setParentClass(){} + template <typename cb> + methodBinding *addMethod(std::string n, cb f){ + return new methodBinding(); + } + template <typename cb> + methodBinding *setConstructor(cb f){ + return new methodBinding(); + } +}; + +class binding { + public: + template<class t> + classBinding *addClass(std::string className){ + return new classBinding(); + } +}; +#endif diff --git a/Common/LuaBindings.cpp b/Common/LuaBindings.cpp index 39259741777bb48b095d92a8fa0cfa705f89e221..b88a153fc3bc5ca46ab661c16b863e392c3eb902 100644 --- a/Common/LuaBindings.cpp +++ b/Common/LuaBindings.cpp @@ -23,7 +23,6 @@ void report_errors(lua_State *L, int status) lua_pop(L, 1); // remove error message } } - int read_lua(const char *filename) { lua_State *L = lua_open(); @@ -34,20 +33,21 @@ int read_lua(const char *filename) luaopen_string(L); luaopen_math(L); luaopen_debug(L); + binding b; + b.L=L; // Register Lua bindings - classBinding<GModel>::Register(L); - classBinding<dgSystemOfEquations>::Register(L); - classBinding<dgBoundaryCondition>::Register(L); - classBinding<dgConservationLaw>::Register(L); - classBinding<dgConservationLawShallowWater2d>::Register(L); - classBinding<dgConservationLawAdvection>::Register(L); - classBinding<dgConservationLawWaveEquation>::Register(L); - classBinding<dgPerfectGasLaw2d>::Register(L); - classBinding<fullMatrix<double> >::Register(L); - classBinding<function>::Register(L); - classBinding<functionLua>::Register(L); - classBinding<functionConstant>::Register(L); + GModel::registerBindings(&b); + dgSystemOfEquations::registerBindings(&b); + dgBoundaryCondition::registerBindings(&b); + dgConservationLaw::registerBindings(&b); + dgConservationLawShallowWater2dRegisterBindings(&b); + dgConservationLawWaveEquationRegisterBindings(&b); + dgConservationLawAdvectionRegisterBindings(&b); + dgPerfectGasLaw2dRegisterBindings(&b); + fullMatrix<double>::registerBindings(&b); + function::registerBindings(&b); + functionLua::registerBindings(&b); function::registerDefaultFunctions(); int s = luaL_loadfile(L, filename); diff --git a/Common/LuaBindings.h b/Common/LuaBindings.h index f70c09cef3dba27ee43430b1d21f0c8c920eecde..6ef329eceb49687248c8f2d3ea78dafcf70daae3 100644 --- a/Common/LuaBindings.h +++ b/Common/LuaBindings.h @@ -1,6 +1,421 @@ #ifndef _LUA_BINDINGS_H_ #define _LUA_BINDINGS_H_ +#include "Bindings.h" #ifdef HAVE_LUA int read_lua(const char *filename); + +extern "C" { +#include "lua.h" +#include "lauxlib.h" +} +#include <vector> + + +/*** store a unique static class name for each binded class ***/ +template <typename type> +class className{ + static std::string _name; + public: + static void set(std::string name){ + if(_name!="") + throw; + _name=name; + } + static const std::string &get(){ + if(_name=="") + throw; + return _name; + } +}; +template<typename type> +std::string className<type>::_name; + + + + +/*** lua Stack : templates to get/push value from/on the lua stack ***/ + +template<class type> +class luaStack { + public: + static type get(lua_State *L, int ia){ + printf("error cannot get generic class in lua, only pointers are implemented\n"); + } + static void push(lua_State *L, type obj){ + printf("error cannot push generic class in lua, only pointers are implemented\n"); + } +}; + +template<> +class luaStack<lua_State *>{ + public: + static lua_State *get(lua_State *L, int ia){ + return L; + } + static void push(lua_State *L, int i){ + printf("error cannot push a lua_State in lua\n"); + } +}; + +template<> +class luaStack<int>{ + public: + static int get(lua_State *L, int ia){ + int a= luaL_checkint(L,ia); + return a; + } + static void push(lua_State *L, int i){ + lua_pushinteger(L,i); + } +}; + +template<class type> +class luaStack<std::vector<type > >{ + public: + static std::vector<type> get(lua_State *L, int ia){ + std::vector<type> v; + size_t size=lua_objlen(L,ia); + v.resize(size); + for(size_t i=0;i<size;i++){ + lua_pushinteger(L,i+1); + lua_gettable(L,ia); + v[i]=luaStack<type>::get(L,-1); + lua_pop(L,1); + } + return v; + } + static void push(lua_State *L, std::vector<type> a){ + } +}; + +template<> +class luaStack<double>{ + public: + static double get(lua_State *L, int ia){ + return luaL_checknumber(L,ia); + } + static void push(lua_State *L, double v){ + lua_pushnumber(L,v); + } +}; + +template<> +class luaStack<std::string>{ + public: + static std::string get(lua_State *L, int ia){ + return luaL_checkstring(L,ia); + } + static void push(lua_State *L, std::string s){ + lua_pushstring(L,s.c_str()); + } +}; + +template <typename type> +class luaStack<type *>{ + typedef struct { type *pT;} userdataType; + public: + static type* get(lua_State *L, int ia){ + userdataType *ud = static_cast<userdataType*>(lua_touserdata(L, ia)); + if(!ud) luaL_typerror(L, ia, className<type>::get().c_str()); + return ud->pT; + } + static void push(lua_State *L,type *obj){ + userdataType *ud = static_cast<userdataType*>(lua_newuserdata(L, sizeof(userdataType))); + ud->pT=obj; + luaL_getmetatable(L,className<type>::get().c_str()); // lookup metatable in Lua registry + lua_setmetatable(L, -2); + } +}; +template <typename type> +class luaStack<const type *>{ + typedef struct { type *pT;} userdataType; + public: + static type* get(lua_State *L, int ia){ + userdataType *ud = static_cast<userdataType*>(lua_touserdata(L, ia)); + if(!ud) luaL_typerror(L, ia, className<type>::get().c_str()); + return ud->pT; + } + static void push(lua_State *L,const type *obj){ + userdataType *ud = static_cast<userdataType*>(lua_newuserdata(L, sizeof(userdataType))); + ud->pT=(type*)obj; + luaL_getmetatable(L,className<type>::get().c_str()); // lookup metatable in Lua registry + lua_setmetatable(L, -2); + } +}; + +/*** template to call c function from the lua stack ***/ +//static, return (only used for contructor now) +template < typename tRet, typename t0, typename t1, typename t2, typename t3> +static int luaCall(lua_State *L,tRet (*_f)(t0,t1,t2,t3)) { + lua_remove(L,1); + luaStack<tRet>::push(L,(*(_f))(luaStack<t0>::get(L,1),luaStack<t1>::get(L,2),luaStack<t2>::get(L,3),luaStack<t3>::get(L,4))); + return 1; +}; +template < typename tRet, typename t0, typename t1, typename t2> +static int luaCall(lua_State *L,tRet (*_f)(t0,t1,t2)) { + lua_remove(L,1); + luaStack<tRet>::push(L,(*(_f))(luaStack<t0>::get(L,1),luaStack<t1>::get(L,2),luaStack<t2>::get(L,3))); + return 1; +}; +template < typename tRet, typename t0, typename t1> +static int luaCall(lua_State *L,tRet (*_f)(t0,t1)) { + lua_remove(L,1); + luaStack<tRet>::push(L,(*(_f))(luaStack<t0>::get(L,1),luaStack<t1>::get(L,2))); + return 1; +}; +template < typename tRet, typename t0> +static int luaCall(lua_State *L,tRet (*_f)(t0)) { + lua_remove(L,1); + luaStack<tRet>::push(L,(*(_f))(luaStack<t0>::get(L,1))); + return 1; +}; +template < typename tRet> +static int luaCall(lua_State *L,tRet (*_f)()) { + lua_remove(L,1); + luaStack<tRet>::push(L,(*(_f))()); + return 1; +}; + +//const, return +template <typename tObj, typename tRet, typename t0, typename t1, typename t2, typename t3> +static int luaCall(lua_State *L,tRet (tObj::*_f)(t0,t1,t2,t3) const) { + luaStack<tRet>::push(L,(luaStack<tObj*>::get(L,1)->*(_f))(luaStack<t0>::get(L,2),luaStack<t1>::get(L,3),luaStack<t2>::get(L,4),luaStack<t3>::get(L,5))); + return 1; +}; +template <typename tObj, typename tRet, typename t0, typename t1, typename t2> +static int luaCall(lua_State *L,tRet (tObj::*_f)(t0,t1,t2) const) { + luaStack<tRet>::push(L,(luaStack<tObj*>::get(L,1)->*(_f))(luaStack<t0>::get(L,2),luaStack<t1>::get(L,3),luaStack<t2>::get(L,4))); + return 1; +}; +template <typename tObj, typename tRet, typename t0, typename t1> +static int luaCall(lua_State *L,tRet (tObj::*_f)(t0,t1) const) { + luaStack<tRet>::push(L,(luaStack<tObj*>::get(L,1)->*(_f))(luaStack<t0>::get(L,2),luaStack<t1>::get(L,3))); + return 1; +}; +template <typename tObj, typename tRet, typename t0> +static int luaCall(lua_State *L,tRet (tObj::*_f)(t0) const) { + luaStack<tRet>::push(L,(luaStack<tObj*>::get(L,1)->*(_f))(luaStack<t0>::get(L,2))); + return 1; +}; +template <typename tObj, typename tRet> +static int luaCall(lua_State *L,tRet (tObj::*_f)() const) { + luaStack<tRet>::push(L,(luaStack<tObj*>::get(L,1)->*(_f))()); + return 1; +}; + +//non const, return +template <typename tObj, typename tRet, typename t0, typename t1, typename t2, typename t3> +static int luaCall(lua_State *L,tRet (tObj::*_f)(t0,t1,t2,t3)) { + luaStack<tRet>::push(L,(luaStack<tObj*>::get(L,1)->*(_f))(luaStack<t0>::get(L,2),luaStack<t1>::get(L,3),luaStack<t2>::get(L,4),luaStack<t3>::get(L,5))); + return 1; +}; +template <typename tObj, typename tRet, typename t0, typename t1, typename t2> +static int luaCall(lua_State *L,tRet (tObj::*_f)(t0,t1,t2)) { + luaStack<tRet>::push(L,(luaStack<tObj*>::get(L,1)->*(_f))(luaStack<t0>::get(L,2),luaStack<t1>::get(L,3),luaStack<t2>::get(L,4))); + return 1; +}; +template <typename tObj, typename tRet, typename t0, typename t1> +static int luaCall(lua_State *L,tRet (tObj::*_f)(t0,t1)) { + luaStack<tRet>::push(L,(luaStack<tObj*>::get(L,1)->*(_f))(luaStack<t0>::get(L,2),luaStack<t1>::get(L,3))); + return 1; +}; +template <typename tObj, typename tRet, typename t0> +static int luaCall(lua_State *L,tRet (tObj::*_f)(t0)) { + luaStack<tRet>::push(L,(luaStack<tObj*>::get(L,1)->*(_f))(luaStack<t0>::get(L,2))); + return 1; +}; +template <typename tObj, typename tRet> +static int luaCall(lua_State *L,tRet (tObj::*_f)()) { + luaStack<tRet>::push(L,(luaStack<tObj*>::get(L,1)->*(_f))()); + return 1; +}; + +//const, no return +template <typename tObj, typename t0, typename t1, typename t2, typename t3> +static int luaCall(lua_State *L,void (tObj::*_f)(t0,t1,t2,t3) const) { + (luaStack<tObj*>::get(L,1)->*(_f))(luaStack<t0>::get(L,2),luaStack<t1>::get(L,3),luaStack<t2>::get(L,4),luaStack<t3>::get(L,5)); + return 0; +}; +template <typename tObj, typename t0, typename t1, typename t2> +static int luaCall(lua_State *L,void (tObj::*_f)(t0,t1,t2) const) { + (luaStack<tObj*>::get(L,1)->*(_f))(luaStack<t0>::get(L,2),luaStack<t1>::get(L,3),luaStack<t2>::get(L,4)); + return 0; +}; +template <typename tObj, typename t0, typename t1> +static int luaCall(lua_State *L,void (tObj::*_f)(t0,t1) const) { + (luaStack<tObj*>::get(L,1)->*(_f))(luaStack<t0>::get(L,2),luaStack<t1>::get(L,3)); + return 0; +}; +template <typename tObj, typename t0> +static int luaCall(lua_State *L,void (tObj::*_f)(t0) const) { + (luaStack<tObj*>::get(L,1)->*(_f))(luaStack<t0>::get(L,2)); + return 0; +}; +template <typename tObj> +static int luaCall(lua_State *L,void (tObj::*_f)() const) { + (luaStack<tObj*>::get(L,1)->*(_f))(); + return 0; +}; + +//non const, no return +template <typename tObj, typename t0, typename t1, typename t2, typename t3> +static int luaCall(lua_State *L,void (tObj::*_f)(t0,t1,t2,t3)) { + (luaStack<tObj*>::get(L,1)->*(_f))(luaStack<t0>::get(L,2),luaStack<t1>::get(L,3),luaStack<t2>::get(L,4),luaStack<t3>::get(L,5)); + return 0; +}; +template <typename tObj, typename t0, typename t1, typename t2> +static int luaCall(lua_State *L,void (tObj::*_f)(t0,t1,t2)) { + (luaStack<tObj*>::get(L,1)->*(_f))(luaStack<t0>::get(L,2),luaStack<t1>::get(L,3),luaStack<t2>::get(L,4)); + return 0; +}; +template <typename tObj, typename t0, typename t1> +static int luaCall(lua_State *L,void (tObj::*_f)(t0,t1)) { + (luaStack<tObj*>::get(L,1)->*(_f))(luaStack<t0>::get(L,2),luaStack<t1>::get(L,3)); + return 0; +}; +template <typename tObj, typename t0> +static int luaCall(lua_State *L,void (tObj::*_f)(t0)) { + (luaStack<tObj*>::get(L,1)->*(_f))(luaStack<t0>::get(L,2)); + return 0; +}; +template <typename tObj> +static int luaCall(lua_State *L,void (tObj::*_f)()) { + (luaStack<tObj*>::get(L,1)->*(_f))(); + return 0; +}; + +/*** actual bindings classes ***/ +class luaMethodBinding :public methodBinding{ + public: + std::string _luaname; + virtual int call (lua_State *L)=0; + luaMethodBinding(const std::string luaname){ + _luaname=luaname; + } +}; + +template <typename cb> +class methodBindingT:public luaMethodBinding { + public: + cb _f; + methodBindingT(const std::string luaname,cb f):luaMethodBinding(luaname){ + _f=f; + } + int call (lua_State *L) { + return luaCall(L,_f); + } +}; + + +class classBinding { + std::string _className; + lua_State *_L; + static int callMethod(lua_State *L) { + return static_cast<luaMethodBinding*>(lua_touserdata(L, lua_upvalueindex(1)))->call(L); + } + //I'd like to remove the "luaMethodBinding" and the "methodBindingT" classes and use this callback insteak + //but for some reason I don't understand, it does not work + static int callMethod2(lua_State *L) { + int (*f)(lua_State*,void *)=(int (*)(lua_State*,void*))(lua_touserdata(L,lua_upvalueindex(1))); + void *ff=lua_touserdata(L,lua_upvalueindex(2)); + return (*f)(L,ff); + } + static int tostring (lua_State *L) { + typedef struct {void *pt;} userdata; + char buff[32]; + const char *name = luaL_checkstring(L,lua_upvalueindex(1)); + userdata *ud = static_cast<userdata*>(lua_touserdata(L, 1)); + sprintf(buff, "%p", ud->pt); + lua_pushfstring(L, "%s (%s)", name, buff); + return 1; + } +public: + // get userdata from Lua stack and return pointer to T object + classBinding(lua_State *L, std::string name){ + _L=L; + _className=name; + + // there are 3 tables involved : + // methods : the table of the C++ functions we bind (exept constructor) + // metatable : the metatable attached to each intance of the class, falling back to method (metatable.__index=method) + // mt : the metatable of method to store the constructor (__new) and possibly falling back to the parent metatable( __index) + lua_newtable(L); // methods + int methods = lua_gettop(L); + lua_pushvalue(L, methods); + lua_setglobal(L, _className.c_str()); // global[_className] = methods + + luaL_newmetatable(L, _className.c_str()); + int metatable = lua_gettop(L); + + lua_pushvalue(L, methods); + lua_setfield(L, metatable,"__index"); // metatable.__index=methods + + lua_pushstring(L,name.c_str()); + lua_pushcclosure(L, tostring,1); + lua_setfield(L, metatable,"__tostring"); + + lua_newtable(L); + int mt = lua_gettop(L); + + lua_setmetatable(L, methods); // setmetatable(methods, mt) + lua_pop(L, 2); // drop metatable and method table + } + template<typename parentType> + void setParentClass(){ + std::string parentClassName=className<parentType>::get(); + lua_getglobal(_L,_className.c_str()); + lua_getmetatable(_L,-1); + int mt=lua_gettop(_L); + lua_getglobal(_L,parentClassName.c_str()); + lua_setfield(_L,mt,"__index");// mt.__index = global[_parentClassName] // this is the inheritance bit + lua_pop(_L,2); + } + void setDescription(std::string description){}; + + template <typename cb> + methodBinding *addMethod(std::string n, cb f){ + luaMethodBinding *mb = new methodBindingT<cb>(n,f); + + lua_getglobal(_L,_className.c_str()); + int methods=lua_gettop(_L); + /*int (*lc)(lua_State *,cb)=(int(*)(lua_State*,cb))luaCall; + lua_pushlightuserdata(_L, (void*)lc); + lua_pushlightuserdata(_L, (void*)f); + lua_pushcclosure(_L, callMethod2, 2);*/ + lua_pushlightuserdata(_L, (void*)mb); + lua_pushcclosure(_L, callMethod, 1); + lua_setfield(_L,methods, n.c_str()); //className.name = callMethod(mb) + lua_pop(_L,1); + return mb; + } + template <typename cb> + methodBinding *setConstructor(cb f){ + luaMethodBinding *_constructorMethod = new methodBindingT<cb>("constructor",f); + + lua_getglobal(_L,_className.c_str()); + int methods = lua_gettop(_L); + lua_getmetatable(_L,methods); + int mt = lua_gettop(_L); + lua_pushlightuserdata(_L,(void*)_constructorMethod); + lua_pushcclosure(_L, callMethod, 1); + lua_setfield(_L, mt,"__call"); + lua_pop(_L,2); + return _constructorMethod; + } +}; + +class binding { + public: + lua_State *L; + template<class t> + classBinding *addClass(std::string className); +}; + +template<typename t> +classBinding *binding::addClass(std::string name){ + className<t>::set(name); + classBinding *cb=new classBinding(L,name); + return cb; +} #endif #endif diff --git a/Geo/GModel.cpp b/Geo/GModel.cpp index 453dae3999666308c496b6715564a7d3d0268136..3b2617342aa51335ffba6df3fdcad1d92f4d5ba1 100644 --- a/Geo/GModel.cpp +++ b/Geo/GModel.cpp @@ -1380,13 +1380,12 @@ void GModel::save(std::string fileName){ #ifdef HAVE_LUA #include "Bindings.h" -const char GModel::className[]="GModel"; -const char GModel::parentClassName[]=""; -methodBinding *GModel::methods[]={ - new methodBindingTemplate<GModel,int,int>("mesh",&GModel::mesh), - new methodBindingTemplate<GModel,void,std::string>("load",&GModel::load), - new methodBindingTemplate<GModel,void,std::string>("save",&GModel::save), - 0 -}; -constructorBinding *GModel::constructorMethod=new constructorBindingTemplate<GModel>(); +void GModel::registerBindings(binding *b){ + classBinding *cb = b->addClass<GModel>("GModel"); + methodBinding *cm; + cm = cb->addMethod("mesh",&GModel::mesh); + cm = cb->addMethod("load",&GModel::load); + cm = cb->addMethod("save",&GModel::save); + cb->setConstructor(constructorPtr<GModel>); +} #endif diff --git a/Geo/GModel.h b/Geo/GModel.h index aa025f734c91a6ce02749393403263fbc4ac604b..7aab300314ef13a9ea3afd663bb68fabf2e9a0f7 100644 --- a/Geo/GModel.h +++ b/Geo/GModel.h @@ -19,11 +19,6 @@ #include "SBoundingBox3d.h" #include "discreteFace.h" -#ifdef HAVE_LUA - class methodBinding; - class constructorBinding; -#endif - class Octree; class FM_Internals; class GEO_Internals; @@ -33,6 +28,7 @@ class FieldManager; class CGNSOptions; class gLevelset; class discreteFace; +class binding; // A geometric model. The model is a "not yet" non-manifold B-Rep. class GModel @@ -445,12 +441,7 @@ class GModel void save(std::string fileName); void load(std::string fileName); -#ifdef HAVE_LUA - static const char className[]; - static const char parentClassName[]; - static methodBinding *methods[]; - static constructorBinding *constructorMethod; -#endif + static void registerBindings(binding *b); }; #endif diff --git a/Numeric/fullMatrix.cpp b/Numeric/fullMatrix.cpp index 2b169cb54851a34c6aec2c82a07a7f7eee0fb5dd..d660be5003baa5e8a07bddd3f4ca0df51972cfbf 100644 --- a/Numeric/fullMatrix.cpp +++ b/Numeric/fullMatrix.cpp @@ -289,28 +289,16 @@ bool fullMatrix<double>::svd(fullMatrix<double> &V, fullVector<double> &S) return false; } -#if defined(HAVE_LUA) #include "Bindings.h" template<> -const char fullMatrix<double>::className[]="fullMatrix"; -template<> -const char fullMatrix<float>::className[]="fullMatrixFloat"; -template<> -const char fullMatrix<double>::parentClassName[]=""; -template<> -const char fullMatrix<float>::parentClassName[]=""; -template<> -methodBinding *fullMatrix<double>::methods[]={ - new methodBindingTemplate<const fullMatrix<double>,int>("size1",&fullMatrix<double>::size1), - new methodBindingTemplate<const fullMatrix<double>,int>("size2",&fullMatrix<double>::size2), - new methodBindingTemplate<const fullMatrix<double>,double,int,int>("get",&fullMatrix<double>::get), - new methodBindingTemplate<fullMatrix<double>,void,int,int,double>("set",&fullMatrix<double>::set), - new methodBindingTemplate<fullMatrix<double>,void,const fullMatrix<double>*,const fullMatrix<double> *>("gemm",&fullMatrix<double>::gemm), - 0 -}; -template<> -constructorBinding *fullMatrix<double>::constructorMethod = new constructorBindingTemplate<fullMatrix<double>,int,int>(); -#endif - - +void fullMatrix<double>::registerBindings(binding *b){ + classBinding *cb = b->addClass<fullMatrix<double> >("fullMatrix"); + methodBinding *cm; + cb->addMethod("size1",&fullMatrix<double>::size1); + cb->addMethod("size2",&fullMatrix<double>::size2); + cb->addMethod("get",&fullMatrix<double>::get); + cb->addMethod("set",&fullMatrix<double>::set); + cb->addMethod("gemm",&fullMatrix<double>::gemm); + cb->setConstructor(constructorPtr<fullMatrix<double>,int,int>); +} #endif diff --git a/Numeric/fullMatrix.h b/Numeric/fullMatrix.h index 4a3a2c451b4a05317061487d6e15fefe07889a88..9bec79e685025b0be6ed4a2fa929b77ca8e33b54 100644 --- a/Numeric/fullMatrix.h +++ b/Numeric/fullMatrix.h @@ -11,6 +11,7 @@ #include "GmshConfig.h" #include "GmshMessage.h" +class binding; template <class scalar> class fullMatrix; template <class scalar> @@ -93,10 +94,6 @@ class fullVector printf("\n"); } }; -#if defined(HAVE_LUA) -class methodBinding; -class constructorBinding; -#endif template <class scalar> class fullMatrix @@ -112,12 +109,6 @@ class fullMatrix inline void set(int r, int c, scalar v){ (*this)(r,c)=v; } -#if defined(HAVE_LUA) - static const char className[]; - static const char parentClassName[]; - static methodBinding *methods[]; - static constructorBinding *constructorMethod; -#endif // HAVE LUA fullMatrix(scalar *original, int r, int c){ _r = r; _c = c; @@ -219,9 +210,6 @@ class fullMatrix } #endif ; - inline void gemm (const fullMatrix<scalar> *a, const fullMatrix<scalar> *b){ - gemm(*a,*b); - } void gemm(const fullMatrix<scalar> &a, const fullMatrix<scalar> &b, scalar alpha=1., scalar beta=1.) #if !defined(HAVE_BLAS) @@ -370,6 +358,7 @@ inline void add(const fullMatrix<scalar> &m, const double &a) printf("\n"); } } + static void registerBindings(binding *b); }; #endif diff --git a/Solver/TESTCASES/Advection1D.lua b/Solver/TESTCASES/Advection1D.lua index fb2abf5186f4023214c73a0e56b7e0d634e0b75e..8df7e25056d5180acb96a72e5fdca6112291f35b 100644 --- a/Solver/TESTCASES/Advection1D.lua +++ b/Solver/TESTCASES/Advection1D.lua @@ -17,7 +17,7 @@ v:set(2,0,0) nu=fullMatrix(1,1); nu:set(0,0,0) -law = ConservationLawAdvection(FunctionConstant(v):getName(), '') +law = dgConservationLawAdvection(functionConstant(v):getName(), '') --FunctionConstant(nu):getName()) dg:setConservationLaw(law) @@ -25,7 +25,7 @@ dg:setConservationLaw(law) -- boundary condition outside=fullMatrix(1,1) outside:set(0,0,0.) -bndcondition=law:newOutsideValueBoundary(FunctionConstant(outside):getName()) +bndcondition=law:newOutsideValueBoundary(functionConstant(outside):getName()) law:addBoundaryCondition('Left',bndcondition) law:addBoundaryCondition('Right',bndcondition) @@ -44,7 +44,7 @@ function initial_condition( xyz , f ) end end end -dg:L2Projection(FunctionLua(1,'initial_condition',{'XYZ'}):getName()) +dg:L2Projection(functionLua(1,'initial_condition',{'XYZ'}):getName()) dg:exportSolution('output/Adv1D_unlimited') dg:limitSolution() diff --git a/Solver/TESTCASES/Advection3D.lua b/Solver/TESTCASES/Advection3D.lua index 14de45f995fb91c58f892493fd19132f454d8c1c..149f7fbc4b39d8402f4fcdef0f89c2436d189be9 100644 --- a/Solver/TESTCASES/Advection3D.lua +++ b/Solver/TESTCASES/Advection3D.lua @@ -15,16 +15,16 @@ v:set(2,0,0) nu=fullMatrix(1,1); nu:set(0,0,0.001) ---law = ConservationLawAdvection(FunctionConstant(v):getName(),FunctionConstant(nu):getName()) ---law = ConservationLawAdvection('',FunctionConstant(nu):getName()) -law = ConservationLawAdvection(FunctionConstant(v):getName(),'') +--law = ConservationLawAdvection(functionConstant(v):getName(),functionConstant(nu):getName()) +--law = ConservationLawAdvection('',functionConstant(nu):getName()) +law = dgConservationLawAdvection(functionConstant(v):getName(),'') dg:setConservationLaw(law) -- boundary condition outside=fullMatrix(1,1) outside:set(0,0,1) -bndcondition=law:newOutsideValueBoundary(FunctionConstant(outside):getName()) +bndcondition=law:newOutsideValueBoundary(functionConstant(outside):getName()) --[[law:addBoundaryCondition('Left',bndcondition) law:addBoundaryCondition('Right',bndcondition) --]] @@ -41,7 +41,7 @@ function initial_condition( xyz , f ) f:set (i, 0, x ) end end --- dg:L2Projection(FunctionLua(1,'initial_condition',{'XYZ'}):getName()) +-- dg:L2Projection(functionLua(1,'initial_condition',{'XYZ'}):getName()) law:addBoundaryCondition('boundary',law:new0FluxBoundary()) diff --git a/Solver/TESTCASES/AdvectionDiffusion.lua b/Solver/TESTCASES/AdvectionDiffusion.lua index 3be0149715359c7320b28a4af8f7b8558ced965e..56a34529dc1daa5bc7af4b3cd777006d16dd3c13 100644 --- a/Solver/TESTCASES/AdvectionDiffusion.lua +++ b/Solver/TESTCASES/AdvectionDiffusion.lua @@ -10,7 +10,7 @@ vmodel[1]:load('') vmodel[2]:load('') dg = dgSystemOfEquations (model) -dg:setOrder(1) +dg:setOrder(3) -- conservation law @@ -24,13 +24,13 @@ v:set(2,0,0) nu=fullMatrix(1,1); nu:set(0,0,0.001) -law = ConservationLawAdvection(FunctionConstant(v):getName(),FunctionConstant(nu):getName()) +law = dgConservationLawAdvection(functionConstant(v):getName(),functionConstant(nu):getName()) dg:setConservationLaw(law) -- boundary condition outside=fullMatrix(1,1) outside:set(0,0,0.) -law:addBoundaryCondition('Border',law:newOutsideValueBoundary(FunctionConstant(outside):getName())) +law:addBoundaryCondition('Border',law:newOutsideValueBoundary(functionConstant(outside):getName())) dg:setup() @@ -43,14 +43,14 @@ function initial_condition( xyz , f ) f:set (i, 0, math.exp(-100*((x-0.2)^2 +(y-0.3)^2))) end end -dg:L2Projection(FunctionLua(1,'initial_condition',{'XYZ'}):getName()) +dg:L2Projection(functionLua(1,'initial_condition',{'XYZ'}):getName()) dg:exportSolution('output/Advection_00000') -- main loop for i=1,10000 do norm = dg:RK44(0.01) - if (i % 1 == 0) then + if (i % 10 == 0) then print('iter',i,norm) dg:exportSolution(string.format("output/Advection-%05d", i)) end diff --git a/Solver/TESTCASES/Diffusion.lua b/Solver/TESTCASES/Diffusion.lua index 4b969dc01e2a50ea87dc33a0363c98c17660fd37..b8093035934f6b9b44b08ab2bc77f13ffefe114b 100644 --- a/Solver/TESTCASES/Diffusion.lua +++ b/Solver/TESTCASES/Diffusion.lua @@ -2,14 +2,14 @@ model = GModel () model:load ('square.geo') model:load ('square.msh') dg = dgSystemOfEquations (model) -dg:setOrder(5) +dg:setOrder(3) -- conservation law -- advection speed nu=fullMatrix(1,1); nu:set(0,0,0.01) -law = ConservationLawAdvection('',FunctionConstant(nu):getName()) +law = dgConservationLawAdvection('',functionConstant(nu):getName()) dg:setConservationLaw(law) -- boundary condition @@ -28,7 +28,7 @@ function initial_condition( xyz , f ) f:set (i, 0, math.exp(-100*((x-0.2)^2 +(y-0.3)^2))) end end -dg:L2Projection(FunctionLua(1,'initial_condition',{'XYZ'}):getName()) +dg:L2Projection(functionLua(1,'initial_condition',{'XYZ'}):getName()) dg:exportSolution('output/Diffusion_00000') diff --git a/Solver/TESTCASES/ForwardFacingStep.lua b/Solver/TESTCASES/ForwardFacingStep.lua index e474376ad9a10315e642d7f881350281120834c0..2c4ccff29aeabd9c746d0f1ae3c98f4bf3901f5b 100644 --- a/Solver/TESTCASES/ForwardFacingStep.lua +++ b/Solver/TESTCASES/ForwardFacingStep.lua @@ -28,11 +28,11 @@ myModel:load ('step.msh') print'*** Create a dg solver ***' DG = dgSystemOfEquations (myModel) DG:setOrder(order) -law=ConservationLawPerfectGas2d() +law=dgPerfectGasLaw2d() DG:setConservationLaw(law) law:addBoundaryCondition('Walls',law:newWallBoundary()) -FS = FunctionLua(4, 'free_stream', {'XYZ'}):getName() +FS = functionLua(4, 'free_stream', {'XYZ'}):getName() law:addBoundaryCondition('LeftRight',law:newOutsideValueBoundary(FS)) DG:setup() diff --git a/Solver/TESTCASES/Stommel.lua b/Solver/TESTCASES/Stommel.lua index b5017e97c941d5cf8703f8efab0df1fdf243cea9..b7b1ef93c754c32a754cafa9c7f5f128b02c0b67 100644 --- a/Solver/TESTCASES/Stommel.lua +++ b/Solver/TESTCASES/Stommel.lua @@ -3,8 +3,8 @@ model:load ('stommel_square.msh') dg = dgSystemOfEquations (model) order=1 dg:setOrder (order) -claw = ShallowWater2d() -claw:addBoundaryCondition('Wall',claw:newWallBoundary()) +claw = dgConservationLawShallowWater2d() +claw:addBoundaryCondition('Wall',claw:newBoundaryWall()) dg:setConservationLaw(claw) dg:setup() diff --git a/Solver/TESTCASES/WavePulse.lua b/Solver/TESTCASES/WavePulse.lua index a9251261f9846e87d706631612ae3d440b19f9d0..982cfeb34db6ac4300a7e8dc7876a6a59ef67708 100644 --- a/Solver/TESTCASES/WavePulse.lua +++ b/Solver/TESTCASES/WavePulse.lua @@ -27,15 +27,16 @@ myModel = GModel () --myModel:load('square_quads.msh') myModel:load('square_mixed.msh') + print'*** Create a dg solver ***' DG = dgSystemOfEquations (myModel) -DG:setOrder(2) -law=ConservationLawWaveEquation(2) +DG:setOrder(3) +law=dgConservationLawWaveEquation(2) DG:setConservationLaw(law) -law:addBoundaryCondition('Border',law:newWallBoundary()) +law:addBoundaryCondition('Border',law:newBoundaryWall()) DG:setup() -initialCondition = FunctionLua(3,'initial_condition',{'XYZ'}):getName() +initialCondition = functionLua(3,'initial_condition',{'XYZ'}):getName() print'*** setting the initial solution ***' @@ -55,7 +56,7 @@ for i=1,N do -- norm = DG:multirateRK43(dt) norm = DG:RK44(dt) print('*** ITER ***',i,norm) - if (i % 100 == 0) then + if (i % 10 == 0) then DG:exportSolution(string.format("output/solution-%04d", i)) end end diff --git a/Solver/TESTCASES/square_mixed.geo b/Solver/TESTCASES/square_mixed.geo index 267a1bd2df059225386757395d917c745cc0539c..bfc7da2a66518f15fe09658bfed76d08e7983712 100644 --- a/Solver/TESTCASES/square_mixed.geo +++ b/Solver/TESTCASES/square_mixed.geo @@ -1,4 +1,4 @@ -N=25; +N=5; Point(1) = {0.0, 0.0, 0, .03}; Point(2) = {1, 0.0, 0, .03}; Point(3) = {1, 1, 0, .03}; diff --git a/Solver/dgConservationLaw.cpp b/Solver/dgConservationLaw.cpp index f1e8cd05def2f64a22f0f373eb95ac6ce3c8e0eb..fce315c2a3bb54fee79db05a086491a81e71b453 100644 --- a/Solver/dgConservationLaw.cpp +++ b/Solver/dgConservationLaw.cpp @@ -63,15 +63,16 @@ dgBoundaryCondition *dgConservationLaw::new0FluxBoundary() { } #include "Bindings.h" -const char dgConservationLaw::className[]="ConservationLaw"; -const char dgConservationLaw::parentClassName[]=""; -methodBinding * dgConservationLaw::methods[]={ - new methodBindingTemplate<dgConservationLaw,void,std::string,dgBoundaryCondition*>("addBoundaryCondition",&dgConservationLaw::addBoundaryCondition), - new methodBindingTemplate<dgConservationLaw,dgBoundaryCondition*>("new0FluxBoundary",&dgConservationLaw::new0FluxBoundary), - new methodBindingTemplate<dgConservationLaw,dgBoundaryCondition*,std::string>("newOutsideValueBoundary",&dgConservationLaw::newOutsideValueBoundary), -0}; -constructorBinding * dgConservationLaw::constructorMethod=NULL; -const char dgBoundaryCondition::className[]="BoundaryCondition"; -const char dgBoundaryCondition::parentClassName[]=""; -methodBinding * dgBoundaryCondition::methods[]={0}; -constructorBinding * dgBoundaryCondition::constructorMethod=NULL; + +void dgConservationLaw::registerBindings(binding *b){ + classBinding *cb = b->addClass<dgConservationLaw>("dgConservationLaw"); + cb->addMethod("addBoundaryCondition",&dgConservationLaw::addBoundaryCondition); + cb->addMethod("new0FluxBoundary",&dgConservationLaw::new0FluxBoundary); + cb->addMethod("newOutsideValueBoundary",&dgConservationLaw::newOutsideValueBoundary); +} + + + +void dgBoundaryCondition::registerBindings(binding *b){ + classBinding *cb = b->addClass<dgBoundaryCondition>("dgBoundaryCondition"); +} diff --git a/Solver/dgConservationLaw.h b/Solver/dgConservationLaw.h index 7e037cd3e1312ce9f8d4bcf2e371438d070b8d0f..6a4460a637fd105f470da4842085a5f1823e7add 100644 --- a/Solver/dgConservationLaw.h +++ b/Solver/dgConservationLaw.h @@ -9,19 +9,15 @@ #include "fullMatrix.h" class dataCacheDouble; class dataCacheMap; -class constructorBinding; -class methodBinding; class dgConservationLaw; +class binding; class dgBoundaryCondition { public: virtual ~dgBoundaryCondition () {} virtual dataCacheDouble *newBoundaryTerm(dataCacheMap &cacheMapLeft) const = 0; - static const char className[]; - static const char parentClassName[]; - static methodBinding *methods[]; - static constructorBinding *constructorMethod; + static void registerBindings(binding *b); }; class dgConservationLaw { @@ -58,10 +54,7 @@ class dgConservationLaw { dgBoundaryCondition *newOutsideValueBoundary(std::string outsideValueFunctionName); dgBoundaryCondition *new0FluxBoundary(); - static const char className[]; - static const char parentClassName[]; - static methodBinding *methods[]; - static constructorBinding *constructorMethod; + static void registerBindings(binding *b); }; dgConservationLaw *dgNewPerfectGasLaw2d(); diff --git a/Solver/dgConservationLawAdvection.cpp b/Solver/dgConservationLawAdvection.cpp index a97805fca2510274a6412bce64eff5d821bcc30b..a8b02efa194eee511ade39d087a60ab745004027 100644 --- a/Solver/dgConservationLawAdvection.cpp +++ b/Solver/dgConservationLawAdvection.cpp @@ -94,8 +94,9 @@ dgConservationLawAdvection::dgConservationLawAdvection(std::string vFunctionName } #include "Bindings.h" -const char * dgConservationLawAdvection::className = "ConservationLawAdvection"; -const char * dgConservationLawAdvection::parentClassName = "ConservationLaw"; -constructorBinding *dgConservationLawAdvection::constructorMethod = new constructorBindingTemplate<dgConservationLawAdvection,std::string,std::string>(); -methodBinding *dgConservationLawAdvection::methods []={0}; +void dgConservationLawAdvectionRegisterBindings (binding *b){ + classBinding *cb = b->addClass<dgConservationLawAdvection>("dgConservationLawAdvection"); + cb->setConstructor(constructorPtr<dgConservationLawAdvection,std::string,std::string>); + cb->setParentClass<dgConservationLaw>(); +} diff --git a/Solver/dgConservationLawAdvection.h b/Solver/dgConservationLawAdvection.h index 69c11578a2bb322280158e1ed91a1326a3ea47d5..f56894bb21ca4e7348df329a6bfd7b0c7d2fbcb7 100644 --- a/Solver/dgConservationLawAdvection.h +++ b/Solver/dgConservationLawAdvection.h @@ -1,8 +1,6 @@ #ifndef _DG_CONSERVATION_LAW_ADVECTION_H #define _DG_CONSERVATION_LAW_ADVECTION_H #include "dgConservationLaw.h" -class constructorBinding; -class methodBinding; class dgConservationLawAdvection : public dgConservationLaw { std::string _vFunctionName,_nuFunctionName; class advection; @@ -14,9 +12,7 @@ class dgConservationLawAdvection : public dgConservationLaw { dataCacheDouble *newRiemannSolver( dataCacheMap &cacheMapLeft, dataCacheMap &cacheMapRight) const; dataCacheDouble *newDiffusiveFlux( dataCacheMap &cacheMap) const; dgConservationLawAdvection(std::string vFunctionName, std::string nuFunctionName); - static const char * className; - static const char * parentClassName; - static methodBinding *methods[]; - static constructorBinding *constructorMethod; }; +class binding; +void dgConservationLawAdvectionRegisterBindings (binding *b); #endif diff --git a/Solver/dgConservationLawPerfectGas.cpp b/Solver/dgConservationLawPerfectGas.cpp index 4776a51719042691995e5fe9b4e433a5e398055d..5a21432eea53711356582724ff11e1b57aaf9ef0 100644 --- a/Solver/dgConservationLawPerfectGas.cpp +++ b/Solver/dgConservationLawPerfectGas.cpp @@ -311,10 +311,11 @@ class dgBoundaryConditionPerfectGasLaw2dFreeStream : public dgBoundaryCondition #endif #include "Bindings.h" -const char *dgPerfectGasLaw2d::className = "ConservationLawPerfectGas2d"; -const char *dgPerfectGasLaw2d::parentClassName = "ConservationLaw"; -methodBinding *dgPerfectGasLaw2d::methods[] ={ - new methodBindingTemplate<const dgPerfectGasLaw2d,dgBoundaryCondition*>("newWallBoundary",&dgPerfectGasLaw2d::newWallBoundary), -0}; -constructorBinding *dgPerfectGasLaw2d::constructorMethod=new constructorBindingTemplate<dgPerfectGasLaw2d>(); +void dgPerfectGasLaw2dRegisterBindings (binding *b){ + classBinding *cb = b->addClass<dgPerfectGasLaw2d>("dgPerfectGasLaw2d"); + methodBinding *cm; + cb->addMethod("newWallBoundary",&dgPerfectGasLaw2d::newWallBoundary); + cb->setConstructor(constructorPtr<dgPerfectGasLaw2d>); + cb->setParentClass<dgConservationLaw>(); +} diff --git a/Solver/dgConservationLawPerfectGas.h b/Solver/dgConservationLawPerfectGas.h index 434e9e602a51a2adf66ea016798b1d4ff2651539..c53ff8c057d001a3b642873c3d5ad7f8bd402e2d 100644 --- a/Solver/dgConservationLawPerfectGas.h +++ b/Solver/dgConservationLawPerfectGas.h @@ -11,10 +11,8 @@ class dgPerfectGasLaw2d : public dgConservationLaw { dataCacheDouble *newDiffusiveFlux( dataCacheMap &cacheMap) const; dataCacheDouble *newSourceTerm (dataCacheMap &cacheMap) const; dgPerfectGasLaw2d(); - static const char * className; - static const char * parentClassName; - static methodBinding *methods[]; - static constructorBinding *constructorMethod; dgBoundaryCondition *newWallBoundary()const ; }; +class binding; +void dgPerfectGasLaw2dRegisterBindings(binding *b); #endif diff --git a/Solver/dgConservationLawShallowWater2d.cpp b/Solver/dgConservationLawShallowWater2d.cpp index 76ddc2f910b0c58d65417cbb44a546e926e63f83..de798d27b071ebb489974f9c1352e721a174dbc3 100644 --- a/Solver/dgConservationLawShallowWater2d.cpp +++ b/Solver/dgConservationLawShallowWater2d.cpp @@ -140,13 +140,11 @@ dgBoundaryCondition *dgConservationLawShallowWater2d::newBoundaryWall(){ return new boundaryWall(); } -#ifdef HAVE_LUA #include "Bindings.h" -const char dgConservationLawShallowWater2d::className[]="ShallowWater2d"; -const char dgConservationLawShallowWater2d::parentClassName[]="ConservationLaw"; -methodBinding *dgConservationLawShallowWater2d::methods[]={ - new methodBindingTemplate<dgConservationLawShallowWater2d,dgBoundaryCondition*>("newWallBoundary",&dgConservationLawShallowWater2d::newBoundaryWall), - 0 -}; -constructorBinding *dgConservationLawShallowWater2d::constructorMethod=new constructorBindingTemplate<dgConservationLawShallowWater2d>(); -#endif +void dgConservationLawShallowWater2dRegisterBindings (binding *b){ + classBinding *cb = b->addClass<dgConservationLawShallowWater2d>("dgConservationLawShallowWater2d"); + methodBinding *cm; + cb->addMethod("newBoundaryWall",&dgConservationLawShallowWater2d::newBoundaryWall); + cb->setConstructor(constructorPtr<dgConservationLawShallowWater2d>); + cb->setParentClass<dgConservationLaw>(); +} diff --git a/Solver/dgConservationLawShallowWater2d.h b/Solver/dgConservationLawShallowWater2d.h index c37c9525e2320800933ebaa75bf6ea491a3d8a89..2cf268972b24657e820c4b64806178fd97320843 100644 --- a/Solver/dgConservationLawShallowWater2d.h +++ b/Solver/dgConservationLawShallowWater2d.h @@ -2,11 +2,8 @@ #define _DG_CONSERVATION_LAW_SHALLOW_WATER_2D_ #include "dgConservationLaw.h" -#ifdef HAVE_LUA -class methodBinding; -class constructorBinding; -#endif class dataCacheMap; +class binding; class dgConservationLawShallowWater2d : public dgConservationLaw { class advection; @@ -23,11 +20,6 @@ class dgConservationLawShallowWater2d : public dgConservationLaw { _nbf = 3; // H U(=Hu) V(=Hv) } dgBoundaryCondition *newBoundaryWall(); -#ifdef HAVE_LUA - static const char className[]; - static const char parentClassName[]; - static methodBinding *methods[]; - static constructorBinding *constructorMethod; -#endif }; +void dgConservationLawShallowWater2dRegisterBindings(binding *b); #endif diff --git a/Solver/dgConservationLawWaveEquation.cpp b/Solver/dgConservationLawWaveEquation.cpp index 9d9e18ef7247aa99aa4fbb6dad67b8039760375c..583b79c7e0c818c5d4a877c3ebbe35de48b4d97e 100644 --- a/Solver/dgConservationLawWaveEquation.cpp +++ b/Solver/dgConservationLawWaveEquation.cpp @@ -136,9 +136,10 @@ dgBoundaryCondition *dgConservationLawWaveEquation::newBoundaryWall()const{ } #include "Bindings.h" -const char *dgConservationLawWaveEquation::className = "ConservationLawWaveEquation"; -const char *dgConservationLawWaveEquation::parentClassName = "ConservationLaw"; -methodBinding *dgConservationLawWaveEquation::methods[] ={ - new methodBindingTemplate<const dgConservationLawWaveEquation,dgBoundaryCondition*>("newWallBoundary",&dgConservationLawWaveEquation::newBoundaryWall), -0}; -constructorBinding *dgConservationLawWaveEquation::constructorMethod=new constructorBindingTemplate<dgConservationLawWaveEquation,int>(); +void dgConservationLawWaveEquationRegisterBindings(binding *b){ + classBinding *cb = b->addClass<dgConservationLawWaveEquation> ("dgConservationLawWaveEquation"); + methodBinding *cm; + cb->addMethod("newBoundaryWall",&dgConservationLawWaveEquation::newBoundaryWall); + cb->setConstructor(constructorPtr<dgConservationLawWaveEquation,int>); + cb->setParentClass<dgConservationLaw>(); +} diff --git a/Solver/dgConservationLawWaveEquation.h b/Solver/dgConservationLawWaveEquation.h index 530dff8b2d080b4f57c9e57f766fa4e06e16ded4..ee3498acdd00ded72aecc1712a91e7c0b7c2ab38 100644 --- a/Solver/dgConservationLawWaveEquation.h +++ b/Solver/dgConservationLawWaveEquation.h @@ -21,4 +21,5 @@ class dgConservationLawWaveEquation : public dgConservationLaw { static methodBinding *methods[]; static constructorBinding *constructorMethod; }; +void dgConservationLawWaveEquationRegisterBindings(binding *b); #endif diff --git a/Solver/dgSystemOfEquations.cpp b/Solver/dgSystemOfEquations.cpp index b514d7a0e882e443be6a85b623e185d35b7ba662..df6070965a80fa91c27cde15c6943a0e21960f49 100644 --- a/Solver/dgSystemOfEquations.cpp +++ b/Solver/dgSystemOfEquations.cpp @@ -37,24 +37,34 @@ void dgSystemOfEquations::setConservationLaw (dgConservationLaw *law){ _claw=law; } -#ifdef HAVE_LUA #include "Bindings.h" -const char dgSystemOfEquations::className[] = "dgSystemOfEquations"; -const char dgSystemOfEquations::parentClassName[] = ""; -constructorBinding *dgSystemOfEquations::constructorMethod = new constructorBindingTemplate<dgSystemOfEquations,GModel*>(); -methodBinding *dgSystemOfEquations::methods[]={ - new methodBindingTemplate<dgSystemOfEquations,void,int>("setOrder",&dgSystemOfEquations::setOrder), - new methodBindingTemplate<dgSystemOfEquations,void,dgConservationLaw*>("setConservationLaw",&dgSystemOfEquations::setConservationLaw), - new methodBindingTemplate<dgSystemOfEquations,void>("setup",&dgSystemOfEquations::setup), - new methodBindingTemplate<dgSystemOfEquations,void,std::string>("exportSolution",&dgSystemOfEquations::exportSolution), - new methodBindingTemplate<dgSystemOfEquations,void>("limitSolution",&dgSystemOfEquations::limitSolution), - new methodBindingTemplate<dgSystemOfEquations,void,std::string>("L2Projection",&dgSystemOfEquations::L2Projection), - new methodBindingTemplate<dgSystemOfEquations,double,double>("RK44",&dgSystemOfEquations::RK44), - new methodBindingTemplate<dgSystemOfEquations,double>("computeInvSpectralRadius",&dgSystemOfEquations::computeInvSpectralRadius), - new methodBindingTemplate<dgSystemOfEquations,double,double>("RK44_limiter",&dgSystemOfEquations::RK44_limiter), - new methodBindingTemplate<dgSystemOfEquations,double,double>("multirateRK43",&dgSystemOfEquations::multirateRK43), - 0}; -#endif // HAVE_LUA +void dgSystemOfEquations::registerBindings(binding *b){ + classBinding *cb = b->addClass<dgSystemOfEquations>("dgSystemOfEquations"); + cb->setDescription("a class to rule them all :-) -- bad description, this class will be removed anyway"); + cb->setConstructor(constructorPtr<dgSystemOfEquations,GModel*>); + methodBinding *cm; + cm = cb->addMethod("setConservationLaw",&dgSystemOfEquations::setConservationLaw); + cm->setArgNames("law",NULL); + cm->setDescription("set the conservation law this system solve"); + cm = cb->addMethod("setup",&dgSystemOfEquations::setup); + cm->setDescription("allocate and init internal stuff, call this function after setOrder and setLaw and before anything else on this instance"); + cm = cb->addMethod("exportSolution",&dgSystemOfEquations::exportSolution); + cm->setArgNames("filename",NULL); + cm->setDescription("Print the solution into a file. This file does not contain the mesh. To visualize the solution in gmsh you have to open the mesh file first."); + cm= cb->addMethod("L2Projection",&dgSystemOfEquations::L2Projection); + cm->setArgNames("functionName",NULL); + cm->setDescription("project the function \"functionName\" on the solution vector"); + cm = cb->addMethod("RK44",&dgSystemOfEquations::RK44); + cm->setArgNames("norm","dt",NULL); + cm->setDescription("do a runge-kuta temporal iteration with a time step \"dt\" and return the sum of the nodal residuals"); + cm = cb->addMethod("setOrder",&dgSystemOfEquations::setOrder); + cm->setArgNames("order",NULL); + cm->setDescription("set the polynpolynomialomial order of the lagrange shape functions"); + cb->addMethod("limitSolution",&dgSystemOfEquations::limitSolution); + cb->addMethod("computeInvSpectralRadius",&dgSystemOfEquations::computeInvSpectralRadius); + cb->addMethod("RK44_limiter",&dgSystemOfEquations::RK44_limiter); + cb->addMethod("multirateRK43",&dgSystemOfEquations::multirateRK43); +} // do a L2 projection void dgSystemOfEquations::L2Projection (std::string functionName){ diff --git a/Solver/dgSystemOfEquations.h b/Solver/dgSystemOfEquations.h index 32aa5d8c2e57f3ae292e8324f936d16894f55001..edc36dddf71bafa1f5ede84d035e2e6c01800939 100644 --- a/Solver/dgSystemOfEquations.h +++ b/Solver/dgSystemOfEquations.h @@ -26,8 +26,7 @@ public: int getNbFields() {return nbFields;} }; -class methodBinding; -class constructorBinding; +class binding; class dgSystemOfEquations { // the mesh and the model @@ -65,10 +64,7 @@ public: void L2Projection (std::string functionName); // assign the solution to a given function double computeInvSpectralRadius(); - static const char className[]; - static const char parentClassName[]; - static methodBinding *methods[]; - static constructorBinding *constructorMethod; + static void registerBindings(binding *b); inline const fullMatrix<double> getSolutionProxy (int iGroup, int iElement){ return fullMatrix<double> ( *_solution->_dataProxys [iGroup] , diff --git a/Solver/function.cpp b/Solver/function.cpp index f092620340b91f1859f14dab80308ae105f54522..209fddc2a26c02632d15a9d965478d334a920f09 100644 --- a/Solver/function.cpp +++ b/Solver/function.cpp @@ -141,23 +141,17 @@ functionConstant::functionConstant(const fullMatrix<double> *source){ } #include "Bindings.h" -const char *functionConstant::className="FunctionConstant"; -const char *functionConstant::parentClassName="Function"; -methodBinding *functionConstant::methods[]={0}; -constructorBinding *functionConstant::constructorMethod=new constructorBindingTemplate<functionConstant,fullMatrix<double>*>(); - - - - void function::registerDefaultFunctions() { function::add("XYZ", new functionXYZ); } -const char *function::className="Function"; -const char *function::parentClassName=""; -methodBinding *function::methods[]={new methodBindingTemplate<const function,std::string>("getName",&function::getName), -0}; -constructorBinding *function::constructorMethod=0; +void function::registerBindings(binding *b){ + classBinding *cb = b->addClass<function>("function"); + cb->addMethod("getName",&function::getName); + cb = b->addClass<functionConstant>("functionConstant"); + cb->setConstructor(constructorPtr<functionConstant,fullMatrix<double>*>); + cb->setParentClass<function>(); +} diff --git a/Solver/function.h b/Solver/function.h index 88b6fe5fb64e33d043be662b409f9f5bebcc7eea..bc8bdc5c4a41479fc6412763e9cc974999d00383 100644 --- a/Solver/function.h +++ b/Solver/function.h @@ -7,8 +7,7 @@ #include <fullMatrix.h> class dataCacheMap; class MElement; -class methodBinding; -class constructorBinding; +class binding; // those classes manage complex function dependencies and keep their values in cache so that they are not recomputed when it is not necessary. To do this, we use three classes : function, dataCache and dataCacheMap. The workflow is : // @@ -127,11 +126,8 @@ class function { inline std::string getName()const {return _name;} - static const char *className; - static const char *parentClassName; - static methodBinding *methods[]; - static constructorBinding *constructorMethod; virtual ~function(){}; + static void registerBindings(binding *b); }; // A special node in the dependency tree for which all the leafs @@ -179,12 +175,5 @@ class functionConstant : public function { fullMatrix<double> _source; dataCacheDouble *newDataCache(dataCacheMap *m); functionConstant(const fullMatrix<double> *source); - static const char *className; - static const char *parentClassName; - static methodBinding *methods[]; - static constructorBinding *constructorMethod; - ~functionConstant(){ - printf("delete fc\n"); - } }; #endif diff --git a/Solver/luaFunction.cpp b/Solver/luaFunction.cpp index 4e7083cfd5f23391bfc0a16f6417045ec20b9260..832ddded3f3ef713c83b3dd4de480b224ee3b7c3 100644 --- a/Solver/luaFunction.cpp +++ b/Solver/luaFunction.cpp @@ -26,9 +26,9 @@ class functionLua::data : public dataCacheDouble{ lua_getfield(_function->_L, LUA_GLOBALSINDEX, _function->_luaFunctionName.c_str()); for (int i=0;i< _dependencies.size();i++){ const fullMatrix<double> *data = &(*_dependencies[i])(); - classBinding<const fullMatrix<double> >::push(_function->_L,data,false); + luaStack<const fullMatrix<double>*>::push(_function->_L,data); } - classBinding<const fullMatrix<double> >::push(_function->_L,&_value,false); + luaStack<const fullMatrix<double>*>::push(_function->_L,&_value); lua_call(_function->_L,_dependencies.size()+1,0); /* call Lua function */ } }; @@ -46,9 +46,10 @@ dataCacheDouble *functionLua::newDataCache(dataCacheMap *m) return new data(this,m); } -const char *functionLua::className="FunctionLua"; -const char *functionLua::parentClassName="Function"; -methodBinding *functionLua::methods[]={0}; -constructorBinding *functionLua::constructorMethod=new constructorBindingTemplate<functionLua,int,std::string,std::vector<std::string> ,lua_State*>(); +void functionLua::registerBindings(binding *b){ + classBinding *cb= b->addClass<functionLua>("functionLua"); + cb->setConstructor(constructorPtr<functionLua,int,std::string,std::vector<std::string>,lua_State*>); + cb->setParentClass<function>(); +} #endif // HAVE LUA diff --git a/Solver/luaFunction.h b/Solver/luaFunction.h index 63e66c937e420ccaf2f229bb854404788d42a68a..2ded4ce76d655b820ba84692eeb3861f2e43329a 100644 --- a/Solver/luaFunction.h +++ b/Solver/luaFunction.h @@ -6,6 +6,7 @@ class lua_State; #include <string> #include <vector> +class binding; class functionLua : public function { lua_State *_L; std::string _luaFunctionName; @@ -16,10 +17,7 @@ class functionLua : public function { functionLua (int nbCol, std::string &luaFunctionName, std::vector<std::string> &dependenciesName, lua_State *L); dataCacheDouble *newDataCache(dataCacheMap *m); - static const char *className; - static const char *parentClassName; - static methodBinding *methods[]; - static constructorBinding *constructorMethod; + static void registerBindings(binding *b); }; #endif // HAVE LUA #endif // _LUA_FUNCTION_H_