Browse Source

Some refactoring in scripting

Panagiotis Christopoulos Charitos 7 years ago
parent
commit
5e6a78bfe3

+ 6 - 1
src/anki/gr/vulkan/GrManagerImpl.cpp

@@ -404,7 +404,12 @@ Error GrManagerImpl::initInstance(const GrManagerInitInfo& init)
 	ANKI_VK_LOGI(
 		"GPU is %s. Vendor identified as %s", m_devProps.deviceName, &GPU_VENDOR_STR[m_capabilities.m_gpuVendor][0]);
 
-	vkGetPhysicalDeviceFeatures(m_physicalDevice, &m_devFeatures);
+	VkPhysicalDeviceFeatures devFeatures = m_devFeatures;
+	devFeatures.robustBufferAccess =
+		(init.m_config->getNumber("window.debugContext") && m_devFeatures.robustBufferAccess) ? true : false;
+	ANKI_VK_LOGI("Robust buffer access is %s", (devFeatures.robustBufferAccess) ? "enabled" : "disabled");
+
+	vkGetPhysicalDeviceFeatures(m_physicalDevice, &devFeatures);
 
 	// Set limits
 	m_capabilities.m_uniformBufferBindOffsetAlignment =

+ 17 - 0
src/anki/math/Vec.h

@@ -2239,6 +2239,23 @@ public:
 		return out;
 	}
 
+	/// Serialize the structure.
+	void serialize(void* data, PtrSize& size) const
+	{
+		size = sizeof(*this);
+		if(data)
+		{
+			memcpy(data, this, sizeof(*this));
+		}
+	}
+
+	/// De-serialize the structure.
+	void deserialize(const void* data)
+	{
+		ANKI_ASSERT(data);
+		memcpy(this, data, sizeof(*this));
+	}
+
 	template<typename TAlloc>
 	String toString(TAlloc alloc) const
 	{

+ 1 - 2
src/anki/renderer/Renderer.cpp

@@ -492,8 +492,7 @@ TexturePtr Renderer::createAndClearRenderTarget(const TextureInitInfo& inf, cons
 
 					cmdb->bindShaderProgram(variant->getProgram());
 
-					Vec4 clearColorUni(&clearVal.m_colorf[0]);
-					cmdb->setPushConstants(&clearColorUni, sizeof(clearColorUni));
+					cmdb->setPushConstants(&clearVal.m_colorf[0], sizeof(clearVal.m_colorf));
 
 					TextureViewPtr view = getGrManager().newTextureView(TextureViewInitInfo(tex, surf));
 					cmdb->bindImage(0, 0, view);

+ 31 - 4
src/anki/script/LuaBinder.cpp

@@ -185,7 +185,7 @@ Error LuaBinder::checkString(lua_State* l, I32 stackIdx, const char*& out)
 	return err;
 }
 
-Error LuaBinder::checkUserData(lua_State* l, I32 stackIdx, const char* typeName, I64 typeSignature, LuaUserData*& out)
+Error LuaBinder::checkUserData(lua_State* l, I32 stackIdx, const LuaUserDataTypeInfo& typeInfo, LuaUserData*& out)
 {
 	Error err = Error::NONE;
 
@@ -193,10 +193,10 @@ Error LuaBinder::checkUserData(lua_State* l, I32 stackIdx, const char* typeName,
 	if(p != nullptr)
 	{
 		out = reinterpret_cast<LuaUserData*>(p);
-		if(out->getSig() == typeSignature)
+		if(out->getSig() == typeInfo.m_signature)
 		{
 			// Check using a LUA method again
-			ANKI_ASSERT(luaL_testudata(l, stackIdx, typeName) != nullptr
+			ANKI_ASSERT(luaL_testudata(l, stackIdx, typeInfo.m_typeName) != nullptr
 						&& "ANKI type check passes but LUA's type check failed");
 		}
 		else
@@ -213,7 +213,7 @@ Error LuaBinder::checkUserData(lua_State* l, I32 stackIdx, const char* typeName,
 
 	if(err)
 	{
-		lua_pushfstring(l, "Userdata of %s expected. Got %s", typeName, luaL_typename(l, stackIdx));
+		lua_pushfstring(l, "Userdata of %s expected. Got %s", typeInfo.m_typeName, luaL_typename(l, stackIdx));
 	}
 
 	return err;
@@ -296,6 +296,33 @@ void LuaBinder::dumpGlobals(lua_State* l, LuaBinderDumpGlobalsCallback& callback
 		case LUA_TSTRING:
 			callback.string(keyString, lua_tostring(l, -1));
 			break;
+		case LUA_TUSERDATA:
+		{
+			LuaUserData* ud = static_cast<LuaUserData*>(lua_touserdata(l, -1));
+			ANKI_ASSERT(ud);
+			LuaUserDataSerializeCallback cb = ud->getDataTypeInfo().m_serializeCallback;
+			if(cb)
+			{
+				Array<U8, 256> buff;
+				PtrSize dumpSize;
+				cb(*ud, nullptr, dumpSize);
+				if(dumpSize <= buff.getSize())
+				{
+					cb(*ud, &buff[0], dumpSize);
+					callback.userData(keyString, ud->getDataTypeInfo(), &buff[0], dumpSize);
+				}
+				else
+				{
+					ANKI_ASSERT(!"TODO");
+				}
+			}
+			else
+			{
+				ANKI_SCRIPT_LOGW("Can't serialize variable %s. No callback provided", keyString.cstr());
+			}
+
+			break;
+		}
 		}
 
 		lua_pop(l, 1);

+ 41 - 16
src/anki/script/LuaBinder.h

@@ -19,9 +19,24 @@
 namespace anki
 {
 
+// Forward
+class LuaUserData;
+
 /// @addtogroup script
 /// @{
 
+/// @memberof LuaUserData
+using LuaUserDataSerializeCallback = void (*)(LuaUserData& self, void* data, PtrSize& size);
+
+/// @memberof LuaUserData
+class LuaUserDataTypeInfo
+{
+public:
+	I64 m_signature;
+	const char* m_typeName;
+	LuaUserDataSerializeCallback m_serializeCallback;
+};
+
 /// LUA userdata.
 class LuaUserData
 {
@@ -34,15 +49,19 @@ public:
 		return m_sig;
 	}
 
-	void initGarbageCollected(I64 sig)
+	void initGarbageCollected(const LuaUserDataTypeInfo* info)
 	{
-		m_sig = sig;
+		ANKI_ASSERT(info);
+		m_sig = info->m_signature;
+		m_info = info;
 		m_addressOrGarbageCollect = GC_MASK;
 	}
 
-	void initPointed(I64 sig, void* ptrToObject)
+	void initPointed(const LuaUserDataTypeInfo* info, void* ptrToObject)
 	{
-		m_sig = sig;
+		ANKI_ASSERT(info);
+		m_sig = info->m_signature;
+		m_info = info;
 		U64 addr = ptrToNumber(ptrToObject);
 		ANKI_ASSERT((addr & GC_MASK) == 0 && "Address too high, cannot encode a flag");
 		m_addressOrGarbageCollect = addr;
@@ -58,6 +77,7 @@ public:
 	T* getData()
 	{
 		ANKI_ASSERT(m_addressOrGarbageCollect != 0);
+		ANKI_ASSERT(getDataTypeInfoFor<T>().m_signature == m_sig);
 		T* out = nullptr;
 		if(isGarbageCollected())
 		{
@@ -84,12 +104,23 @@ public:
 		return getAlignedRoundUp(alignof(T), sizeof(LuaUserData)) + sizeof(T);
 	}
 
+	const LuaUserDataTypeInfo& getDataTypeInfo() const
+	{
+		ANKI_ASSERT(m_info);
+		return *m_info;
+	}
+
+	template<typename TWrapedType>
+	static const LuaUserDataTypeInfo& getDataTypeInfoFor();
+
 private:
 	static constexpr U64 GC_MASK = U64(1) << U64(63);
 
 	I64 m_sig = 0; ///< Signature to identify the user data.
 
 	U64 m_addressOrGarbageCollect = 0; ///< Encodes an address or a flag if it's for garbage collection.
+
+	const LuaUserDataTypeInfo* m_info = nullptr;
 };
 
 /// An instance of the original lua state with its own state.
@@ -135,7 +166,7 @@ public:
 
 	virtual void string(CString name, CString value) = 0;
 
-	// virtual void userData(CString name, ) = 0;
+	virtual void userData(CString name, const LuaUserDataTypeInfo& typeInfo, const void* value, PtrSize valueSize) = 0;
 };
 
 /// Lua binder class. A wrapper on top of LUA
@@ -168,8 +199,8 @@ public:
 	{
 		void* ptr = lua_newuserdata(state, sizeof(LuaUserData));
 		LuaUserData* ud = static_cast<LuaUserData*>(ptr);
-		ud->initPointed(getWrappedTypeSignature<T>(), y);
-		luaL_setmetatable(state, getWrappedTypeName<T>());
+		ud->initPointed(&LuaUserData::getDataTypeInfoFor<T>(), y);
+		luaL_setmetatable(state, LuaUserData::getDataTypeInfoFor<T>().m_typeName);
 		lua_setglobal(state, name.cstr());
 	}
 
@@ -178,8 +209,8 @@ public:
 	{
 		void* ptr = lua_newuserdata(state, sizeof(LuaUserData));
 		LuaUserData* ud = static_cast<LuaUserData*>(ptr);
-		ud->initPointed(getWrappedTypeSignature<T>(), y);
-		luaL_setmetatable(state, getWrappedTypeName<T>());
+		ud->initPointed(&LuaUserData::getDataTypeInfoFor<T>(), y);
+		luaL_setmetatable(state, LuaUserData::getDataTypeInfoFor<T>().m_typeName);
 	}
 
 	/// Evaluate a string
@@ -237,7 +268,7 @@ public:
 	/// The function uses the type signature to validate the type and not the
 	/// typeName. That is supposed to be faster.
 	static ANKI_USE_RESULT Error checkUserData(
-		lua_State* l, I32 stackIdx, const char* typeName, I64 typeSignature, LuaUserData*& out);
+		lua_State* l, I32 stackIdx, const LuaUserDataTypeInfo& typeInfo, LuaUserData*& out);
 
 	/// Allocate memory.
 	static void* luaAlloc(lua_State* l, size_t size, U32 alignment);
@@ -245,12 +276,6 @@ public:
 	/// Free memory.
 	static void luaFree(lua_State* l, void* ptr);
 
-	template<typename TWrapedType>
-	static I64 getWrappedTypeSignature();
-
-	template<typename TWrapedType>
-	static const char* getWrappedTypeName();
-
 private:
 	ScriptAllocator m_alloc;
 	lua_State* m_l = nullptr;

File diff suppressed because it is too large
+ 163 - 123
src/anki/script/Math.cpp


+ 3 - 3
src/anki/script/Math.xml

@@ -12,7 +12,7 @@
 namespace anki {]]></head>
 
 	<classes>
-		<class name="Vec2">
+		<class name="Vec2" serialize="true">
 			<constructor>
 				<args>
 					<arg>F32</arg>
@@ -111,7 +111,7 @@ namespace anki {]]></head>
 				</method>
 			</methods>
 		</class>
-		<class name="Vec3">
+		<class name="Vec3" serialize="true">
 			<constructor>
 				<args>
 					<arg>F32</arg>
@@ -223,7 +223,7 @@ namespace anki {]]></head>
 
 			</methods>
 		</class>
-		<class name="Vec4">
+		<class name="Vec4" serialize="true">
 			<constructor>
 				<args>
 					<arg>F32</arg>

+ 15 - 24
src/anki/script/Renderer.cpp

@@ -22,18 +22,13 @@ static MainRenderer* getMainRenderer(lua_State* l)
 	return &scriptManager->getMainRenderer();
 }
 
-static const char* classnameDbg = "Dbg";
+// Type info for Dbg
+LuaUserDataTypeInfo luaUserDataTypeInfoDbg = {-2784798555522127122, "Dbg", nullptr};
 
 template<>
-I64 LuaBinder::getWrappedTypeSignature<Dbg>()
+const LuaUserDataTypeInfo& LuaUserData::getDataTypeInfoFor<Dbg>()
 {
-	return -2784798555522127122;
-}
-
-template<>
-const char* LuaBinder::getWrappedTypeName<Dbg>()
-{
-	return classnameDbg;
+	return luaUserDataTypeInfoDbg;
 }
 
 /// Pre-wrap method Dbg::getEnabled.
@@ -49,7 +44,7 @@ static inline int pwrapDbggetEnabled(lua_State* l)
 	LuaBinder::checkArgsCount(l, 1);
 
 	// Get "this" as "self"
-	if(LuaBinder::checkUserData(l, 1, classnameDbg, -2784798555522127122, ud))
+	if(LuaBinder::checkUserData(l, 1, luaUserDataTypeInfoDbg, ud))
 	{
 		return -1;
 	}
@@ -91,7 +86,7 @@ static inline int pwrapDbgsetEnabled(lua_State* l)
 	LuaBinder::checkArgsCount(l, 2);
 
 	// Get "this" as "self"
-	if(LuaBinder::checkUserData(l, 1, classnameDbg, -2784798555522127122, ud))
+	if(LuaBinder::checkUserData(l, 1, luaUserDataTypeInfoDbg, ud))
 	{
 		return -1;
 	}
@@ -127,24 +122,19 @@ static int wrapDbgsetEnabled(lua_State* l)
 /// Wrap class Dbg.
 static inline void wrapDbg(lua_State* l)
 {
-	LuaBinder::createClass(l, classnameDbg);
+	LuaBinder::createClass(l, luaUserDataTypeInfoDbg.m_typeName);
 	LuaBinder::pushLuaCFuncMethod(l, "getEnabled", wrapDbggetEnabled);
 	LuaBinder::pushLuaCFuncMethod(l, "setEnabled", wrapDbgsetEnabled);
 	lua_settop(l, 0);
 }
 
-static const char* classnameMainRenderer = "MainRenderer";
-
-template<>
-I64 LuaBinder::getWrappedTypeSignature<MainRenderer>()
-{
-	return 919289102518575326;
-}
+// Type info for MainRenderer
+LuaUserDataTypeInfo luaUserDataTypeInfoMainRenderer = {919289102518575326, "MainRenderer", nullptr};
 
 template<>
-const char* LuaBinder::getWrappedTypeName<MainRenderer>()
+const LuaUserDataTypeInfo& LuaUserData::getDataTypeInfoFor<MainRenderer>()
 {
-	return classnameMainRenderer;
+	return luaUserDataTypeInfoMainRenderer;
 }
 
 /// Pre-wrap method MainRenderer::getAspectRatio.
@@ -160,7 +150,7 @@ static inline int pwrapMainRenderergetAspectRatio(lua_State* l)
 	LuaBinder::checkArgsCount(l, 1);
 
 	// Get "this" as "self"
-	if(LuaBinder::checkUserData(l, 1, classnameMainRenderer, 919289102518575326, ud))
+	if(LuaBinder::checkUserData(l, 1, luaUserDataTypeInfoMainRenderer, ud))
 	{
 		return -1;
 	}
@@ -192,7 +182,7 @@ static int wrapMainRenderergetAspectRatio(lua_State* l)
 /// Wrap class MainRenderer.
 static inline void wrapMainRenderer(lua_State* l)
 {
-	LuaBinder::createClass(l, classnameMainRenderer);
+	LuaBinder::createClass(l, luaUserDataTypeInfoMainRenderer.m_typeName);
 	LuaBinder::pushLuaCFuncMethod(l, "getAspectRatio", wrapMainRenderergetAspectRatio);
 	lua_settop(l, 0);
 }
@@ -222,7 +212,8 @@ static inline int pwrapgetMainRenderer(lua_State* l)
 	voidp = lua_newuserdata(l, sizeof(LuaUserData));
 	ud = static_cast<LuaUserData*>(voidp);
 	luaL_setmetatable(l, "MainRenderer");
-	ud->initPointed(919289102518575326, const_cast<MainRenderer*>(ret));
+	extern LuaUserDataTypeInfo luaUserDataTypeInfoMainRenderer;
+	ud->initPointed(&luaUserDataTypeInfoMainRenderer, const_cast<MainRenderer*>(ret));
 
 	return 1;
 }

File diff suppressed because it is too large
+ 153 - 195
src/anki/script/Scene.cpp


+ 43 - 23
src/anki/script/lua_glue_gen.py

@@ -18,7 +18,7 @@ def parse_commandline():
 
 	parser = optparse.OptionParser(usage = "usage: %prog [options]", description = "Create LUA bindings using XML")
 
-	parser.add_option("-i", "--input", dest = "inp", type = "string", 
+	parser.add_option("-i", "--input", dest = "inp", type = "string",
 		help = "specify the XML files to parse. Seperate with :")
 
 	(options, args) = parser.parse_args()
@@ -134,17 +134,19 @@ def ret(ret_el):
 			wglue("ud = static_cast<LuaUserData*>(voidp);")
 			wglue("luaL_setmetatable(l, \"%s\");" % type)
 
+			wglue("extern LuaUserDataTypeInfo luaUserDataTypeInfo%s;" % type)
 			if is_ptr:
-				wglue("ud->initPointed(%d, const_cast<%s*>(ret));" % (type_sig(type), type))
+				wglue("ud->initPointed(&luaUserDataTypeInfo%s, const_cast<%s*>(ret));" % (type, type))
 			elif is_ref:
-				wglue("ud->initPointed(%d, const_cast<%s*>(&ret));" % (type_sig(type), type))
+				wglue("ud->initPointed(&luaUserDataTypeInfo%s, const_cast<%s*>(&ret));" % (type, type))
 		else:
 			wglue("size = LuaUserData::computeSizeForGarbageCollected<%s>();" % type)
 			wglue("voidp = lua_newuserdata(l, size);")
 			wglue("luaL_setmetatable(l, \"%s\");" % type)
 
 			wglue("ud = static_cast<LuaUserData*>(voidp);")
-			wglue("ud->initGarbageCollected(%d);" % type_sig(type))
+			wglue("extern LuaUserDataTypeInfo luaUserDataTypeInfo%s;" % type)
+			wglue("ud->initGarbageCollected(&luaUserDataTypeInfo%s);" % type)
 
 			wglue("::new(ud->getData<%s>()) %s(std::move(ret));" % (type, type))
 
@@ -173,7 +175,8 @@ def arg(arg_txt, stack_index, index):
 		ident(-1)
 		wglue("}")
 	else:
-		wglue("if(LuaBinder::checkUserData(l, %d, \"%s\", %d, ud))" % (stack_index, type, type_sig(type)))
+		wglue("extern LuaUserDataTypeInfo luaUserDataTypeInfo%s;" % type)
+		wglue("if(LuaBinder::checkUserData(l, %d, luaUserDataTypeInfo%s, ud))" % (stack_index, type))
 		wglue("{")
 		ident(1)
 		wglue("return -1;")
@@ -286,7 +289,7 @@ def method(class_name, meth_el):
 
 	# Get this pointer
 	wglue("// Get \"this\" as \"self\"")
-	wglue("if(LuaBinder::checkUserData(l, 1, classname%s, %d, ud))" % (class_name, type_sig(class_name)))
+	wglue("if(LuaBinder::checkUserData(l, 1, luaUserDataTypeInfo%s, ud))" % class_name)
 	wglue("{")
 	ident(1)
 	wglue("return -1;")
@@ -419,9 +422,10 @@ def constructor(constr_el, class_name):
 
 	wglue("size = LuaUserData::computeSizeForGarbageCollected<%s>();" % class_name)
 	wglue("voidp = lua_newuserdata(l, size);")
-	wglue("luaL_setmetatable(l, classname%s);" % class_name)
+	wglue("luaL_setmetatable(l, luaUserDataTypeInfo%s.m_typeName);" % class_name)
 	wglue("ud = static_cast<LuaUserData*>(voidp);")
-	wglue("ud->initGarbageCollected(%d);" % type_sig(class_name))
+	wglue("extern LuaUserDataTypeInfo luaUserDataTypeInfo%s;" % class_name)
+	wglue("ud->initGarbageCollected(&luaUserDataTypeInfo%s);" % class_name)
 	wglue("::new(ud->getData<%s>()) %s(%s);" % (class_name, class_name, args_str))
 	wglue("")
 
@@ -460,7 +464,7 @@ def destructor(class_name):
 	write_local_vars();
 
 	wglue("LuaBinder::checkArgsCount(l, 1);")
-	wglue("if(LuaBinder::checkUserData(l, 1, classname%s, %d, ud))" % (class_name, type_sig(class_name)))
+	wglue("if(LuaBinder::checkUserData(l, 1, luaUserDataTypeInfo%s, ud))" % class_name)
 	wglue("{")
 	ident(1)
 	wglue("return -1;")
@@ -488,22 +492,37 @@ def class_(class_el):
 
 	class_name = class_el.get("name")
 
-	# Write class decoration and stuff
-	wglue("static const char* classname%s = \"%s\";" % (class_name, class_name))
-	wglue("")
-	wglue("template<>")
-	wglue("I64 LuaBinder::getWrappedTypeSignature<%s>()" % class_name)
-	wglue("{")
+	wglue("// Type info for %s" % class_name)
+
+	# Write serializer
+	serialize = class_el.get("serialize") is not None and class_el.get("serialize") == "true"
+	if serialize:
+		serialize_cb_name = "serialize%s" % class_name
+		wglue("static void %s(LuaUserData& self, void* data, PtrSize& size)" % (serialize_cb_name))
+		wglue("{")
+		ident(1)
+		wglue("%s* obj = self.getData<%s>();" % (class_name, class_name))
+		wglue("obj->serialize(data, size);")
+		ident(-1)
+		wglue("}")
+		wglue("")
+	else:
+		serialize_cb_name = "nullptr"
+
+	# Write the type info
+	wglue("LuaUserDataTypeInfo luaUserDataTypeInfo%s = {" % class_name)
 	ident(1)
-	wglue("return %d;" % type_sig(class_name))
+	wglue("%d, \"%s\", %s" % (type_sig(class_name), class_name, serialize_cb_name))
 	ident(-1)
-	wglue("}")
+	wglue("};")
 	wglue("")
+
+	# Specialize the getDataTypeInfoFor
 	wglue("template<>")
-	wglue("const char* LuaBinder::getWrappedTypeName<%s>()" % class_name)
+	wglue("const LuaUserDataTypeInfo& LuaUserData::getDataTypeInfoFor<%s>()" % class_name)
 	wglue("{")
 	ident(1)
-	wglue("return classname%s;" % class_name)
+	wglue("return luaUserDataTypeInfo%s;" % class_name)
 	ident(-1)
 	wglue("}")
 	wglue("")
@@ -541,11 +560,12 @@ def class_(class_el):
 	wglue("static inline void wrap%s(lua_State* l)" % class_name)
 	wglue("{")
 	ident(1)
-	wglue("LuaBinder::createClass(l, classname%s);" % class_name)
+	wglue("LuaBinder::createClass(l, luaUserDataTypeInfo%s.m_typeName);" % class_name)
 
 	# Register constructor
 	if has_constructor:
-		wglue("LuaBinder::pushLuaCFuncStaticMethod(l, classname%s, \"new\", wrap%sCtor);" % (class_name, class_name))
+		wglue("LuaBinder::pushLuaCFuncStaticMethod(l, luaUserDataTypeInfo%s.m_typeName, \"new\", wrap%sCtor);"
+				% (class_name, class_name))
 
 	# Register destructor
 	if has_constructor:
@@ -557,8 +577,8 @@ def class_(class_el):
 			meth_alias = meth_name_alias[1]
 			is_static = meth_name_alias[2]
 			if is_static:
-				wglue("LuaBinder::pushLuaCFuncStaticMethod(l, classname%s, \"%s\", wrap%s%s);" \
-					% (class_name, meth_alias, class_name, meth_alias))
+				wglue("LuaBinder::pushLuaCFuncStaticMethod(l, luaUserDataTypeInfo%s.m_typeName, \"%s\", wrap%s%s);"
+						% (class_name, meth_alias, class_name, meth_alias))
 			else:
 				wglue("LuaBinder::pushLuaCFuncMethod(l, \"%s\", wrap%s%s);" % (meth_alias, class_name, meth_alias))
 

+ 12 - 1
tests/script/LuaBinder.cpp

@@ -49,7 +49,7 @@ ANKI_TEST(Script, LuaBinderThreads)
 
 	static const char* script = R"(
 vec = Vec4.new(0, 0, 0, 0)
-	
+
 function myFunc()
 	vec:setX(vec:getX() + 1)
 	logi(string.format("The number is %f", vec:getX()))
@@ -77,6 +77,7 @@ ANKI_TEST(Script, LuaBinderThreadsDump)
 	static const char* script = R"(
 num = 123.4
 str = "lala"
+vec = Vec3.new(1, 2, 3)
 )";
 
 	ANKI_TEST_EXPECT_NO_ERR(env->evalString(script));
@@ -93,6 +94,16 @@ str = "lala"
 		{
 			printf("%s = %s\n", name.cstr(), value.cstr());
 		}
+
+		void userData(CString name, const LuaUserDataTypeInfo& typeInfo, const void* value, PtrSize valueSize)
+		{
+			if(LuaUserData::getDataTypeInfoFor<Vec3>().m_signature == typeInfo.m_signature)
+			{
+				Vec3 v;
+				v.deserialize(value);
+				printf("%s = %f %f %f\n", name.cstr(), v.x(), v.y(), v.z());
+			}
+		}
 	} callback;
 
 	env->dumpGlobals(callback);

Some files were not shown because too many files changed in this diff