Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed Squirrel inheritance/multiple exposure (Will O'Wisps are back in scripting) #1566

Merged
merged 3 commits into from
Oct 24, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/badguy/dispenser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,16 @@ class Dispenser final : public BadGuy,
virtual ObjectSettings get_settings() override;
virtual void after_editor_set() override;

virtual void expose(HSQUIRRELVM vm, SQInteger table_idx) override
{
ExposedObject<Dispenser, scripting::Dispenser>::expose(vm, table_idx);
}

virtual void unexpose(HSQUIRRELVM vm, SQInteger table_idx) override
{
ExposedObject<Dispenser, scripting::Dispenser>::unexpose(vm, table_idx);
}

void notify_dead() {
if (m_limit_dispensed_badguys) {
m_current_badguys--;
Expand Down
10 changes: 10 additions & 0 deletions src/badguy/willowisp.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,16 @@ class WillOWisp final :
virtual ObjectSettings get_settings() override;
virtual void move_to(const Vector& pos) override;

virtual void expose(HSQUIRRELVM vm, SQInteger table_idx) override
{
ExposedObject<WillOWisp, scripting::WillOWisp>::expose(vm, table_idx);
}

virtual void unexpose(HSQUIRRELVM vm, SQInteger table_idx) override
{
ExposedObject<WillOWisp, scripting::WillOWisp>::unexpose(vm, table_idx);
}

/** make WillOWisp vanish */
void vanish();

Expand Down
4 changes: 2 additions & 2 deletions src/scripting/badguy.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ class BadGuy;

namespace scripting {

class BadGuy final
class BadGuy
#ifndef SCRIPTING_API
: public GameObject<::BadGuy>
: virtual public GameObject<::BadGuy>
#endif
{
#ifndef SCRIPTING_API
Expand Down
4 changes: 2 additions & 2 deletions src/scripting/dispenser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ namespace scripting {

void Dispenser::activate()
{
SCRIPT_GUARD_VOID;
SCRIPT_GUARD_VOID_T(Dispenser);
object.activate();
}

void Dispenser::deactivate()
{
SCRIPT_GUARD_VOID;
SCRIPT_GUARD_VOID_T(Dispenser);
object.deactivate();
}

Expand Down
7 changes: 4 additions & 3 deletions src/scripting/dispenser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,22 @@
#define HEADER_SUPERTUX_SCRIPTING_DISPENSER_HPP

#ifndef SCRIPTING_API
#include "scripting/badguy.hpp"
#include "scripting/game_object.hpp"

class Dispenser;
#endif

namespace scripting {

class Dispenser final
class Dispenser final : public scripting::BadGuy
#ifndef SCRIPTING_API
: public GameObject<::Dispenser>
, virtual public GameObject<::Dispenser>
#endif
{
#ifndef SCRIPTING_API
public:
using GameObject::GameObject;
using BadGuy::BadGuy;

private:
Dispenser(const Dispenser&) = delete;
Expand Down
27 changes: 27 additions & 0 deletions src/scripting/game_object.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,33 @@
} \
auto& object __attribute__((unused)) = *object_ptr

#define SCRIPT_GUARD_VOID_T(OBJECT) \
auto object_ptr = GameObject<::OBJECT>::get_object_ptr(); \
if (object_ptr == nullptr) { \
log_fatal << "error: script is accessing a dead object: " \
<< GameObject<::OBJECT>::m_uid << std::endl; \
return; \
} \
auto& object = *object_ptr

#define SCRIPT_GUARD_DEFAULT_T(OBJECT) \
auto object_ptr = GameObject<::OBJECT>::get_object_ptr(); \
if (object_ptr == nullptr) { \
log_fatal << "error: script is accessing a dead object: " \
<< GameObject<::OBJECT>::m_uid << std::endl; \
return {}; \
} \
auto& object = *object_ptr

#define SCRIPT_GUARD_RETURN_T(OBJECT, x) \
auto object_ptr = GameObject<::OBJECT>::get_object_ptr(); \
if (object_ptr == nullptr) { \
log_fatal << "error: script is accessing a dead object: " \
<< GameObject<::OBJECT>::m_uid << std::endl; \
return x; \
} \
auto& object __attribute__((unused)) = *object_ptr

class GameObjectManager;

namespace scripting {
Expand Down
8 changes: 4 additions & 4 deletions src/scripting/willowisp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,28 +23,28 @@ namespace scripting {
void
WillOWisp::goto_node(int node_no)
{
SCRIPT_GUARD_VOID;
SCRIPT_GUARD_VOID_T(WillOWisp);
object.goto_node(node_no);
}

void
WillOWisp::set_state(const std::string& state)
{
SCRIPT_GUARD_VOID;
SCRIPT_GUARD_VOID_T(WillOWisp);
object.set_state(state);
}

void
WillOWisp::start_moving()
{
SCRIPT_GUARD_VOID;
SCRIPT_GUARD_VOID_T(WillOWisp);
object.start_moving();
}

void
WillOWisp::stop_moving()
{
SCRIPT_GUARD_VOID;
SCRIPT_GUARD_VOID_T(WillOWisp);
object.stop_moving();
}

Expand Down
7 changes: 4 additions & 3 deletions src/scripting/willowisp.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,22 @@

#ifndef SCRIPTING_API
#include <string>
#include "scripting/badguy.hpp"
#include "scripting/game_object.hpp"

class WillOWisp;
#endif

namespace scripting {

class WillOWisp final
class WillOWisp final : public scripting::BadGuy
#ifndef SCRIPTING_API
: public GameObject<::WillOWisp>
, virtual public GameObject<::WillOWisp>
#endif
{
#ifndef SCRIPTING_API
public:
using GameObject::GameObject;
using BadGuy::BadGuy;

private:
WillOWisp(const WillOWisp&) = delete;
Expand Down
132 changes: 68 additions & 64 deletions src/scripting/wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8176,6 +8176,74 @@ void register_supertux_wrapper(HSQUIRRELVM v)
throw SquirrelError(v, "Couldn't register class 'BadGuy'");
}

// Register class Dispenser
sq_pushstring(v, "Dispenser", -1);
sq_pushstring(v, "BadGuy", -1);
sq_get(v, -3);
if(sq_newclass(v, SQTrue) < 0) {
std::ostringstream msg;
msg << "Couldn't create new class 'Dispenser'";
throw SquirrelError(v, msg.str());
}
sq_pushstring(v, "activate", -1);
sq_newclosure(v, &Dispenser_activate_wrapper, 0);
sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
if(SQ_FAILED(sq_createslot(v, -3))) {
throw SquirrelError(v, "Couldn't register function 'activate'");
}

sq_pushstring(v, "deactivate", -1);
sq_newclosure(v, &Dispenser_deactivate_wrapper, 0);
sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
if(SQ_FAILED(sq_createslot(v, -3))) {
throw SquirrelError(v, "Couldn't register function 'deactivate'");
}

if(SQ_FAILED(sq_createslot(v, -3))) {
throw SquirrelError(v, "Couldn't register class 'Dispenser'");
}

// Register class WillOWisp
sq_pushstring(v, "WillOWisp", -1);
sq_pushstring(v, "BadGuy", -1);
sq_get(v, -3);
if(sq_newclass(v, SQTrue) < 0) {
std::ostringstream msg;
msg << "Couldn't create new class 'WillOWisp'";
throw SquirrelError(v, msg.str());
}
sq_pushstring(v, "goto_node", -1);
sq_newclosure(v, &WillOWisp_goto_node_wrapper, 0);
sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|ti");
if(SQ_FAILED(sq_createslot(v, -3))) {
throw SquirrelError(v, "Couldn't register function 'goto_node'");
}

sq_pushstring(v, "set_state", -1);
sq_newclosure(v, &WillOWisp_set_state_wrapper, 0);
sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|ts");
if(SQ_FAILED(sq_createslot(v, -3))) {
throw SquirrelError(v, "Couldn't register function 'set_state'");
}

sq_pushstring(v, "start_moving", -1);
sq_newclosure(v, &WillOWisp_start_moving_wrapper, 0);
sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
if(SQ_FAILED(sq_createslot(v, -3))) {
throw SquirrelError(v, "Couldn't register function 'start_moving'");
}

sq_pushstring(v, "stop_moving", -1);
sq_newclosure(v, &WillOWisp_stop_moving_wrapper, 0);
sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
if(SQ_FAILED(sq_createslot(v, -3))) {
throw SquirrelError(v, "Couldn't register function 'stop_moving'");
}

if(SQ_FAILED(sq_createslot(v, -3))) {
throw SquirrelError(v, "Couldn't register class 'WillOWisp'");
}

// Register class Camera
sq_pushstring(v, "Camera", -1);
if(sq_newclass(v, SQFalse) < 0) {
Expand Down Expand Up @@ -8286,31 +8354,6 @@ void register_supertux_wrapper(HSQUIRRELVM v)
throw SquirrelError(v, "Couldn't register class 'Decal'");
}

// Register class Dispenser
sq_pushstring(v, "Dispenser", -1);
if(sq_newclass(v, SQFalse) < 0) {
std::ostringstream msg;
msg << "Couldn't create new class 'Dispenser'";
throw SquirrelError(v, msg.str());
}
sq_pushstring(v, "activate", -1);
sq_newclosure(v, &Dispenser_activate_wrapper, 0);
sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
if(SQ_FAILED(sq_createslot(v, -3))) {
throw SquirrelError(v, "Couldn't register function 'activate'");
}

sq_pushstring(v, "deactivate", -1);
sq_newclosure(v, &Dispenser_deactivate_wrapper, 0);
sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
if(SQ_FAILED(sq_createslot(v, -3))) {
throw SquirrelError(v, "Couldn't register function 'deactivate'");
}

if(SQ_FAILED(sq_createslot(v, -3))) {
throw SquirrelError(v, "Couldn't register class 'Dispenser'");
}

// Register class DisplayEffect
sq_pushstring(v, "DisplayEffect", -1);
if(sq_newclass(v, SQFalse) < 0) {
Expand Down Expand Up @@ -9463,45 +9506,6 @@ void register_supertux_wrapper(HSQUIRRELVM v)
throw SquirrelError(v, "Couldn't register class 'Torch'");
}

// Register class WillOWisp
sq_pushstring(v, "WillOWisp", -1);
if(sq_newclass(v, SQFalse) < 0) {
std::ostringstream msg;
msg << "Couldn't create new class 'WillOWisp'";
throw SquirrelError(v, msg.str());
}
sq_pushstring(v, "goto_node", -1);
sq_newclosure(v, &WillOWisp_goto_node_wrapper, 0);
sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|ti");
if(SQ_FAILED(sq_createslot(v, -3))) {
throw SquirrelError(v, "Couldn't register function 'goto_node'");
}

sq_pushstring(v, "set_state", -1);
sq_newclosure(v, &WillOWisp_set_state_wrapper, 0);
sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|ts");
if(SQ_FAILED(sq_createslot(v, -3))) {
throw SquirrelError(v, "Couldn't register function 'set_state'");
}

sq_pushstring(v, "start_moving", -1);
sq_newclosure(v, &WillOWisp_start_moving_wrapper, 0);
sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
if(SQ_FAILED(sq_createslot(v, -3))) {
throw SquirrelError(v, "Couldn't register function 'start_moving'");
}

sq_pushstring(v, "stop_moving", -1);
sq_newclosure(v, &WillOWisp_stop_moving_wrapper, 0);
sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, "x|t");
if(SQ_FAILED(sq_createslot(v, -3))) {
throw SquirrelError(v, "Couldn't register function 'stop_moving'");
}

if(SQ_FAILED(sq_createslot(v, -3))) {
throw SquirrelError(v, "Couldn't register class 'WillOWisp'");
}

// Register class Wind
sq_pushstring(v, "Wind", -1);
if(sq_newclass(v, SQFalse) < 0) {
Expand Down
2 changes: 1 addition & 1 deletion src/squirrel/exposed_object.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
* @param class T: Scripting class (e.g. scripting::Gradient)
*/
template<class S, class T>
class ExposedObject : public ScriptInterface
class ExposedObject : virtual public ScriptInterface
{
private:
/**
Expand Down