Browse Source

Add love.graphics.pop("all"), which pops the entire stack (resolves #1248)

--HG--
branch : minor
Bart van Strien 8 years ago
parent
commit
a2ad1b462f

+ 35 - 12
src/modules/graphics/Graphics.cpp

@@ -1303,25 +1303,30 @@ void Graphics::push(StackType type)
 	stackTypeStack.push_back(type);
 	stackTypeStack.push_back(type);
 }
 }
 
 
-void Graphics::pop()
+void Graphics::pop(PopMode mode)
 {
 {
-	if (stackTypeStack.size() < 1)
-		throw Exception("Minimum stack depth reached (more pops than pushes?)");
+	size_t amount = mode == POP_ALL ? stackTypeStack.size() : 1;
 
 
-	popTransform();
-	pixelScaleStack.pop_back();
+	if (stackTypeStack.size() < amount)
+		throw Exception("Minimum stack depth reached (more pops than pushes?)");
 
 
-	if (stackTypeStack.back() == STACK_ALL)
+	for (size_t i = 0; i < amount; ++i)
 	{
 	{
-		DisplayState &newstate = states[states.size() - 2];
+		popTransform();
+		pixelScaleStack.pop_back();
 
 
-		restoreStateChecked(newstate);
+		if (stackTypeStack.back() == STACK_ALL)
+		{
+			DisplayState &newstate = states[states.size() - 2];
 
 
-		// The last two states in the stack should be equal now.
-		states.pop_back();
+			restoreStateChecked(newstate);
+
+			// The last two states in the stack should be equal now.
+			states.pop_back();
+		}
+
+		stackTypeStack.pop_back();
 	}
 	}
-	
-	stackTypeStack.pop_back();
 }
 }
 
 
 /**
 /**
@@ -1515,6 +1520,16 @@ bool Graphics::getConstant(StackType in, const char *&out)
 	return stackTypes.find(in, out);
 	return stackTypes.find(in, out);
 }
 }
 
 
+bool Graphics::getConstant(const char *in, PopMode &out)
+{
+	return popModes.find(in, out);
+}
+
+bool Graphics::getConstant(PopMode in, const char *&out)
+{
+	return popModes.find(in, out);
+}
+
 StringMap<Graphics::DrawMode, Graphics::DRAW_MAX_ENUM>::Entry Graphics::drawModeEntries[] =
 StringMap<Graphics::DrawMode, Graphics::DRAW_MAX_ENUM>::Entry Graphics::drawModeEntries[] =
 {
 {
 	{ "line", DRAW_LINE },
 	{ "line", DRAW_LINE },
@@ -1608,5 +1623,13 @@ StringMap<Graphics::StackType, Graphics::STACK_MAX_ENUM>::Entry Graphics::stackT
 
 
 StringMap<Graphics::StackType, Graphics::STACK_MAX_ENUM> Graphics::stackTypes(Graphics::stackTypeEntries, sizeof(Graphics::stackTypeEntries));
 StringMap<Graphics::StackType, Graphics::STACK_MAX_ENUM> Graphics::stackTypes(Graphics::stackTypeEntries, sizeof(Graphics::stackTypeEntries));
 
 
+StringMap<Graphics::PopMode, Graphics::POP_MAX_ENUM>::Entry Graphics::popModeEntries[] =
+{
+	{ "one", POP_ONE },
+	{ "all", POP_ALL },
+};
+
+StringMap<Graphics::PopMode, Graphics::POP_MAX_ENUM> Graphics::popModes(Graphics::popModeEntries, sizeof(Graphics::popModeEntries));
+
 } // graphics
 } // graphics
 } // love
 } // love

+ 14 - 1
src/modules/graphics/Graphics.h

@@ -194,6 +194,13 @@ public:
 		STACK_MAX_ENUM
 		STACK_MAX_ENUM
 	};
 	};
 
 
+	enum PopMode
+	{
+		POP_ONE,
+		POP_ALL,
+		POP_MAX_ENUM
+	};
+
 	enum TemporaryRenderTargetFlags
 	enum TemporaryRenderTargetFlags
 	{
 	{
 		TEMPORARY_RT_DEPTH   = (1 << 0),
 		TEMPORARY_RT_DEPTH   = (1 << 0),
@@ -735,7 +742,7 @@ public:
 	Stats getStats() const;
 	Stats getStats() const;
 
 
 	void push(StackType type = STACK_TRANSFORM);
 	void push(StackType type = STACK_TRANSFORM);
-	void pop();
+	void pop(PopMode mode = POP_ONE);
 
 
 	const Matrix4 &getTransform() const;
 	const Matrix4 &getTransform() const;
 	const Matrix4 &getProjection() const;
 	const Matrix4 &getProjection() const;
@@ -798,6 +805,9 @@ public:
 	static bool getConstant(const char *in, StackType &out);
 	static bool getConstant(const char *in, StackType &out);
 	static bool getConstant(StackType in, const char *&out);
 	static bool getConstant(StackType in, const char *&out);
 
 
+	static bool getConstant(const char *in, PopMode &out);
+	static bool getConstant(PopMode in, const char *&out);
+
 	// Default shader code (a shader is always required internally.)
 	// Default shader code (a shader is always required internally.)
 	static Shader::ShaderSource defaultShaderCode[Shader::STANDARD_MAX_ENUM][Shader::LANGUAGE_MAX_ENUM][2];
 	static Shader::ShaderSource defaultShaderCode[Shader::STANDARD_MAX_ENUM][Shader::LANGUAGE_MAX_ENUM][2];
 
 
@@ -946,6 +956,9 @@ private:
 	static StringMap<StackType, STACK_MAX_ENUM>::Entry stackTypeEntries[];
 	static StringMap<StackType, STACK_MAX_ENUM>::Entry stackTypeEntries[];
 	static StringMap<StackType, STACK_MAX_ENUM> stackTypes;
 	static StringMap<StackType, STACK_MAX_ENUM> stackTypes;
 
 
+	static StringMap<PopMode, POP_MAX_ENUM>::Entry popModeEntries[];
+	static StringMap<PopMode, POP_MAX_ENUM> popModes;
+
 }; // Graphics
 }; // Graphics
 
 
 } // graphics
 } // graphics

+ 6 - 1
src/modules/graphics/wrap_Graphics.cpp

@@ -2648,7 +2648,12 @@ int w_push(lua_State *L)
 
 
 int w_pop(lua_State *L)
 int w_pop(lua_State *L)
 {
 {
-	luax_catchexcept(L, [&](){ instance()->pop(); });
+	Graphics::PopMode mode = Graphics::POP_ONE;
+	const char *modestring = lua_isnoneornil(L, 1) ? nullptr : luaL_checkstring(L, 1);
+	if (modestring && !Graphics::getConstant(modestring, mode))
+		return luaL_error(L, "Invalid pop mode: %s", modestring);
+
+	luax_catchexcept(L, [&](){ instance()->pop(mode); });
 	return 0;
 	return 0;
 }
 }