// ----------------------------------------------------------------------------
//
// Copyright (C) Columbia University, 1994. All Rights Reserved.
// Sameer A. Nene, Shree K. Nayar, Hiroshi Murase
//
// See file LICENSE for details of software license agreement.
//
// ----------------------------------------------------------------------------
//
// registry.h
//
// Author:               Sameer Nene
// Date:                 05/17/94
// Version:              1.0
// Modification History:
// Bugs:
//
// Classes:
//   Entry
//   EntryLink
//   Registry
//   Registrar
//
// Notes:
//   This header includes declarations of classes needed to maintain a
//   registry. A registry keeps track of all the persistent classes which exist
//   in the current execution instance of a program which uses persistent
//   objects. A registry is necessary to implement the dynamic loading scheme
//   for persistent objects.
//
//   Registry maintains a linked list of nodes. The node is the class Entry.
//   EntryLink is an inheritance wrapper for Entry and incorporates the link.
//   Entry inherits PeDef for convenience.
//
//   Registrar serves as a front end for manipulating the registry. A
//   persistent class wishing to be enrolled in the registry should contain an
//   instance of a Registrar.
//
// ----------------------------------------------------------------------------

#ifndef REGISTRY_INCLUDED
#define REGISTRY_INCLUDED

#ifndef PEDEF_INCLUDED
#include "pedef.h"
#endif

class EntryLink;
class Registry;
class Registrar;

class Entry : public PeDef {
  
  // Private Members

  // Entrys cannot be copied
  
  Entry(const Entry&);
  Entry& operator=(const Entry&);
  
  // Friends
  
  friend Registry;
  
  // Protected Members
  
protected:
  
  char *d_name_p;
  CreateFP d_createFunc;
  
  // Contruct and Destroy
  
  Entry(const char *name, CreateFP);
  ~Entry();
  
  // Public Members
  
public: 
  
  // Accessors
  
  const char *name() const;
  // return class name
  
  CreateFP createFunc() const;
  // return pointer to a function to create this object
  
};

class EntryLink : public Entry {
  
  // Private members
  
  EntryLink *d_next_p;
  
  // EntryLinks cannot be copied
  
  EntryLink(const EntryLink&);
  EntryLink& operator=(const EntryLink&);
  
  // Construct and Destroy
  
  EntryLink(EntryLink**, const char*, CreateFP);
  ~EntryLink();
  
  // Friends
  
  friend Registry;
  
};

class Registry : public PeDef {
  
  // Private members
  
  static EntryLink *d_head_p;
  
  static void add(const char *name, CreateFP);
  // add new entry into registry
  
  static void destroy();
  // destroy any objects created in the class
  
  // Friends
  
  friend Registrar;
  
  // Public members
  
public:
  
  static Entry* lookup(const char *name); 
  // look up an entry int the registry by name.  
  
};

class Registrar : public PeDef {

  // Private members

  static int d_count;
  
  // Registars cannot be copied
  
  Registrar(const Registrar&);
  Registrar& operator=(const Registrar&);

  // Public members

public:
  
  // Contruct and Destroy
  
  Registrar(const char *name, CreateFP);
  // add a class to the static class registry 

  ~Registrar();
  
};

#endif
