| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256 |
- /*
- ** Command & Conquer Generals(tm)
- ** Copyright 2025 Electronic Arts Inc.
- **
- ** 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 3 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, see <http://www.gnu.org/licenses/>.
- */
- /***********************************************************************************************
- *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
- ***********************************************************************************************
- * *
- * Project Name : Commando / G Library *
- * *
- * $Archive:: /Commando/Code/wwlib/refcount.h $*
- * *
- * $Author:: Greg_h $*
- * *
- * $Modtime:: 8/28/01 9:23a $*
- * *
- * $Revision:: 22 $*
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #if _MSC_VER >= 1000
- #pragma once
- #endif // _MSC_VER >= 1000
-
- #ifndef REFCOUNT_H
- #define REFCOUNT_H
- #ifndef ALWAYS_H
- #include "always.h"
- #endif
- #ifndef LISTNODE_H
- #include "listnode.h"
- #endif
- class RefCountClass;
- #ifndef NDEBUG
- struct ActiveRefStruct
- {
- char * File;
- int Line;
- };
- #define NEW_REF( C, P ) ( (C*)RefCountClass::Set_Ref_Owner( W3DNEW C P, __FILE__, __LINE__ ) )
- #define SET_REF_OWNER( P ) ( RefCountClass::Set_Ref_Owner( P, __FILE__, __LINE__ ) )
- #else
- #define NEW_REF( C, P ) ( W3DNEW C P )
- #define SET_REF_OWNER( P ) P
- #endif
- /*
- ** Macros for setting and releasing a pointer to a ref counted object.
- ** If you have a member variable which can be pointed at a ref counted object and
- ** you want to point it at some object. You must release whatever it currently points at,
- ** point it at the new object, and add-ref the new object (if its not null...)
- */
- #define REF_PTR_SET(dst,src) { if (src) (src)->Add_Ref(); if (dst) (dst)->Release_Ref(); (dst) = (src); }
- #define REF_PTR_RELEASE(x) { if (x) x->Release_Ref(); x = NULL; }
- /*
- ** Rules regarding the use of RefCountClass
- **
- ** If you call a function that returns a pointer to a RefCountClass,
- ** you MUST Release_Ref() it
- **
- ** If a functions calls you, and you return a pointer to a RefCountClass,
- ** you MUST Add_Ref() it
- **
- ** If you call a function and pass a pointer to a RefCountClass,
- ** you DO NOT Add_Ref() it
- **
- ** If a function calls you, and passes you a pointer to a RefCountClass,
- ** if you keep the pointer, you MUST Add_Ref() and Release_Ref() it
- ** otherwise, you DO NOT Add_Ref() or Release_Ref() it
- **
- */
- typedef DataNode<RefCountClass *> RefCountNodeClass;
- typedef List<RefCountNodeClass *> RefCountListClass;
- class RefCountClass
- {
- public:
-
- RefCountClass(void) :
- NumRefs(1)
- #ifndef NDEBUG
- ,ActiveRefNode(this)
- #endif
- {
- #ifndef NDEBUG
- Add_Active_Ref(this);
- Inc_Total_Refs(this);
- #endif
- }
- RefCountClass(const RefCountClass & ) :
- NumRefs(1)
- #ifndef NDEBUG
- ,ActiveRefNode(this)
- #endif
- {
- #ifndef NDEBUG
- Add_Active_Ref(this);
- Inc_Total_Refs(this);
- #endif
- }
- /*
- ** Add_Ref, call this function if you are going to keep a pointer
- ** to this object.
- */
- #ifdef NDEBUG
- virtual void Add_Ref(void) { NumRefs++; }
- #else
- virtual void Add_Ref(void);
- #endif
- /*
- ** Release_Ref, call this function when you no longer need the pointer
- ** to this object.
- */
- virtual void Release_Ref(void) {
- #ifndef NDEBUG
- Dec_Total_Refs(this);
- #endif
- NumRefs--;
- assert(NumRefs >= 0);
- if (NumRefs == 0) Delete_This();
- }
- /*
- ** Check the number of references to this object.
- */
- int Num_Refs(void) { return NumRefs; }
- /*
- ** Delete_This - this function will be called when the object is being
- ** destroyed as a result of its last reference being released. Its
- ** job is to actually destroy the object.
- */
- virtual void Delete_This(void) { delete this; }
- /*
- ** Total_Refs - This static function can be used to get the total number
- ** of references that have been made. Once you've released all of your
- ** objects, it should go to zero.
- */
- static int Total_Refs(void) { return TotalRefs; }
- protected:
- /*
- ** Destructor, user should not have access to this...
- */
- virtual ~RefCountClass(void)
- {
- #ifndef NDEBUG
- Remove_Active_Ref(this);
- #endif
- assert(NumRefs == 0);
- }
- private:
- /*
- ** Current reference count of this object
- */
- int NumRefs;
- /*
- ** Sum of all references to RefCountClass's. Should equal zero after
- ** everything has been released.
- */
- static int TotalRefs;
- /*
- ** increments the total reference count
- */
- static void Inc_Total_Refs(RefCountClass *);
-
- /*
- ** decrements the total reference count
- */
- static void Dec_Total_Refs(RefCountClass *);
- public:
-
- #ifndef NDEBUG // Debugging stuff
- /*
- ** Node in the Active Refs List
- */
- RefCountNodeClass ActiveRefNode;
-
- /*
- ** Auxiliary Active Ref Data
- */
- ActiveRefStruct ActiveRefInfo;
- /*
- ** List of the active referenced objects
- */
- static RefCountListClass ActiveRefList;
-
- /*
- ** Adds the ref obj pointer to the active ref list
- */
- static RefCountClass * Add_Active_Ref(RefCountClass *obj);
- /*
- ** Updates the owner file/line for the given ref obj in the active ref list
- */
- static RefCountClass * Set_Ref_Owner(RefCountClass *obj,char * file,int line);
- /*
- ** Remove the ref obj from the active ref list
- */
- static void Remove_Active_Ref(RefCountClass * obj);
- /*
- ** Confirm the active ref object using the pointer of the refbaseclass as a search key
- */
- static bool Validate_Active_Ref(RefCountClass * obj);
- #endif
- };
- #endif
|