Difference between revisions of "Talk:Writing Modules In C"

From ASSS Wiki
Jump to: navigation, search
(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.