120 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			120 lines
		
	
	
		
			4.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
// Copyright (C) 2002-2018 Nikolaus Gebhardt
 | 
						|
// This file is part of the "irrKlang" library.
 | 
						|
// For conditions of distribution and use, see copyright notice in irrKlang.h
 | 
						|
 | 
						|
#ifndef __I_IRRKLANG_IREFERENCE_COUNTED_H_INCLUDED__
 | 
						|
#define __I_IRRKLANG_IREFERENCE_COUNTED_H_INCLUDED__
 | 
						|
 | 
						|
#include "ik_irrKlangTypes.h"
 | 
						|
 | 
						|
namespace irrklang
 | 
						|
{
 | 
						|
	//! Base class of most objects of the irrKlang.
 | 
						|
	/** This class provides reference counting through the methods grab() and drop().
 | 
						|
	It also is able to store a debug string for every instance of an object.
 | 
						|
	Most objects of irrKlang are derived from IRefCounted, and so they are reference counted.
 | 
						|
 | 
						|
	When you receive an object in irrKlang (for example an ISound using play2D() or
 | 
						|
	play3D()), and you no longer need the object, you have 
 | 
						|
	to call drop(). This will destroy the object, if grab() was not called
 | 
						|
	in another part of you program, because this part still needs the object.
 | 
						|
	Note, that you only don't need to call drop() for all objects you receive, it
 | 
						|
	will be explicitely noted in the documentation.
 | 
						|
 | 
						|
	A simple example:
 | 
						|
 | 
						|
	If you want to play a sound, you may want to call the method
 | 
						|
	ISoundEngine::play2D. You call
 | 
						|
	ISound* mysound = engine->play2D("foobar.mp3", false, false true);
 | 
						|
	If you no longer need the sound interface, call mysound->drop(). The 
 | 
						|
	sound may still play on after this because the engine still has a reference
 | 
						|
	to that sound, but you can be sure that it's memory will be released as soon
 | 
						|
	the sound is no longer used.
 | 
						|
 | 
						|
	If you want to add a sound source, you may want to call a method
 | 
						|
	ISoundEngine::addSoundSourceFromFile. You do this like
 | 
						|
	ISoundSource* mysource = engine->addSoundSourceFromFile("example.jpg");
 | 
						|
	You will not have to drop the pointer to the source, because
 | 
						|
	sound sources are managed by the engine (it will live as long as the sound engine) and
 | 
						|
	the documentation says so. 
 | 
						|
	*/
 | 
						|
	class IRefCounted
 | 
						|
	{
 | 
						|
	public:
 | 
						|
 | 
						|
		//! Constructor.
 | 
						|
		IRefCounted()
 | 
						|
			: ReferenceCounter(1)
 | 
						|
		{
 | 
						|
		}
 | 
						|
 | 
						|
		//! Destructor.
 | 
						|
		virtual ~IRefCounted()
 | 
						|
		{
 | 
						|
		}
 | 
						|
 | 
						|
		//! Grabs the object. Increments the reference counter by one.
 | 
						|
		//! Someone who calls grab() to an object, should later also call
 | 
						|
		//! drop() to it. If an object never gets as much drop() as grab()
 | 
						|
		//! calls, it will never be destroyed.
 | 
						|
		//! The IRefCounted class provides a basic reference counting mechanism
 | 
						|
		//! with its methods grab() and drop(). Most objects of irrklang
 | 
						|
		//! are derived from IRefCounted, and so they are reference counted.
 | 
						|
		//!
 | 
						|
		//! When you receive an object in irrKlang (for example an ISound using play2D() or
 | 
						|
		//! play3D()), and you no longer need the object, you have 
 | 
						|
		//! to call drop(). This will destroy the object, if grab() was not called
 | 
						|
		//! in another part of you program, because this part still needs the object.
 | 
						|
		//! Note, that you only don't need to call drop() for all objects you receive, it
 | 
						|
		//! will be explicitely noted in the documentation.
 | 
						|
		//! 
 | 
						|
		//! A simple example:
 | 
						|
		//! 
 | 
						|
		//! If you want to play a sound, you may want to call the method
 | 
						|
		//! ISoundEngine::play2D. You call
 | 
						|
		//! ISound* mysound = engine->play2D("foobar.mp3", false, false true);
 | 
						|
		//! If you no longer need the sound interface, call mysound->drop(). The 
 | 
						|
		//! sound may still play on after this because the engine still has a reference
 | 
						|
		//! to that sound, but you can be sure that it's memory will be released as soon
 | 
						|
		//! the sound is no longer used.
 | 
						|
		void grab() { ++ReferenceCounter; }
 | 
						|
 | 
						|
		//! When you receive an object in irrKlang (for example an ISound using play2D() or
 | 
						|
		//! play3D()), and you no longer need the object, you have 
 | 
						|
		//! to call drop(). This will destroy the object, if grab() was not called
 | 
						|
		//! in another part of you program, because this part still needs the object.
 | 
						|
		//! Note, that you only don't need to call drop() for all objects you receive, it
 | 
						|
		//! will be explicitely noted in the documentation.
 | 
						|
		//! 
 | 
						|
		//! A simple example:
 | 
						|
		//! 
 | 
						|
		//! If you want to play a sound, you may want to call the method
 | 
						|
		//! ISoundEngine::play2D. You call
 | 
						|
		//! ISound* mysound = engine->play2D("foobar.mp3", false, false true);
 | 
						|
		//! If you no longer need the sound interface, call mysound->drop(). The 
 | 
						|
		//! sound may still play on after this because the engine still has a reference
 | 
						|
		//! to that sound, but you can be sure that it's memory will be released as soon
 | 
						|
		//! the sound is no longer used.
 | 
						|
		bool drop()
 | 
						|
		{
 | 
						|
			--ReferenceCounter;
 | 
						|
 | 
						|
			if (!ReferenceCounter)
 | 
						|
			{
 | 
						|
				delete this;
 | 
						|
				return true;
 | 
						|
			}
 | 
						|
 | 
						|
			return false;
 | 
						|
		}
 | 
						|
 | 
						|
	private:
 | 
						|
 | 
						|
		ik_s32	ReferenceCounter;
 | 
						|
	};
 | 
						|
 | 
						|
} // end namespace irr
 | 
						|
 | 
						|
#endif
 | 
						|
 |