eugene.litvinov Posted November 10, 2010 Share Posted November 10, 2010 Hello. I try to use trigger for PlayerActor (when PlayerActor enter to trigger do something); I have class Game, that created and use in main.cpp. So, when I set enter/leave callbacks to trigger, in this functions I can not set variables, that in Game class scope. How can I get variable robotActive from class Game? #include <core/scripts/utils.h> #include <source/scripts/Utils.h> Node add_editor(Node node) { engine.editor.addNode(node); return node_remove(node); } class Game { private: PlayerActor player; public: int robotActive = 110; // this is variable, that I want set in trigger's callback ObjectMeshSkinned meshWoman; PhysicalTrigger trigger; Game(PlayerActor player) { if (engine.editor.isLoaded()) return 1; this.player = player; } ~Game() { log.message("Game::destructor()\n"); } void enter_callback(Body body) { log.message("ENTER: " + this.robotActive + "\n"); this.robotActive = 1; // this is work, but variable Game::robotActive don't change value log.message("ENTER: " + this.robotActive + "\n"); } void leave_callback(Body body) { log.message("LEAVE: " + this.robotActive + "\n"); this.robotActive = 0; log.message("LEAVE: " + this.robotActive + "\n"); } int init() { log.message("Game::init()\n"); // search the node by the specified name int meshWomanIndex = engine.editor.findNode("robot"); log.message("robot: " + meshWomanIndex + "\n"); int meshDieIndex = engine.editor.findNode("cube"); log.message("cube: " + meshDieIndex + "\n"); if (meshDieIndex != -1) { Node meshDie = engine.editor.getNode(meshDieIndex); GameObject data = new GameObject("dieData", NULL, NULL); data.node = meshDie; //meshDie.setData(data); meshDie.setData(format("x: %d y: %d",0,1)); } if (meshWomanIndex != -1) { Node nodeWoman = engine.editor.getNode(meshWomanIndex); meshWoman = Utils::nodeCast(nodeWoman); trigger = add_editor(new PhysicalTrigger(SHAPE_BOX, vec3(10.0f, 10.0f, 2.0f))); trigger.setPosition(meshWoman.getPosition()); trigger.setEnterCallback("Game::enter_callback"); trigger.setLeaveCallback("Game::leave_callback"); } return 1; } int shutdown() { log.message("Game::shutdown()\n"); return 1; } int update() { trigger.renderVisualizer(); // in this place variable robotActive always stay 110, even when activated trigger functions log.message("robotActive: " + robotActive + "\n"); if (meshWoman != NULL && robotActive == 1) { log.message("update robot: \n"); } return 1; } }; Thanks Link to comment
frustum Posted November 10, 2010 Share Posted November 10, 2010 You can't use such callback function. Because script treats them as ordinary function in class namespace. There is trick in UnigineScript: class Foo { PhysicalTrigger trigger; Foo() { trigger.setEnterCallback("Foo::enter_callback_redirector",this); } void enter_callback() { // do_some } void enter_callback_redirector(Foo foo) { foo.enter_callback(); } }; Link to comment
eugene.litvinov Posted November 10, 2010 Author Share Posted November 10, 2010 I change my code: trigger.setEnterCallback("Game::enterCallbackRedirector", this); trigger.setLeaveCallback("Game::leaveCallbackRedirector", this); and add two functions: void enterCallbackRedirector(Game game) { game.enter_callback(); } void leaveCallbackRedirector(Game game) { game.leave_callback(); } but now, when I enter to trigger zone, interpreter throw error: Interpreter::runFunction(): bad argument type “Body” in “Game::enterCallbackRedirector” function mustbe “Game”. Link to comment
eugene.litvinov Posted November 11, 2010 Author Share Posted November 11, 2010 Decision: void enterCallbackRedirector(Body body, Game game) { game.enter_callback(body); } void leaveCallbackRedirector(Body body, Game game) { game.leave_callback(body); } void enter_callback(Body body) { log.message("ENTER: " + this.robotActive + "\n"); this.robotActive = 1; } void leave_callback(Body body) { log.message("LEAVE: " + this.robotActive + "\n"); this.robotActive = 0; } Link to comment
eugene.litvinov Posted November 11, 2010 Author Share Posted November 11, 2010 In additional to: I'm writing GUI interface, and add some interaction: <icon name="ToolBar::changeCameraIcon" export="1" toggleable="1" texture="player_dummy.png"> <callback type="clicked">ToolBar::changeCameraClickHandler</callback> </icon> ToolBar - it's class, in this class saved pointer to my main Game class. And when I write function changeCameraClickHandler: void changeCameraClickHandler() { log.message("ToolBar::changeCameraClickHandler()\n"); log.message("game: " + typeinfo(game) + "\n"); game.changeCamera(); } this in throw error, because in function changeCameraClickHandler I can not get access to game variable. It's the same problem like with Trigger's callback? I can only use namespaces instead classes? If so, in future releases will be more strong OOP support? Thanks. Link to comment
eugene.litvinov Posted November 11, 2010 Author Share Posted November 11, 2010 I try to use this variant: void changeCameraClickHandler() { log.message("ToolBar::changeCameraClickHandler()\n"); Game::changeCamera(); } I don't know is it good practice or not, but it's work :) Link to comment
eugene.litvinov Posted November 11, 2010 Author Share Posted November 11, 2010 No, it's not a good decision: Game::changeCamera() works something like static call? I can not get members of Game, this is NULL :) Link to comment
ulf.schroeter Posted November 11, 2010 Share Posted November 11, 2010 I don't know is it good practice or not, but it's work :) It works because you are now calling "static" function changeCamera() in namespace Game. Previously you tried to access a Game object instance without having a global reference to it. Link to comment
eugene.litvinov Posted November 11, 2010 Author Share Posted November 11, 2010 Yes, I have some global variables in world script: Editor editor; Game game; int init() { game = new Game(); } I try to use your example: class Game { public: PlayerActor player; PlayerSpectator observer; Game(PlayerActor player) { if (engine.editor.isLoaded()) return 1; player = new PlayerActor(); engine.game.setPlayer(player); } ~Game() { log.message("Game::destructor()\n"); } void changeCamera() { log.message("Game::changeCamera(): " + typeinfo(game) + "\n"); } }; but I have some problem: 18:16:14 Unigine~# world_load main 18:16:14 log.message("Game::changeCamera(): " + typeinfo(game) + "\n"); 18:16:14 source/scripts/Game.h:103: Interpreter::parse_expression(): unknown token "game" in "game" expression So I can't get access to global variable game inside a class member function Game::changeCamera() :) Link to comment
ulf.schroeter Posted November 11, 2010 Share Posted November 11, 2010 So I can't get access to global variable game inside a class member function Game::changeCamera() :) Not sure, but I think this would require some kind of forward declaration capability which is most probably not supported within UNIGINE script (but I am not expert). Anyway I think you should stay with working static function call Game::changeCamera() because this is a straight-forward implmentation. Link to comment
eugene.litvinov Posted November 12, 2010 Author Share Posted November 12, 2010 I prepare test_gui scene, this is source: test.cpp: Game game; ToolBar toolBar; int init() { game = new Game(); toolBar = new ToolBar(game); return 1; } Game.h class Game { public: int cameraType = 1; Game() { } ~Game() { log.message("Game::destructor()\n"); } void changeCamera() { log.message("Game::changeCamera(): " + typeinfo(this) + "\n"); log.message("Game::cameraType(): " + cameraType + "\n"); cameraType = 2; log.message("Game::cameraType(): " + cameraType + "\n"); } }; ToolBar.h class ToolBar { private: Game game; public: UserInterface ui; WidgetVBox vBox; WidgetIcon changeCameraIcon; ToolBar(Game game) { this.game = game; log.message("game: " + typeinfo(this.game) + "\n"); ui = engine.gui.addUserInterface(engine.getGui(), "test_gui/scripts/ToolBar.ui"); Gui gui = engine.getGui(); gui.addChild(vBox, GUI_ALIGN_OVERLAP); vBox.setPosition(2, 42); } void changeCameraClickHandler() { log.message("ToolBar::changeCameraClickHandler()\n"); //game.changeCamera(); // not work at all Game::changeCamera(); // function call like static } }; ToolBar.ui <?xml version="1.0" encoding="utf-8"?> <ui version="1.0"> <vbox name="ToolBar::vBox" export="1"> <icon name="ToolBar::changeCameraIcon" export="1" toggleable="1" texture="player_dummy.png"> <callback type="clicked">ToolBar::changeCameraClickHandler</callback> </icon> </vbox> </ui> If I call function like static Game::changeCamera() than I can't get Game's variables. How this situation can be solved? In attachment full source. Thanks. test_gui.zip Link to comment
eugene.litvinov Posted November 12, 2010 Author Share Posted November 12, 2010 Decision: Write class Global with members variables: class Global { public: Editor editor; Game game; Game getGame() { return game; } Game getEditor() { return editor; } }; In other classes we can write: Game game = Global::getGame(); game.changeCamera(); For some reason I cant access to variables right Game::game, but function getGame() return correct pointer; Link to comment
Recommended Posts