The Battle for Wesnoth  1.15.0-dev
aspect_advancements.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2013 - 2018 by Felix Bauer <fehlxb+wesnoth@gmail.com>
3  Part of the Battle for Wesnoth Project http://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
16 
17 #include "log.hpp" // for LOG_STREAM, logger, etc
18 #include "lua/lauxlib.h" // for luaL_ref, LUA_REFNIL
19 #include "lua/lua.h" // for lua_isstring, etc
20 #include "map/location.hpp" // for map_location
21 #include "serialization/string_utils.hpp" // for split
22 #include "units/map.hpp" // for unit_map::const_iterator, etc
23 #include "units/unit.hpp"
24 
25 #include <ostream> // for operator<<, basic_ostream, etc
26 #include <string> // for string, char_traits, etc
27 #include <vector> // for vector
28 
29 struct lua_State;
30 
31 static lg::log_domain log_ai_engine_lua("ai/engine/lua");
32 #define LOG_LUA LOG_STREAM(info, log_ai_engine_lua)
33 #define ERR_LUA LOG_STREAM(err, log_ai_engine_lua)
34 
35 namespace ai
36 {
38  : val_()
39  , L_()
40  , ref_()
41 {
42 }
43 
45  : val_("Lua Function")
46  , L_(L)
47  , ref_()
48 {
49  lua_settop(L, n);
50 
51  // on the top of the Lua-Stack is now the pointer to the function. Save it:
53 }
54 
56  : val_(val)
57  , L_()
58  , ref_()
59 {
60 }
61 
63 {
64  if(L_) {
65  // Remove the function from the registry
67  }
68 }
69 
70 const std::vector<std::string> unit_advancements_aspect::get_advancements(const unit_map::const_iterator& unit) const
71 {
72  if(!unit.valid()) {
73  return std::vector<std::string>();
74  }
75 
76  const std::string& unit_id = (*unit).id();
77  const int unit_x = (*unit).get_location().wml_x();
78  const int unit_y = (*unit).get_location().wml_y();
79 
80  LOG_LUA << "Entering unit_advancements_aspect::get_advancements() in instance " << this << " with unit " << unit_id
81  << " on (x,y) = (" << unit_x << ", " << unit_y << ")\n";
82 
83  if(L_ == nullptr || ref_ == LUA_REFNIL) {
84  // If we end up here, most likely the aspect don't use the lua-engine.
85  // Just to make sure:
86  if(val_ == "Lua Function") {
87  return std::vector<std::string>();
88  }
89 
90  return utils::split(val_);
91  }
92 
93  // put the Pointer back on the Stack
95 
96  if(lua_isstring(L_, -1)) {
97  return utils::split(lua_tostring(L_, -1));
98  }
99 
100  if(!lua_isfunction(L_, -1)) {
101  ERR_LUA << "Can't evaluate advancement aspect: Value is neither a string nor a function." << std::endl;
102  return std::vector<std::string>();
103  }
104 
105  // push parameter to the stack
106  lua_pushinteger(L_, unit_x);
107  lua_pushinteger(L_, unit_y);
108 
109  // To make unit_id a Parameter of the Lua function:
110  // lua_pushfstring(L_, unit_id.c_str());
111 
112  // call function
113  if(lua_pcall(L_, 2, 1, 0) != 0) {
114  ERR_LUA << "LUA Error while evaluating advancements_aspect: " << lua_tostring(L_, -1) << std::endl;
115  return std::vector<std::string>();
116  }
117 
118  if(!lua_isstring(L_, -1)) {
119  ERR_LUA << "LUA Error while evaluating advancements_aspect: Function must return String " << std::endl;
120  return std::vector<std::string>();
121  }
122 
123  // get result from Lua-Stack
124  const std::string retval = std::string(lua_tostring(L_, -1));
125  lua_pop(L_, 1);
126 
127  LOG_LUA << "Called Lua advancement function. Result was: \"" << retval << "\".\n";
128 
129  return utils::split(retval);
130 }
131 
132 const std::string unit_advancements_aspect::get_value() const
133 {
134  return val_;
135 }
136 }
static lg::log_domain log_ai_engine_lua("ai/engine/lua")
LUA_API void lua_settop(lua_State *L, int idx)
Definition: lapi.cpp:172
This class represents a single unit of a specific type.
Definition: unit.hpp:99
LUA_API int lua_rawgeti(lua_State *L, int idx, lua_Integer n)
Definition: lapi.cpp:657
LUALIB_API int luaL_ref(lua_State *L, int t)
Definition: lauxlib.cpp:595
#define val_(o)
Definition: lobject.h:123
#define LOG_LUA
std::vector< std::string > split(const std::string &val, const char c, const int flags)
Splits a (comma-)separated string into a vector of pieces.
#define lua_pop(L, n)
Definition: lua.h:344
const std::vector< std::string > get_advancements(const unit_map::const_iterator &unit) const
#define lua_pcall(L, n, r, f)
Definition: lua.h:278
A small explanation about what&#39;s going on here: Each action has access to two game_info objects First...
Definition: actions.cpp:58
LUA_API int lua_isstring(lua_State *L, int idx)
Definition: lapi.cpp:283
#define ERR_LUA
#define lua_isfunction(L, n)
Definition: lua.h:352
#define lua_tostring(L, i)
Definition: lua.h:366
const std::string get_value() const
#define LUA_REGISTRYINDEX
Definition: lua.h:42
Standard logging facilities (interface).
LUALIB_API void luaL_unref(lua_State *L, int t, int ref)
Definition: lauxlib.cpp:616
retval
Default window/dialog return values.
Definition: retval.hpp:28
bool valid() const
Definition: map.hpp:276
static map_location::DIRECTION n
LUA_API void lua_pushinteger(lua_State *L, lua_Integer n)
Definition: lapi.cpp:466
#define LUA_REFNIL
Definition: lauxlib.h:78