/*
    main.m  Main program to cheezmud.
    Copyright (C) 1995  David Flater.

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

/*  main.m    Main program to cheezmud.
 *  DWF 1/26/95
 */

#include "cheezmud.h"

/* Collection of all mud objects */
id world;

/* Time of last heartbeat */
struct timeval lastheartbeat;

void
reaper ()
{
  id t;
  while ((t = pop_death ())) {
    [world remove: t];
    [t free];
  }
}

void
do_heartbeats ()
{
  if (timesincelastheartbeat () >= heartbeat_microseconds)
  {
    /*  This must be done in two passes to avoid extremely bad luck. */
    /*  Pass 1:  send heartbeat, don't free anything */
    /*  Pass 2:  free the dead ones */
    [world elementsPerform: @selector(heartbeat)];
    reaper ();

    /*  This gives more accurate heartbeats than simply calling gettimeofday. */
    lastheartbeat.tv_usec += heartbeat_microseconds;
    while (lastheartbeat.tv_usec > 1000000) {
      lastheartbeat.tv_sec++;
      lastheartbeat.tv_usec -= 1000000;
    }

    /*  If we fall behind, do not play catch-up.  Skip a beat instead. */
    if (timesincelastheartbeat () >= heartbeat_microseconds)
      gettimeofday (&lastheartbeat, NULL);
  }
}

int
main (int argc, char **argv)
{
  srandom (time(NULL));
  powerup ();
  world = [OrdCltn new];
  genesis ();
  gettimeofday (&lastheartbeat, NULL);
  cheezlog ("Mud started");
  while (1)
  {
    /*  The heartbeat is invoked from within service_cons. */
    service_cons ();
    wait_for_activity ();
  }
}