1// SuperTux -- ExposedObject class
2// Copyright (C) 2016 Tobias Markus <tobbi.bugs@googlemail.com>
3//
4// This program is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// This program is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with this program. If not, see <http://www.gnu.org/licenses/>.
16
17#ifndef HEADER_SUPERTUX_SQUIRREL_EXPOSED_OBJECT_HPP
18#define HEADER_SUPERTUX_SQUIRREL_EXPOSED_OBJECT_HPP
19
20#include <memory>
21
22#include "squirrel/squirrel_virtual_machine.hpp"
23#include "squirrel/squirrel_util.hpp"
24#include "squirrel/script_interface.hpp"
25#include "util/log.hpp"
26
27/**
28 * @class ExposedObject
29 * This class binds a certain GameObject class to a scripting class.
30 * To bind a game object class to a scripting class, extend the GameObject
31 * class as shown in the following example:
32 * \code{.cpp}
33 * public ExposedObject<Gradient, scripting::Gradient>
34 * \endcode
35 *
36 * and instantiate it in each constructor with the <i>this</i> pointer, like this:
37 * \code{.cpp}
38 * Gradient::Gradient(const ReaderMapping& reader) :
39 * ExposedObject<Gradient, scripting::Gradient>(this)
40 * \endcode
41 * @param class S: GameObject class (e.g. Gradient)
42 * @param class T: Scripting class (e.g. scripting::Gradient)
43 */
44template<class S, class T>
45class ExposedObject : public ScriptInterface
46{
47private:
48 /**
49 * The parent object that is exposed to the script interface
50 */
51 S* m_parent;
52
53public:
54 /**
55 * Constructor
56 * @param parent GameObject
57 */
58 ExposedObject(S* parent) :
59 m_parent(parent)
60 {
61 }
62
63 /**
64 * Exposes the parent GameObject to the script Interface
65 * @param vm The squirrel virtual machine to expose the object on
66 * @param table_idx Index of the table to expose the object on
67 */
68 virtual void expose(HSQUIRRELVM vm, SQInteger table_idx) override
69 {
70 auto name = m_parent->get_name();
71 if (name.empty())
72 {
73 return;
74 }
75
76 log_debug << "Exposing " << m_parent->get_class() << " object " << name << std::endl;
77
78 auto object = std::make_unique<T>(m_parent->get_uid());
79 expose_object(vm, table_idx, std::move(object), name);
80 }
81
82 /**
83 * Un-exposes the parent GameObject to the script Interface
84 * @param vm The squirrel virtual machine to un-expose the object on
85 * @param table_idx Index of the table to un-expose the object on
86 */
87 virtual void unexpose(HSQUIRRELVM vm, SQInteger table_idx) override
88 {
89 auto name = m_parent->get_name();
90 if (name.empty())
91 {
92 return;
93 }
94
95 log_debug << "Unexposing object " << name << std::endl;
96
97 unexpose_object(vm, table_idx, name);
98 }
99
100private:
101 ExposedObject(const ExposedObject&) = delete;
102 ExposedObject& operator=(const ExposedObject&) = delete;
103};
104
105#endif
106
107/* EOF */
108