Procházet zdrojové kódy

Add overloaded 'registerUserType' which automatically registers a constructor

Ole před 10 roky
rodič
revize
8d177c29ae
2 změnil soubory, kde provedl 40 přidání a 6 odebrání
  1. 3 6
      examples/usertypes.cpp
  2. 37 0
      lib/luwra/usertypes.hpp

+ 3 - 6
examples/usertypes.cpp

@@ -33,8 +33,10 @@ int main() {
 	// Register our user type.
 	// This function also registers a garbage-collector hook and a string representation function.
 	// Both can be overwritten using the third parameter, which lets you add custom meta methods.
-	luwra::registerUserType<Point>(
+	luwra::registerUserType<Point(double, double)>(
 		state,
+		// Constructor name
+		"Point",
 		// Methods which shall be availabe in the Lua user data, need to be declared here
 		{
 			LUWRA_MEMBER(Point, scale),
@@ -47,11 +49,6 @@ int main() {
 		}
 	);
 
-	// What's left, is registering a constructor for our type.
-	// We have to specify which parameters our constructor takes, because there might be more than
-	// one constructor to deal with.
-	luwra::setGlobal(state, "Point", LUWRA_WRAP_CONSTRUCTOR(Point, double, double));
-
 	// Load Lua code
 	luaL_loadstring(
 		state,

+ 37 - 0
lib/luwra/usertypes.hpp

@@ -12,6 +12,7 @@
 #include "stack.hpp"
 
 #include <map>
+#include <string>
 
 LUWRA_NS_BEGIN
 
@@ -218,6 +219,42 @@ void registerUserType(
 	lua_pop(state, -1);
 }
 
+namespace internal {
+	template <typename T>
+	struct UserTypeSignature {
+		static_assert(
+			sizeof(T) == -1,
+			"Parameter to UserTypeSignature is not a valid signature"
+		);
+	};
+
+	template <typename T, typename... A>
+	struct UserTypeSignature<T(A...)> {
+		using UserType = T;
+
+		static inline
+		void registerConstructor(State* state, const std::string& name) {
+			setGlobal(state, name, &construct_user_type<UserType, A...>);
+		}
+	};
+}
+
+/**
+ * Same as other `registerUserType` but registers the construtor as well. Also template parameter
+ * is a signature `U(A...)` where `U` is the user type and `A...` its constructor parameters.
+ */
+template <typename T> static inline
+void registerUserType(
+	State* state,
+	const std::string& ctor_name,
+	const std::map<const char*, CFunction>& methods = std::map<const char*, CFunction>(),
+	const std::map<const char*, CFunction>& meta_methods = std::map<const char*, CFunction>()
+) {
+	using U = typename internal::UserTypeSignature<T>::UserType;
+	registerUserType<U>(state, methods, meta_methods);
+	internal::UserTypeSignature<T>::registerConstructor(state, ctor_name);
+}
+
 LUWRA_NS_END
 
 /**