1 //  SuperTux
2 //  Copyright (C) 2006 Matthias Braun <matze@braunis.de>
3 //                2018 Ingo Ruhnke <grumbel@gmail.com>
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 3 of the License, or
8 //  (at your option) any later version.
9 //
10 //  This program is distributed in the hope that it will be useful,
11 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 //  GNU General Public License for more details.
14 //
15 //  You should have received a copy of the GNU General Public License
16 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 
18 #ifndef HEADER_SUPERTUX_SQUIRREL_SQUIRREL_ENVIRONMENT_HPP
19 #define HEADER_SUPERTUX_SQUIRREL_SQUIRREL_ENVIRONMENT_HPP
20 
21 #include <string>
22 #include <vector>
23 
24 #include <squirrel.h>
25 
26 #include "squirrel/squirrel_util.hpp"
27 
28 class GameObject;
29 class ScriptInterface;
30 class SquirrelVM;
31 
32 /** The SquirrelEnvironment contains the environment in which a script
33     is executed, meaning a root table containing objects and
34     variables. */
35 class SquirrelEnvironment
36 {
37 public:
38   SquirrelEnvironment(SquirrelVM& vm, const std::string& name);
39   virtual ~SquirrelEnvironment();
40 
41 public:
get_vm() const42   SquirrelVM& get_vm() const { return m_vm; }
43 
44   /** Expose this engine under 'name' */
45   void expose_self();
46   void unexpose_self();
47 
48   /** Expose the GameObject if it has a ScriptInterface, otherwise do
49       nothing. */
50   void try_expose(GameObject& object);
51   void try_unexpose(GameObject& object);
52 
53   /** Generic expose function, T must be a type that has a
54       create_squirrel_instance() associated with it. */
55   template<typename T>
expose(const std::string & name,std::unique_ptr<T> script_object)56   void expose(const std::string& name, std::unique_ptr<T> script_object)
57   {
58     sq_pushobject(m_vm.get_vm(), m_table);
59     expose_object(m_vm.get_vm(), -1, std::move(script_object), name.c_str());
60     sq_pop(m_vm.get_vm(), 1);
61   }
62   void unexpose(const std::string& name);
63 
64   /** Convenience function that takes an std::string instead of an
65       std::istream& */
66   void run_script(const std::string& script, const std::string& sourcename);
67 
68   /** Runs a script in the context of the SquirrelEnvironment (m_table will
69       be the roottable of this squirrel VM) and keeps a reference to
70       the script so the script gets destroyed when the SquirrelEnvironment is
71       destroyed). */
72   void run_script(std::istream& in, const std::string& sourcename);
73 
74   void update(float dt_sec);
75   void wait_for_seconds(HSQUIRRELVM vm, float seconds);
76   void skippable_wait_for_seconds(HSQUIRRELVM vm, float seconds);
77 
78 private:
79   void garbage_collect();
80 
81 private:
82   SquirrelVM& m_vm;
83   HSQOBJECT m_table;
84   std::string m_name;
85   std::vector<HSQOBJECT> m_scripts;
86   std::unique_ptr<SquirrelScheduler> m_scheduler;
87 
88 private:
89   SquirrelEnvironment(const SquirrelEnvironment&) = delete;
90   SquirrelEnvironment& operator=(const SquirrelEnvironment&) = delete;
91 };
92 
93 #endif
94 
95 /* EOF */
96