The Battle for Wesnoth  1.17.0-dev
lua_kernel_base.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2014 - 2021
3  by Chris Beck <render787@gmail.com>
4  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY.
12 
13  See the COPYING file for more details.
14 */
15 
16 #pragma once
17 
18 #include <sstream>
19 #include <string>
20 #include <vector>
21 #include <functional>
22 #include <cstdint>
23 
24 struct lua_State;
25 class config;
26 
28 public:
30  virtual ~lua_kernel_base();
31 
32  /** Runs a [lua] tag. Doesn't throw lua_error.*/
33  void run_lua_tag(const config& cfg);
34 
35  /** Runs a plain script. Doesn't throw lua_error.*/
36  void run(char const *prog, const std::string& name, int nArgs = 0);
37 
38  /** Runs a plain script, but reports errors by throwing lua_error.*/
39  void throwing_run(char const * prog, const std::string& name, int nArgs, bool in_interpreter = false);
40 
41  /** Tests if a program resolves to an expression, and pretty prints it if it is, otherwise it runs it normally. Throws exceptions.*/
42  void interactive_run(char const * prog);
43 
44  /** Loads the `package` library into lua environment. Only in allow in `unsafe` modes. */
45  void load_package();
46  /** Loads the "core" library into the Lua environment. Without this, most Wesnoth Lua won't work.
47  * Cannot be called from the constructor because it needs to call virtual functions.
48  */
49  void load_core();
50 
51  /** Get tab completion strings */
52  std::vector<std::string> get_global_var_names();
53  std::vector<std::string> get_attribute_names(const std::string & var_path);
54 
55  /** User-visible name of the lua kernel that they are talking to */
56  virtual std::string my_name() { return "Basic Lua Kernel"; }
57 
58  /** Access / manipulate logging of lua kernel activities */
59  const std::stringstream & get_log() { cmd_log_.log_ << std::flush; return cmd_log_.log_; }
60  void add_log(const char* str) { cmd_log_ << str; }
61  void clear_log() { cmd_log_.log_.str(""); cmd_log_.log_.clear(); }
62 
63  using external_log_type = std::function<void(const std::string &)>;
65 
66  /** Error reporting mechanisms, used by virtual methods protected_call and load_string*/
67  virtual void log_error(char const* msg, char const* context = "Lua error");
68  virtual void throw_exception(char const* msg, char const* context = "Lua error"); //throws game::lua_error
69 
70  typedef std::function<void(char const*, char const*)> error_handler;
71 
72  template<typename T>
73  static T& get_lua_kernel(lua_State *L)
74  {
75  return *static_cast<T*>(get_lua_kernel_base_ptr(L));
76  }
77 
78  virtual uint32_t get_random_seed();
79  lua_State * get_state() { return mState; }
80  void add_widget_definition(const std::string& type, const std::string& id) { registered_widget_definitions_.emplace_back(type, id); }
81 protected:
83 
84  /** Log implementation */
85  struct command_log {
86 
87  std::stringstream log_;
89 
91  : log_()
92  , external_log_(nullptr)
93  {}
94 
95  inline command_log & operator<< (const std::string & str) {
96  log_ << str;
97  if (external_log_) {
98  external_log_(str);
99  }
100  return *this;
101  }
102 
103  inline command_log & operator<< (char const* str) {
104  if (str != nullptr) {
105  log_ << str;
106  if (external_log_) {
107  external_log_(str);
108  }
109  }
110  return *this;
111  }
112  };
113 
115 
116  // Print text to the command log for this lua kernel. Used as a replacement impl for lua print.
117  int intf_print(lua_State * L);
118 public:
119  void add_log_to_console(const std::string& msg);
120  // Show the interactive lua console (for debugging purposes)
122 protected:
123  // Execute a protected call. Error handler is called in case of an error, using syntax for log_error and throw_exception above. Returns true if successful.
124  bool protected_call(int nArgs, int nRets, error_handler);
125  // Execute a protected call, taking a lua_State as argument. For functions pushed into the lua environment, this version should be used, or the function cannot be used by coroutines without segfaulting (since they have a different lua_State pointer). This version is called by the above version.
126  static bool protected_call(lua_State * L, int nArgs, int nRets, error_handler);
127  // Load a string onto the stack as a function. Returns true if successful, error handler is called if not.
128  bool load_string(char const * prog, const std::string& name, error_handler);
129 
130  virtual bool protected_call(int nArgs, int nRets); // select default error handler polymorphically
131  virtual bool load_string(char const * prog, const std::string& name); // select default error handler polymorphically
132 
133  // dofile (using lua_fileops)
134  int intf_dofile(lua_State * L);
135 
136  // require (using lua_fileops, protected_call)
137  int intf_require(lua_State * L);
138 
139  int intf_kernel_type(lua_State* L);
140 
141  virtual int impl_game_config_get(lua_State* L);
142  virtual int impl_game_config_set(lua_State* L);
143 private:
145  std::vector<std::tuple<std::string, std::string>> registered_widget_definitions_;
146 };
void interactive_run(char const *prog)
Tests if a program resolves to an expression, and pretty prints it if it is, otherwise it runs it nor...
std::function< void(char const *, char const *)> error_handler
command_log & operator<<(const std::string &str)
std::vector< std::tuple< std::string, std::string > > registered_widget_definitions_
int intf_kernel_type(lua_State *L)
virtual ~lua_kernel_base()
static void msg(const char *act, debug_info &i, const char *to="", const char *result="")
Definition: debugger.cpp:110
void add_widget_definition(const std::string &type, const std::string &id)
static T & get_lua_kernel(lua_State *L)
void load_core()
Loads the "core" library into the Lua environment.
int intf_show_lua_console(lua_State *L)
void load_package()
Loads the package library into lua environment.
bool protected_call(int nArgs, int nRets, error_handler)
virtual int impl_game_config_get(lua_State *L)
Definition: pump.hpp:40
void run(char const *prog, const std::string &name, int nArgs=0)
Runs a plain script.
int intf_print(lua_State *L)
Replacement print function – instead of printing to std::cout, print to the command log...
void set_external_log(external_log_type lg)
virtual uint32_t get_random_seed()
static std::string flush(std::ostringstream &s)
Definition: reports.cpp:92
std::function< void(const std::string &)> external_log_type
void throwing_run(char const *prog, const std::string &name, int nArgs, bool in_interpreter=false)
Runs a plain script, but reports errors by throwing lua_error.
virtual void log_error(char const *msg, char const *context="Lua error")
Error reporting mechanisms, used by virtual methods protected_call and load_string.
bool load_string(char const *prog, const std::string &name, error_handler)
virtual int impl_game_config_set(lua_State *L)
std::vector< std::string > get_global_var_names()
Get tab completion strings.
command_log cmd_log_
std::vector< std::string > get_attribute_names(const std::string &var_path)
Gets all attribute names of an extended variable name.
const std::stringstream & get_log()
Access / manipulate logging of lua kernel activities.
void add_log(const char *str)
virtual void throw_exception(char const *msg, char const *context="Lua error")
lua_State * get_state()
virtual std::string my_name()
User-visible name of the lua kernel that they are talking to.
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:61
int intf_dofile(lua_State *L)
Loads and executes a Lua file.
lua_State * mState
int intf_require(lua_State *L)
Loads and executes a Lua file, if there is no corresponding entry in wesnoth.package.
void add_log_to_console(const std::string &msg)
void run_lua_tag(const config &cfg)
Runs a [lua] tag.
static lua_kernel_base *& get_lua_kernel_base_ptr(lua_State *L)