/* $Id: rtobjref.c,v 1.1.1.1 2008/10/28 13:28:21 kiesling Exp $ */

/*
  This file is part of ctalk.
  Copyright © 2005-2008  Robert Kiesling, ctalk@ctalklang.org.
  Permission is granted to copy this software provided that this copyright
  notice is included in all source code modules.

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

  This library 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
  Lesser 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., 51 Franklin St., Fifth Floor, Boston, MA 02110-1301 USA.
*/

/*
 *  Functions to handle object reference counts.  The arguments to 
 *  the function calls should use the OBJREF() macro, which is defined
 *  in object.h.
 */

#include <stdio.h>
#include <string.h>
#include "object.h"
#include "message.h"
#include "ctalk.h"

/*
 *  OBJREF_T is defined in object.h.
 */

void __refObj (OBJREF_T ref1, OBJREF_T ref2) {
  OBJECT *var;
  if (*ref1 && IS_OBJECT (*ref1)) {
    --(*ref1) -> nrefs;
    for (var = (*ref1) -> instancevars; var; var = var -> next)
      __objRefCntDec (OBJREF (var));
  }
  *ref1 = *ref2;
  ++(*ref2) -> nrefs;
  for (var = (*ref2) -> instancevars; var; var = var -> next)
    __objRefCntInc (OBJREF (var));
}

void __objRefCntInc (OBJREF_T obj_p) {
  OBJECT *vars;
  if (! *obj_p || !IS_OBJECT (*obj_p)) {
#ifdef DEBUG_INVALID_OBJ_REFS
    _warning ("__objRefCntInc: Not an object.\n");
#endif
  } else {
    (*obj_p) -> nrefs++;
    for (vars = (*obj_p) -> instancevars; vars; vars = vars -> next)
      __objRefCntInc (OBJREF (vars));
  }
}

void __objRefCntDec (OBJREF_T obj_p) {
  OBJECT *vars;
  if (! *obj_p || !IS_OBJECT (*obj_p)) {
#ifdef DEBUG_INVALID_OBJ_REFS
    _warning ("__objRefCntDec: Not an object.\n");
#endif
  } else {
    (*obj_p) -> nrefs--;
    for (vars = (*obj_p) -> instancevars; 
	 vars && IS_OBJECT(vars); 
	 vars = vars -> next)
      __objRefCntDec (OBJREF (vars));
  }
}

void __objRefCntSet (OBJREF_T obj_p, int nrefs) {
  OBJECT *vars;
  if (! *obj_p || !IS_OBJECT (*obj_p)) {
#ifdef DEBUG_INVALID_OBJ_REFS
    _warning ("__objRefCntSet: Not an object.\n");
#endif
  } else {
    (*obj_p) -> nrefs = nrefs;
    for (vars = (*obj_p) -> instancevars; vars; vars = vars -> next)
      __objRefCntSet (OBJREF (vars), nrefs);
  }
}

