diff --git a/include/osgDB/Serializer b/include/osgDB/Serializer index f0b050904..663b92ecb 100644 --- a/include/osgDB/Serializer +++ b/include/osgDB/Serializer @@ -1127,6 +1127,44 @@ public: unsigned int _numElementsOnRow; }; +class MapIteratorObject : public osg::Object +{ +public: + MapIteratorObject(): + _keyType(BaseSerializer::RW_UNDEFINED), _keySize(0), + _elementType(BaseSerializer::RW_UNDEFINED),_elementSize(0) {} + + MapIteratorObject(BaseSerializer::Type keyType, unsigned int keySize, BaseSerializer::Type elementType, unsigned int elementSize): + _keyType(keyType), _keySize(keySize), + _elementType(elementType),_elementSize(elementSize) {} + + MapIteratorObject(const MapIteratorObject& rhs, const osg::CopyOp copyop=osg::CopyOp::SHALLOW_COPY): + osg::Object(rhs, copyop), + _keyType(rhs._keyType), _keySize(rhs._keySize), + _elementType(rhs._elementType),_elementSize(rhs._elementSize) {} + + META_Object(osgDB, MapIteratorObject); + + BaseSerializer::Type getKeyType() const { return _keyType; } + unsigned int getKeySize() const { return _keySize; } + + BaseSerializer::Type getElementType() const { return _elementType; } + unsigned int getElementSize() const { return _elementSize; } + + virtual bool advance() { return false; } + virtual bool valid() const { return false; } + virtual const void* getKey() const { return 0; } + virtual void* getElement() const { return 0; } + virtual void setElement(void* ptr) const {} + +protected: + BaseSerializer::Type _keyType; + unsigned int _keySize; + + BaseSerializer::Type _elementType; + unsigned int _elementSize; +}; + class MapBaseSerializer : public BaseSerializer { public: @@ -1147,6 +1185,8 @@ public: virtual const void* getElement(const osg::Object& obj, void* ptrKey) const { return 0; } virtual unsigned int size(const osg::Object& obj) const { return 0; } + virtual MapIteratorObject* createIterator(osg::Object& obj) const { return 0; } + protected: Type _keyType; unsigned int _keySize; @@ -1163,6 +1203,7 @@ public: typedef typename P::value_type ValueType; typedef typename P::key_type KeyType; typedef typename P::mapped_type ElementType; + typedef typename P::iterator Iterator; typedef typename P::const_iterator ConstIterator; typedef P& (C::*Getter)(); typedef const P& (C::*ConstGetter)() const; @@ -1212,6 +1253,30 @@ public: return map.size(); } + struct MapIterator : public MapIteratorObject + { + MapIterator(BaseSerializer::Type keyType, unsigned int keySize, BaseSerializer::Type elementType, unsigned int elementSize, + Iterator itr, Iterator endItr): + MapIteratorObject(keyType, keySize, elementType, elementSize), + _itr(itr),_endItr(endItr) {} + + Iterator _itr; + Iterator _endItr; + + virtual bool advance() { if (valid()) ++_itr; return valid(); } + virtual bool valid() const { return _itr!=_endItr; } + virtual const void* getKey() const { return valid() ? &(_itr->first) : 0; } + virtual void* getElement() const { return valid() ? &(_itr->second) : 0; } + virtual void setElement(void* ptr) const { if (valid()) _itr->second = *reinterpret_cast(ptr); } + }; + + virtual MapIteratorObject* createIterator(osg::Object& obj) const + { + C& object = OBJECT_CAST(obj); + P& map = (object.*_getter)(); + return new MapIterator(_keyType, _keySize, _elementType, _elementSize, map.begin(), map.end()); + } + virtual bool read( InputStream& is, osg::Object& obj ) { C& object = OBJECT_CAST(obj); diff --git a/src/osgPlugins/lua/LuaScriptEngine.cpp b/src/osgPlugins/lua/LuaScriptEngine.cpp index 3fa1409e3..b5a788a85 100644 --- a/src/osgPlugins/lua/LuaScriptEngine.cpp +++ b/src/osgPlugins/lua/LuaScriptEngine.cpp @@ -362,7 +362,7 @@ static int getMapProperty(lua_State * _lua) return 1; } - return 0; + return 0; } } } @@ -469,6 +469,135 @@ static int getMapSize(lua_State* _lua) return 0; } + +static int createMapIterator(lua_State* _lua) +{ + const LuaScriptEngine* lse = reinterpret_cast(lua_topointer(_lua, lua_upvalueindex(1))); + int n = lua_gettop(_lua); /* number of arguments */ + if (n<1 || lua_type(_lua, 1)!=LUA_TTABLE) return 0; + + osg::Object* object = lse->getObjectFromTable(1); + std::string containerPropertyName = lse->getStringFromTable(1,"containerPropertyName"); + + // check to see if Object "is a" vector + osgDB::BaseSerializer::Type type; + osgDB::BaseSerializer* bs = lse->getPropertyInterface().getSerializer(object, containerPropertyName, type); + osgDB::MapBaseSerializer* ms = dynamic_cast(bs); + if (ms) + { + lse->pushObject(ms->createIterator(*object)); + return 1; + } + + return 0; +} + +////////////////////////////////////////////////////////////////////////////////////// +// +// MapIteratorObject support +// +static int callMapIteratorAdvance(lua_State* _lua) +{ + const LuaScriptEngine* lse = reinterpret_cast(lua_topointer(_lua, lua_upvalueindex(1))); + if (lua_gettop(_lua)<1 || lua_type(_lua, 1)!=LUA_TTABLE) return 0; + osgDB::MapIteratorObject* mio = lse->getObjectFromTable(1); + if (mio) + { + lua_pushboolean(lse->getLuaState(), mio->advance()); + return 1; + } + + return 0; +} + +static int callMapIteratorValid(lua_State* _lua) +{ + const LuaScriptEngine* lse = reinterpret_cast(lua_topointer(_lua, lua_upvalueindex(1))); + if (lua_gettop(_lua)<1 || lua_type(_lua, 1)!=LUA_TTABLE) return 0; + osgDB::MapIteratorObject* mio = lse->getObjectFromTable(1); + if (mio) + { + lua_pushboolean(lse->getLuaState(), mio->valid()); + return 1; + } + + return 0; +} + +static int getMapIteratorKey(lua_State* _lua) +{ + const LuaScriptEngine* lse = reinterpret_cast(lua_topointer(_lua, lua_upvalueindex(1))); + if (lua_gettop(_lua)<1 || lua_type(_lua, 1)!=LUA_TTABLE) return 0; + osgDB::MapIteratorObject* mio = lse->getObjectFromTable(1); + if (mio) + { + const void* dataPtr = mio->getKey(); + if (dataPtr) + { + SerializerScratchPad valuesp(mio->getKeyType(), dataPtr, mio->getKeySize()); + return lse->pushDataToStack(&valuesp); + } + else + { + lua_pushnil(_lua); + return 1; + } + } + + return 0; +} + +static int getMapIteratorElement(lua_State* _lua) +{ + const LuaScriptEngine* lse = reinterpret_cast(lua_topointer(_lua, lua_upvalueindex(1))); + if (lua_gettop(_lua)<1 || lua_type(_lua, 1)!=LUA_TTABLE) return 0; + osgDB::MapIteratorObject* mio = lse->getObjectFromTable(1); + if (mio) + { + const void* dataPtr = mio->getElement(); + if (dataPtr) + { + SerializerScratchPad valuesp(mio->getElementType(), dataPtr, mio->getElementSize()); + return lse->pushDataToStack(&valuesp); + } + else + { + lua_pushnil(_lua); + return 1; + } + } + OSG_NOTICE<<"getMapIteratorElement failed. "<(lua_topointer(_lua, lua_upvalueindex(1))); + if (lua_gettop(_lua)<2 || lua_type(_lua, 1)!=LUA_TTABLE) return 0; + osgDB::MapIteratorObject* mio = lse->getObjectFromTable(1); + if (mio) + { + SerializerScratchPad valuesp; + lse->getDataFromStack(&valuesp, mio->getElementType(), 2); + + if (mio->getElementType()==valuesp.dataType) + { + OSG_NOTICE<<"Assigning element "<setElement(valuesp.data); + return 0; + } + else + { + OSG_NOTICE<<"Warning: Lua setMapIteratorElement() : Failed to matched map element type, valuesp.dataType="<(lsg)->getLuaState(); } + PushStackValueVisitor(const LuaScriptEngine* lse) : _lse(lse) { _lua = const_cast(lse)->getLuaState(); } virtual void apply(bool value) { lua_pushboolean(_lua, value ? 0 : 1); } virtual void apply(char value) { lua_pushnumber(_lua, value); } @@ -861,16 +990,16 @@ public: virtual void apply(float value) { lua_pushnumber(_lua, value); } virtual void apply(double value) { lua_pushnumber(_lua, value); } virtual void apply(const std::string& value) { lua_pushlstring(_lua, &value[0], value.size()); } - virtual void apply(const osg::Vec2f& value) { _lsg->pushValue(value); } - virtual void apply(const osg::Vec3f& value) { _lsg->pushValue(value); } - virtual void apply(const osg::Vec4f& value) { _lsg->pushValue(value); } - virtual void apply(const osg::Vec2d& value) { _lsg->pushValue(value); } - virtual void apply(const osg::Vec3d& value) { _lsg->pushValue(value); } - virtual void apply(const osg::Vec4d& value) { _lsg->pushValue(value); } - virtual void apply(const osg::Quat& value) { _lsg->pushValue(value); } - virtual void apply(const osg::Plane& value) { _lsg->pushValue(value); } - virtual void apply(const osg::Matrixf& value) { _lsg->pushValue(value); } - virtual void apply(const osg::Matrixd& value) { _lsg->pushValue(value); } + virtual void apply(const osg::Vec2f& value) { _lse->pushValue(value); } + virtual void apply(const osg::Vec3f& value) { _lse->pushValue(value); } + virtual void apply(const osg::Vec4f& value) { _lse->pushValue(value); } + virtual void apply(const osg::Vec2d& value) { _lse->pushValue(value); } + virtual void apply(const osg::Vec3d& value) { _lse->pushValue(value); } + virtual void apply(const osg::Vec4d& value) { _lse->pushValue(value); } + virtual void apply(const osg::Quat& value) { _lse->pushValue(value); } + virtual void apply(const osg::Plane& value) { _lse->pushValue(value); } + virtual void apply(const osg::Matrixf& value) { _lse->pushValue(value); } + virtual void apply(const osg::Matrixd& value) { _lse->pushValue(value); } }; #if LUA_VERSION_NUM<=501 @@ -881,12 +1010,12 @@ class GetStackValueVisitor : public osg::ValueObject::SetValueVisitor { public: - const LuaScriptEngine* _lsg; + const LuaScriptEngine* _lse; lua_State* _lua; int _index; int _numberToPop; - GetStackValueVisitor(const LuaScriptEngine* lsg, int index) : _lsg(lsg), _lua(0), _index(index), _numberToPop(0) { _lua = const_cast(lsg)->getLuaState(); } + GetStackValueVisitor(const LuaScriptEngine* lse, int index) : _lse(lse), _lua(0), _index(index), _numberToPop(0) { _lua = const_cast(lse )->getLuaState(); } virtual void apply(bool& value) { if (lua_isboolean(_lua, _index)) { value = (lua_toboolean(_lua, _index)!=0); _numberToPop = 1; } } @@ -899,20 +1028,20 @@ public: virtual void apply(float& value) { if (lua_isnumber(_lua, _index)) { value = lua_tonumber(_lua, _index)!=0; _numberToPop = 1; } } virtual void apply(double& value) { if (lua_isnumber(_lua, _index)) { value = lua_tonumber(_lua, _index)!=0; _numberToPop = 1; } } virtual void apply(std::string& value) { if (lua_isstring(_lua, _index)) { value = std::string(lua_tostring(_lua, _index), lua_rawlen(_lua, _index)); _numberToPop = 1; } } - virtual void apply(osg::Vec2f& value) { _lsg->getValue(_index, value); _numberToPop = 2;} - virtual void apply(osg::Vec3f& value) { _lsg->getValue(_index, value); _numberToPop = 2; } - virtual void apply(osg::Vec4f& value) { _lsg->getValue(_index, value); _numberToPop = 4; } - virtual void apply(osg::Vec2d& value) { _lsg->getValue(_index, value); _numberToPop = 2; } - virtual void apply(osg::Vec3d& value) { _lsg->getValue(_index, value); _numberToPop = 3; } - virtual void apply(osg::Vec4d& value) { _lsg->getValue(_index, value); _numberToPop = 4; } - virtual void apply(osg::Quat& value) { _lsg->getValue(_index, value); _numberToPop = 4; } - virtual void apply(osg::Plane& value) { _lsg->getValue(_index, value); _numberToPop = 4; } - virtual void apply(osg::Matrixf& value) { _lsg->getValue(_index, value); } - virtual void apply(osg::Matrixd& value) { _lsg->getValue(_index, value); } - virtual void apply(osg::BoundingBoxf& value) { _lsg->getValue(_index, value); } - virtual void apply(osg::BoundingBoxd& value) { _lsg->getValue(_index, value); } - virtual void apply(osg::BoundingSpheref& value) { _lsg->getValue(_index, value); } - virtual void apply(osg::BoundingSphered& value) { _lsg->getValue(_index, value); } + virtual void apply(osg::Vec2f& value) { _lse->getValue(_index, value); _numberToPop = 2;} + virtual void apply(osg::Vec3f& value) { _lse->getValue(_index, value); _numberToPop = 2; } + virtual void apply(osg::Vec4f& value) { _lse->getValue(_index, value); _numberToPop = 4; } + virtual void apply(osg::Vec2d& value) { _lse->getValue(_index, value); _numberToPop = 2; } + virtual void apply(osg::Vec3d& value) { _lse->getValue(_index, value); _numberToPop = 3; } + virtual void apply(osg::Vec4d& value) { _lse->getValue(_index, value); _numberToPop = 4; } + virtual void apply(osg::Quat& value) { _lse->getValue(_index, value); _numberToPop = 4; } + virtual void apply(osg::Plane& value) { _lse->getValue(_index, value); _numberToPop = 4; } + virtual void apply(osg::Matrixf& value) { _lse->getValue(_index, value); } + virtual void apply(osg::Matrixd& value) { _lse->getValue(_index, value); } + virtual void apply(osg::BoundingBoxf& value) { _lse->getValue(_index, value); } + virtual void apply(osg::BoundingBoxd& value) { _lse->getValue(_index, value); } + virtual void apply(osg::BoundingSpheref& value) { _lse->getValue(_index, value); } + virtual void apply(osg::BoundingSphered& value) { _lse->getValue(_index, value); } }; int LuaScriptEngine::pushPropertyToStack(osg::Object* object, const std::string& propertyName) const @@ -2338,7 +2467,7 @@ bool LuaScriptEngine::getvec4(int pos) const int abs_pos = getAbsolutePos(pos); if (lua_istable(_lua, abs_pos)) { - if (getfields(abs_pos, "x", "y", "z", LUA_TNUMBER) || + if (getfields(abs_pos, "x", "y", "z", "w", LUA_TNUMBER) || getfields(abs_pos, "r", "g", "b", "a", LUA_TNUMBER) || getfields(abs_pos, "red", "green", "blue", "alpha", LUA_TNUMBER) || getfields(abs_pos, "s", "t", "r", "q", LUA_TNUMBER) || @@ -2905,9 +3034,9 @@ void LuaScriptEngine::pushContainer(osg::Object* object, const std::string& prop } else if (ms) { - OSG_NOTICE<<"Need to set up map object"<(object)!=0) + { + assignClosure("advance", callMapIteratorAdvance); + assignClosure("valid", callMapIteratorValid); + assignClosure("getKey", getMapIteratorKey); + assignClosure("getElement", getMapIteratorElement); + assignClosure("setElement", setMapIteratorElement); + } else { luaL_getmetatable(_lua, "LuaScriptEngine.Object");