Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Different implementations of a C header file

Tags:

c

header

How can I add multiple implementations to this header file:

MoveAgent.h

#ifndef _GAMEAGENT_
#define _GAMEAGENT_

#include "Defs.h"
#include "GameModel.h"

MoveDirection takeDirection(GameState *gs);

#endif _GAMEAGENT_

MoveAgent.c: Let's say that I have an implementation that will return a random move

MoveDirection takeDirection(GameState *gs) {    
    MoveDirection dir = DIR_NONE;       
    while (dir == DIR_NONE) {
        int index = arc4random() % gs->moves_total;     
        MoveDirection tempDir = gs->moves[index];       
        if (tempDir != oppDir(gs->car.direction)) {
            dir = tempDir;
        }
    }
    return dir;
}

What is practical way of having multiple implementations of that function?

As you might guess, I'm a Java programmer trying to make a basic game to learn C, so I'm trying to do this to simulate a Java interface.

Any ideas?

like image 248
David Robles Avatar asked Dec 08 '10 05:12

David Robles


1 Answers

This maybe jumping in a bit too much at the deep end, but:

You might be after a pointer to function plus several implementations of functions with different names that do the task.

MoveAgent.h

extern MoveDirection (*takeDirection)(GameState *gs);

MoveAgent.c

MoveDirection takeDirectionRandom(GameState *gs)
{
    ...
}

MoveDirection takeDirectionSpiral(GameState *gs)
{
    ...
}

Mover.c

#include "MoveAgent.h"

// Default move is random
MoveDirection (*takeDirection)(GameState *gs) = takeDirectionRandom;

void setRandomMover(void)
{
    takeDirection = takeDirectionRandom;
}

void setSpiralMover(void)
{
    takeDirection = takeDirectionSpiral;
}

void mover(GameState *gs)
{
    ...;
    MoveDirection dir = takeDirection(gs);
    ...;
}

So, somewhere along the line, you call one of the setXxxxxMover() functions, and thereafter you move using the mechanism set by the last of the two functions called.

You can also invoke the function using the long-hand notation:

    MoveDirection dir = (*takeDirection)(gs);

Once upon a very long time ago (1980s and earlier), this notation was necessary. I still like it because it makes it clear (to me) that it is a pointer-to-function that is being used.

like image 111
Jonathan Leffler Avatar answered Oct 17 '22 12:10

Jonathan Leffler