Use lua_for_each more places

This commit is contained in:
Thomas Goyne 2013-05-25 16:31:48 -07:00
parent e84b24e9f3
commit bfa5a8df1e
3 changed files with 28 additions and 28 deletions

View file

@ -802,13 +802,12 @@ namespace Automation4 {
std::set<AssDialogue*> sel;
entryIter it = c->ass->Line.begin();
int last_idx = 1;
lua_pushnil(L);
while (lua_next(L, -2)) {
lua_for_each(L, [&] {
if (lua_isnumber(L, -1)) {
int cur = lua_tointeger(L, -1);
if (cur < 1 || cur > (int)c->ass->Line.size()) {
wxLogError("Selected row %d is out of bounds (must be 1-%u)", cur, c->ass->Line.size());
break;
throw LuaForEachBreak();
}
advance(it, cur - last_idx);
@ -816,7 +815,7 @@ namespace Automation4 {
AssDialogue *diag = dynamic_cast<AssDialogue*>(&*it);
if (!diag) {
wxLogError("Selected row %d is not a dialogue line", cur);
break;
throw LuaForEachBreak();
}
sel.insert(diag);
@ -824,17 +823,17 @@ namespace Automation4 {
if (!active_line || active_idx == cur)
active_line = diag;
}
lua_pop(L, 1);
}
});
AssDialogue *new_active = c->selectionController->GetActiveLine();
if (active_line && (active_idx > 0 || !sel.count(new_active)))
new_active = active_line;
c->selectionController->SetSelectionAndActive(sel, new_active);
}
stackcheck.check_stack(1);
else
lua_pop(L, 1);
stackcheck.check_stack(0);
}
catch (agi::UserCancelException const&) {
subsobj->Cancel();

View file

@ -36,6 +36,7 @@
#include "auto4_lua.h"
#include "auto4_lua_utils.h"
#include "ass_style.h"
#include "colour_button.h"
#include "compat.h"
@ -43,8 +44,6 @@
#include "utils.h"
#include "validators.h"
#include <libaegisub/log.h>
#include <boost/algorithm/string/case_conv.hpp>
#include <boost/range/adaptors.hpp>
#include <boost/range/algorithm.hpp>
@ -65,9 +64,6 @@
#include <wx/valnum.h>
#include <wx/window.h>
// These must be after the headers above.
#include <lua.hpp>
namespace {
inline void get_if_right_type(lua_State *L, std::string &def) {
if (lua_isstring(L, -1))
@ -101,16 +97,6 @@ namespace {
return get_field(L, name, std::string());
}
template<typename Func>
void lua_for_each(lua_State *L, Func&& func) {
lua_pushnil(L); // initial key
while (lua_next(L, -2)) {
func();
lua_pop(L, 1); // pop value, leave key
}
lua_pop(L, 1); // pop key
}
template<class T>
void read_string_array(lua_State *L, T &cont) {
lua_for_each(L, [&] {
@ -438,9 +424,7 @@ namespace Automation4 {
luaL_error(L, "Cannot create config dialog from something non-table");
// Ok, so there is a table with controls
lua_pushvalue(L, 1);
lua_pushnil(L); // initial key
while (lua_next(L, -2)) {
lua_for_each(L, [&] {
if (!lua_istable(L, -1))
luaL_error(L, "bad control table entry");
@ -475,8 +459,7 @@ namespace Automation4 {
luaL_error(L, "bad control table entry");
controls.push_back(ctl);
lua_pop(L, 1);
}
});
if (include_buttons && lua_istable(L, 2)) {
lua_pushvalue(L, 2);

View file

@ -85,6 +85,24 @@ inline std::string get_global_string(lua_State *L, const char *name) {
return ret;
}
struct LuaForEachBreak {};
template<typename Func>
void lua_for_each(lua_State *L, Func&& func) {
lua_pushnil(L); // initial key
while (lua_next(L, -2)) {
try {
func();
}
catch (LuaForEachBreak) {
lua_pop(L, 1);
break;
}
lua_pop(L, 1); // pop value, leave key
}
lua_pop(L, 1); // pop table
}
#ifdef _DEBUG
struct LuaStackcheck {
lua_State *L;