{"action":"created","issue":{"url":"https://api.github.com/repos/GarageGames/Torque2D/issues/325","repository_url":"https://api.github.com/repos/GarageGames/Torque2D","labels_url":"https://api.github.com/repos/GarageGames/Torque2D/issues/325/labels{/name}","comments_url":"https://api.github.com/repos/GarageGames/Torque2D/issues/325/comments","events_url":"https://api.github.com/repos/GarageGames/Torque2D/issues/325/events","html_url":"https://github.com/GarageGames/Torque2D/issues/325","id":132604047,"number":325,"title":"Event Manager postEvent script callback error","user":{"login":"capnlove","id":715500,"avatar_url":"https://avatars.githubusercontent.com/u/715500?v=3","gravatar_id":"","url":"https://api.github.com/users/capnlove","html_url":"https://github.com/capnlove","followers_url":"https://api.github.com/users/capnlove/followers","following_url":"https://api.github.com/users/capnlove/following{/other_user}","gists_url":"https://api.github.com/users/capnlove/gists{/gist_id}","starred_url":"https://api.github.com/users/capnlove/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/capnlove/subscriptions","organizations_url":"https://api.github.com/users/capnlove/orgs","repos_url":"https://api.github.com/users/capnlove/repos","events_url":"https://api.github.com/users/capnlove/events{/privacy}","received_events_url":"https://api.github.com/users/capnlove/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":8,"created_at":"2016-02-10T04:29:56Z","updated_at":"2016-09-03T04:09:20Z","closed_at":null,"body":"**Context**\r\n\r\nThis occurs when an eventManager posts an event (via its postEvent ConsoleMethod) to its subscribers.\r\nThe code loops through all Simobject listeners (subscribers) and executes a script callback on each one.\r\n\r\n**/source/messaging/eventManager.cc**\r\nfunction EventManagerListener::onMessageReceived(...\r\n\r\n```\r\nconst char* conResult = Con::executef( iter->listener, 2, iter->callback, data );\r\n      if( dStrcmp( conResult, \"\" ) != 0 && dAtob( conResult ) == false )\r\n         return false;\r\n```\r\n\r\nIf the callback function returns a value and this value is evaluated to \"false\", the loop stops and all remaining subscribers are completely ignored.\r\n\r\nIn my code, the callback function contained one line of code\r\n\r\n```\r\nfunction GameManager::onPlayBall_EVT(%this, %data)\r\n{\r\n%this.CurrentState = \"Restart\";\r\n}\r\n```\r\n\r\nThis code assigns a string to a dynamically created variable (CurrentState) on a ScriptObject.\r\nThe ScriptObject named GameManager is a subscriber to the Event Manager.\r\n\r\n**Here is the problem :**\r\n\r\nThe C++ code takes the string \"Restart\" as the return value of the callback function.\r\nWhy would this value be returned from Con::executef?\r\n\r\nUsing functions like echo(...) or complex physics manipulation never cause this problem, the only way I've managed to reproduce this is with simple dynamic variable assignations as illustrated here.\r\n\r\n**Hack city**\r\n\r\nAdding \"return true;\" at the end of the script function solves the issue.\r\nI still think this points to a problem with the scripting engine."},"comment":{"url":"https://api.github.com/repos/GarageGames/Torque2D/issues/comments/244525317","html_url":"https://github.com/GarageGames/Torque2D/issues/325#issuecomment-244525317","issue_url":"https://api.github.com/repos/GarageGames/Torque2D/issues/325","id":244525317,"user":{"login":"greenfire27","id":5031861,"avatar_url":"https://avatars.githubusercontent.com/u/5031861?v=3","gravatar_id":"","url":"https://api.github.com/users/greenfire27","html_url":"https://github.com/greenfire27","followers_url":"https://api.github.com/users/greenfire27/followers","following_url":"https://api.github.com/users/greenfire27/following{/other_user}","gists_url":"https://api.github.com/users/greenfire27/gists{/gist_id}","starred_url":"https://api.github.com/users/greenfire27/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/greenfire27/subscriptions","organizations_url":"https://api.github.com/users/greenfire27/orgs","repos_url":"https://api.github.com/users/greenfire27/repos","events_url":"https://api.github.com/users/greenfire27/events{/privacy}","received_events_url":"https://api.github.com/users/greenfire27/received_events","type":"User","site_admin":false},"created_at":"2016-09-03T04:09:20Z","updated_at":"2016-09-03T04:09:20Z","body":"Returning to the original problem, if you look at the notes for the function onMessageReceived in eventManager.cc, the code actually take the return values of the callbacks and uses them to decide if it should keep making the callbacks.  Basically, a return value of true means that it will stop doing the callbacks (not sure if this is a useful feature or not).  Most of the callbacks that the engine does, like onAdd() when you create an object, do not expect a return value.  However, these particular callbacks expect a bool returned and are basically trying to make your last line in the callback into something it can use.  In the event that it get's a string that doesn't equal \"false\" it uses it as true stops passing the callback to more listeners.\r\n\r\nTo be honest, unless we decide to make it work differently, the best thing to do is simply always return false in your callbacks.\r\n\r\nNow, to keep things interesting, I found a better EventManager bug!  It seems if you remove a listener from an event during that listener's callback the engine crashes.\r\n\r\n`PlayerObject::onJump(%this, %data)`\r\n`{`\r\n    `   %myEventManager.remove(%this, \"Jump\"); //crash!`\r\n`}\r\n`\r\n\r\nMy guess is that we're changing the length of the iterator in the middle of using it."}}
{"actor":{"display_login":"greenfire27"}}