Undefined reference

Hello,
I´m really a beginner on C++, I just started using it because I'm reading "Programming Game AI by Examples" book, but I have some problem compiling the examples. I wonder if some one can help me with this.
I have this error:

"Buckland_Chapter2-State Machines\WestWorldWithMessaging\MessageDispatcher.o:MessageDispatcher.cpp|| undefined reference to `CrudeTimer::Instance()'|"
1
2
3
4
5
6
7
8
9
#include "CrudeTimer.h"


CrudeTimer* CrudeTimer::Instance()
{
  static CrudeTimer instance;

  return &instance;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#ifndef CRUDETIMER_H
#define CRUDETIMER_H
//------------------------------------------------------------------------
//
//  Name:   CrudeTimer.h
//
//  Desc:   timer to measure time in seconds
//
//  Author: Mat Buckland 2002 (fup@ai-junkie.com)
//
//------------------------------------------------------------------------

//this library must be included
#pragma comment(lib, "winmm.lib")

#include <windows.h>



#define Clock CrudeTimer::Instance()

class CrudeTimer
{
private:

  //set to the time (in seconds) when class is instantiated
  double m_dStartTime;

  //set the start time
  CrudeTimer(){m_dStartTime = timeGetTime() * 0.001;}

  //copy ctor and assignment should be private
  CrudeTimer(const CrudeTimer&);
  CrudeTimer& operator=(const CrudeTimer&);

public:

  static CrudeTimer* Instance();

  //returns how much time has elapsed since the timer was started
  double GetCurrentTime(){return timeGetTime() * 0.001 - m_dStartTime;}

};







#endif

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#include "MessageDispatcher.h"
#include "BaseGameEntity.h"
#include "Time/CrudeTimer.h"
#include "EntityManager.h"
#include "Locations.h"
#include "MessageTypes.h"
#include "EntityNames.h"

#include <iostream>
using std::cout;

using std::set;

#ifdef TEXTOUTPUT
#include <fstream>
extern std::ofstream os;
#define cout os
#endif



//------------------------------ Instance -------------------------------------

MessageDispatcher* MessageDispatcher::Instance()
{
  static MessageDispatcher instance;

  return &instance;
}


//----------------------------- Dispatch ---------------------------------
//
//  see description in header
//------------------------------------------------------------------------
void MessageDispatcher::Discharge(BaseGameEntity* pReceiver,
                                  const Telegram& telegram)
{
  if (!pReceiver->HandleMessage(telegram))
  {
    //telegram could not be handled
    cout << "Message not handled";
  }
}

//---------------------------- DispatchMessage ---------------------------
//
//  given a message, a receiver, a sender and any time delay , this function
//  routes the message to the correct agent (if no delay) or stores
//  in the message queue to be dispatched at the correct time
//------------------------------------------------------------------------
void MessageDispatcher::DispatchMessage(double  delay,
                                        int    sender,
                                        int    receiver,
                                        int    msg,
                                        void*  ExtraInfo)
{
  SetTextColor(BACKGROUND_RED|FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE);

  //get pointers to the sender and receiver
  BaseGameEntity* pSender   = EntityMgr->GetEntityFromID(sender);
  BaseGameEntity* pReceiver = EntityMgr->GetEntityFromID(receiver);

  //make sure the receiver is valid
  if (pReceiver == NULL)
  {
    cout << "\nWarning! No Receiver with ID of " << receiver << " found";

    return;
  }
  GetCurrentTime;
  //create the telegram
  Telegram telegram(0, sender, receiver, msg, ExtraInfo);

  //if there is no delay, route telegram immediately
  if (delay <= 0.0f)
  {
    cout << "\nInstant telegram dispatched at time: " << Clock->GetCurrentTime()
         << " by " << GetNameOfEntity(pSender->ID()) << " for " << GetNameOfEntity(pReceiver->ID())
         << ". Msg is "<< MsgToStr(msg);

    //send the telegram to the recipient
    Discharge(pReceiver, telegram);
  }

  //else calculate the time when the telegram should be dispatched
  else
  {
    double CurrentTime = Clock->GetCurrentTime();

    telegram.DispatchTime = CurrentTime + delay;

    //and put it in the queue
    PriorityQ.insert(telegram);

    cout << "\nDelayed telegram from " << GetNameOfEntity(pSender->ID()) << " recorded at time "
            << Clock->GetCurrentTime() << " for " << GetNameOfEntity(pReceiver->ID())
            << ". Msg is "<< MsgToStr(msg);

  }
}


//---------------------- DispatchDelayedMessages -------------------------
//
//  This function dispatches any telegrams with a timestamp that has
//  expired. Any dispatched telegrams are removed from the queue
//------------------------------------------------------------------------
void MessageDispatcher::DispatchDelayedMessages()
{
  SetTextColor(BACKGROUND_RED|FOREGROUND_RED|FOREGROUND_GREEN|FOREGROUND_BLUE);

  //get current time
  double CurrentTime = Clock->GetCurrentTime();

  //now peek at the queue to see if any telegrams need dispatching.
  //remove all telegrams from the front of the queue that have gone
  //past their sell by date
  while( !PriorityQ.empty() &&
         (PriorityQ.begin()->DispatchTime < CurrentTime) &&
         (PriorityQ.begin()->DispatchTime > 0) )
  {
    //read the telegram from the front of the queue
    const Telegram& telegram = *PriorityQ.begin();

    //find the recipient
    BaseGameEntity* pReceiver = EntityMgr->GetEntityFromID(telegram.Receiver);

    cout << "\nQueued telegram ready for dispatch: Sent to "
         << GetNameOfEntity(pReceiver->ID()) << ". Msg is " << MsgToStr(telegram.Msg);

    //send the telegram to the recipient
    Discharge(pReceiver, telegram);

    //remove it from the queue
    PriorityQ.erase(PriorityQ.begin());
  }
}



I'm using Code:Block with GNU GCC compiler. the code of this examples can be found on http://www.jblearning.com/Catalog/9781556220784/student/.

Thank you in advance.
Javier.
PD: Sorry about my English writing skills-
Last edited on
You are missing a file that has the implementation of CrudeTimer, probably CrudeTimer.cpp.

But you can do without it. Add this code to CrudeTimer.h.
1
2
3
4
5
inline CrudeTimer* CrudeTimer::Instance()
{
    static CrudeTimer timer;
    return &timer;
}
Last edited on
Thanks kbw, but the first code snippet is CrudeTimer.cpp.
I assume that maybe is some problem with the wrong compiler? Because I can't compile any of the examples, with different errors. Or maybe I'm setting paths and libs wrong way...
Last edited on
Sorry, I missed that.

You need to check you are linking with it.
Thanks, I really don't know how to do that, on code::block I add the root commons directory at "Search Directories"->"Linker"
Maybe the problem is that the source is intend to be for VS8 ??
Last edited on
Maybe related to this other error?
obj\Debug\VS8 projects\Buckland_Chapter2-State Machines\WestWorldWithMessaging\MessageDispatcher.o:MessageDispatcher.cpp:(.text$_ZN10CrudeTimer12GetTickCountEv[CrudeTimer::GetTickCount()]+0x7)||undefined reference to `timeGetTime@0'|


I assume that tis "timeGetTime" is from #include <windows.h>
Last edited on
I Just Manage it! But I don't understand any way....
At the MessageDispatcher.cpp every time it use Clock->GetCurrentTime() I change it to only this GetCurrentTime() and it works like a charm...
If some one want to explain me why it is I will appreciate it.
I don't understand why that works.
Topic archived. No new replies allowed.