The Battle for Wesnoth  1.15.11+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 https://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/unit.hpp"
23 #include "units/map.hpp" // for unit_map::const_iterator, etc
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 
32 static lg::log_domain log_ai_engine_lua("ai/engine/lua");
33 #define LOG_LUA LOG_STREAM(info, log_ai_engine_lua)
34 #define ERR_LUA LOG_STREAM(err, log_ai_engine_lua)
35 
36 namespace ai{
37 
39  val_(), L_(),ref_()
40 {
41 }
42 
44  : val_("Lua Function")
45  , L_(L)
46  , ref_()
47 {
48  lua_settop(L, n);
49 
50  //on the top of the Lua-Stack is now the pointer to the function. Save it:
52 
53 }
54 
56 {
57 }
58 
60 {
61  if(L_) {
62  // Remove the function from the registry
64  }
65 }
66 
67 const std::vector<std::string> unit_advancements_aspect::get_advancements(const unit_map::const_iterator& unit) const
68 {
69 
70  if(!unit.valid())
71  {
72  return std::vector<std::string>();
73  }
74 
75  const std::string& unit_id = (*unit).id();
76  const int unit_x = (*unit).get_location().wml_x();
77  const int unit_y = (*unit).get_location().wml_y();
78 
79  LOG_LUA << "Entering unit_advancements_aspect::get_advancements() in instance " << this << " with unit " << unit_id << " on (x,y) = (" << unit_x << ", " << unit_y << ")\n";
80 
81  if(L_ == nullptr || ref_ == LUA_REFNIL)
82  {
83  //If we end up here, most likely the aspect don't use the lua-engine.
84  //Just to make sure:
85  if (val_ == "Lua Function")
86  {
87  return std::vector<std::string>();
88  }
89  return utils::split(val_);
90  }
91 
92  //put the Pointer back on the Stack
94 
95  if(lua_isstring(L_, -1))
96  {
97  return utils::split(lua_tostring(L_, -1));
98  }
99 
100  if(!lua_isfunction(L_, -1))
101  {
102  ERR_LUA << "Can't evaluate advancement aspect: Value is neither a string nor a function." << std::endl;
103  return std::vector<std::string>();
104  }
105 
106  //push parameter to the stack
107  lua_pushinteger(L_, unit_x);
108  lua_pushinteger(L_, unit_y);
109 
110  //To make unit_id a Parameter of the Lua function:
111  //lua_pushfstring(L_, unit_id.c_str());
112 
113  //call function
114  if(lua_pcall(L_, 2, 1, 0) != 0)
115  {
116  ERR_LUA << "LUA Error while evaluating advancements_aspect: " << lua_tostring(L_, -1) << std::endl;
117  return std::vector<std::string>();
118  }
119  if (!lua_isstring(L_, -1))
120  {
121  ERR_LUA << "LUA Error while evaluating advancements_aspect: Function must return String " << std::endl;
122  return std::vector<std::string>();
123  }
124 
125  //get result from Lua-Stack
126  const std::string retval = std::string(lua_tostring(L_, -1));
127  lua_pop(L_, 1);
128 
129  LOG_LUA << "Called Lua advancement function. Result was: \"" << retval << "\".\n";
130 
131  return utils::split(retval);
132 }
133 
134 const std::string unit_advancements_aspect::get_value() const
135 {
136  return val_;
137 }
138 }
static lg::log_domain log_ai_engine_lua("ai/engine/lua")
LUA_API void lua_settop(lua_State *L, int idx)
Definition: lapi.cpp:173
This class represents a single unit of a specific type.
Definition: unit.hpp:120
LUA_API int lua_rawgeti(lua_State *L, int idx, lua_Integer n)
Definition: lapi.cpp:710
LUALIB_API int luaL_ref(lua_State *L, int t)
Definition: lauxlib.cpp:646
#define val_(o)
Definition: lobject.h:70
#define LOG_LUA
#define lua_pop(L, n)
Definition: lua.h:364
const std::vector< std::string > get_advancements(const unit_map::const_iterator &unit) const
#define lua_pcall(L, n, r, f)
Definition: lua.h:287
A small explanation about what&#39;s going on here: Each action has access to two game_info objects First...
Definition: actions.cpp:59
LUA_API int lua_isstring(lua_State *L, int idx)
Definition: lapi.cpp:292
#define ERR_LUA
#define lua_isfunction(L, n)
Definition: lua.h:372
#define lua_tostring(L, i)
Definition: lua.h:386
const std::string get_value() const
#define LUA_REGISTRYINDEX
Definition: lua.h:44
std::vector< std::string > split(const config_attribute_value &val)
Standard logging facilities (interface).
LUALIB_API void luaL_unref(lua_State *L, int t, int ref)
Definition: lauxlib.cpp:667
retval
Default window/dialog return values.
Definition: retval.hpp:28
bool valid() const
Definition: map.hpp:273
static map_location::DIRECTION n
LUA_API void lua_pushinteger(lua_State *L, lua_Integer n)
Definition: lapi.cpp:489
#define LUA_REFNIL
Definition: lauxlib.h:86