Difference between revisions of "Talk:Writing Modules In C"
Mine GO BOOM (talk | contribs) |
(bug in tutorial?) |
||
Line 11: | Line 11: | ||
link = LLGetHead(&pd->playerlist); \ | link = LLGetHead(&pd->playerlist); \ | ||
link && ((p = link->data, link = link->next) || 1); )</pre> | link && ((p = link->data, link = link->next) || 1); )</pre> | ||
+ | |||
+ | |||
+ | === Bug? === | ||
+ | |||
+ | So looking back on this tutorial I think | ||
+ | <pre> | ||
+ | if (action == MM_LOAD) | ||
+ | { | ||
+ | mm = mm_; | ||
+ | |||
+ | chat = mm->GetInterface(I_CHAT,ALLARENAS); | ||
+ | aman = mm->GetInterface(I_ARENAMAN, ALLARENAS); | ||
+ | pd = mm->GetInterface(I_PLAYERDATA,ALLARENAS); | ||
+ | |||
+ | if (!chat || !aman || !pd) // check interfaces | ||
+ | rv = MM_FAIL; | ||
+ | else | ||
+ | { | ||
+ | // allocate data | ||
+ | arenaKey = aman->AllocateArenaData(sizeof(MyArenaData)); | ||
+ | playerKey = pd->AllocatePlayerData(sizeof(MyPlayerData)); | ||
+ | |||
+ | if (!arenaKey || !playerKey) // check if we ran out of memory | ||
+ | { | ||
+ | rv = MM_FAIL; | ||
+ | } | ||
+ | else | ||
+ | { // declare callbacks, commands, and timers | ||
+ | mm->RegCallback(CB_SHIPCHANGE, ShipChange, ALLARENAS); | ||
+ | rv = MM_OK; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </pre> | ||
+ | |||
+ | fails to release the interfaces when there's an error, which will create problems when modules unload. After "rv = MM_FAIL;", in both instances, I think it's necessary to add | ||
+ | <pre> | ||
+ | mm->releaseInterface(chat); | ||
+ | mm->releaseInterface(aman); | ||
+ | mm->releaseInterface(pd); | ||
+ | </pre> | ||
+ | |||
+ | also, the modules shouldn't be listening for MM_ATTACH AND MM_DETACH if it's never using those guys (or the tutorial should cover what they do). | ||
+ | |||
+ | Let me know if I'm wrong. |
Revision as of 19:34, 4 April 2007
The example given for how to use the FOR_EACH_PLAYER macro doesn't show why you need a Link pointer named link!
The example just declares the variable, without initializing it to any value, and doesn't do anything with the Link pointer after that.
quote from article: "There is an ASSS macro, FOR_EACH_PLAYER, that will help us loop through every player. To use this macro we need: a Player* and a Link* named link."
Mine GO BOOM 15:56, Oct 3, 2006 (PDT): In player.h, the macro FOR_EACH_PLAYER is defined as the following. The for line assumes a Link* variable named link for it to work correctly. Under C++, you could initalize the link variable in the for loop but you cannot in C. A slightly better method would have the Link* variable name be include in the macro's definition instead of assuming a variable named link.
#define FOR_EACH_PLAYER(p) \ for ( \ link = LLGetHead(&pd->playerlist); \ link && ((p = link->data, link = link->next) || 1); )
Bug?
So looking back on this tutorial I think
if (action == MM_LOAD) { mm = mm_; chat = mm->GetInterface(I_CHAT,ALLARENAS); aman = mm->GetInterface(I_ARENAMAN, ALLARENAS); pd = mm->GetInterface(I_PLAYERDATA,ALLARENAS); if (!chat || !aman || !pd) // check interfaces rv = MM_FAIL; else { // allocate data arenaKey = aman->AllocateArenaData(sizeof(MyArenaData)); playerKey = pd->AllocatePlayerData(sizeof(MyPlayerData)); if (!arenaKey || !playerKey) // check if we ran out of memory { rv = MM_FAIL; } else { // declare callbacks, commands, and timers mm->RegCallback(CB_SHIPCHANGE, ShipChange, ALLARENAS); rv = MM_OK; } } }
fails to release the interfaces when there's an error, which will create problems when modules unload. After "rv = MM_FAIL;", in both instances, I think it's necessary to add
mm->releaseInterface(chat); mm->releaseInterface(aman); mm->releaseInterface(pd);
also, the modules shouldn't be listening for MM_ATTACH AND MM_DETACH if it's never using those guys (or the tutorial should cover what they do).
Let me know if I'm wrong.