Best Practice re: functions

Discuss programming in the QuakeC language.
Post Reply
OneManClan
Posts: 247
Joined: Sat Feb 28, 2009 2:38 pm
Contact:

Best Practice re: functions

Post by OneManClan »

[EDIT: I've changed the subject from "Are fewer functions better?" to "Best Practice re: functions", because whilst I do present a specific example, I'm more interested in the general concept of 'best practice' for quakec]

Hey people,

From what I've seen looking at other people's QuakeC, if you have Function_1 which does something temporarily, the 'standard practice' is to make a timer entity, which calls Function_2 to undo what Function_1 did.

Q: Is there a reason why no-one does it like this?:

Code: Select all

// EXAMPLE FUNCTION
// This function is first called when a player is stunned, and then calls itself again, to remove the stun
void() Stun =
{
	local entity e;


	if (self.classname == "stun_timer")
	{
		// if we're here, 'self' is the  timer whose job it is to undo the stunned state
		e = self; // e is now the timer entity
		self = self.owner; // self is now the stunned player

		// [Code to remove stun effect]

		remove(e); // remove the timer, sequence complete.

	}
	else
	{
		// if we're here, 'self' is the player who is about to get stunned


		// [Code to stun the player]
		
		e = spawn();
		e.classname = "stun_timer";
		e.owner = self; // the player
		e.think = Stun; 
		e.nextthink = time + 10;
	}
};
I like the idea of an 'all in one' function where everything is included, but am wondering if this is 'ok' or not. Not in the sense of 'will it work', but in the sense of is it 'optimal', is it 'what the pros do', ie .. What is the 'best programming practice'.?

thanks

OneManClan
ps If someone can think of a better/clearer way to describe the "subject" of this post, please let me know
Last edited by OneManClan on Tue Mar 25, 2014 3:35 pm, edited 1 time in total.
frag.machine
Posts: 2126
Joined: Sat Nov 25, 2006 1:49 pm

Re: Are fewer functions better?

Post by frag.machine »

The problem with all-in-one code is when you want to debug it or when you want to reuse part of it somewhere else. If the function is small and simple enough (like the stun effect you posted) it's no big deal, but try to do the same to say, monster spawning or behavior and you'll see what I mean. QuakeC is hard enough to debug without adding non necessary complexity.
I know FrikaC made a cgi-bin version of the quakec interpreter once and wrote part of his website in QuakeC :) (LordHavoc)
Spike
Posts: 2914
Joined: Fri Nov 05, 2004 3:12 am
Location: UK
Contact:

Re: Are fewer functions better?

Post by Spike »

if you're going after less code:

Code: Select all

if (fork(10))
{
  if (self)
  {
    //[code to remove stun effect]
  }
  abort();
}
//[code to apply stun effect]
yes, this is specific to fte servers.
fork is fun. call it once, and it'll return _twice_ (forks the current coprocedure, unlike posix - think cooperative multithreading like win16 had). call abort at the end to destroy the coprocedure.
the only globals which are preserved are self and other, and even those get reset to world if the entity got respawned in the interim, hence the self check (locals+args are preserved and unchecked, they won't reset to world if the entity they refer to got respawned). You can still return to the caller, but you really ought to call abort instead...

the big issue with the code above is that there's no way to reapply the stun properly. your timer will fire after 10 seconds, even if the player got stunned twice during that period. consider the following timing...
0: stunned1
9: stunned2
10: unstunned1
19: end 9 seconds of not being stunned when he should have been, or that might also break the player entity that got unstunned when he was already not stunned.


the thing is though, its not fewer functions that is good, but less random code that needs to be read to be understood. using extra functions instead of huge uberfunctions that do everything including washing the kitchen sink just means that you have a lot of code to read through in order to find what you're actually looking for.
extra functions help give actual names to sections of your code.
basically, the aim is to reduce the glue code in order to give more focus to the code that is actually worthwhile.
you can alternatively use preprocessor to spawn your timer for you if you so desire. that would have the same sort of effect.
OneManClan
Posts: 247
Joined: Sat Feb 28, 2009 2:38 pm
Contact:

Re: Are fewer functions better?

Post by OneManClan »

Thanks for the feedback guys.

It's not so much 'smaller code' /fewer functions I'm concerned about; its more that I don't know what the 'best practice' is when it comes to qc (I've changed the subject accordingly).

Someone on #qc mentioned a while ago that there was some version of quake (original NetQuake?) which was considered 'the standard' when it comes to 'how the pros do it'. But I'm using heaps of new language features of FTEQCC, so I'm not even sure if the 'old ways' are still the 'best ways'.

ps Spike, thanks for the fork info.. will investigate further..
pps Or should I? :?
ceriux
Posts: 2230
Joined: Sat Sep 06, 2008 3:30 pm
Location: Indiana, USA

Re: Best Practice re: functions

Post by ceriux »

idk maybe its just opinionated? if it works and you can read it. what does it matter? i personally like to make my qc as small as possible when i can. but i also like to use seperate functions for seperate things, that way i can reuse else where.
Post Reply