COMMON: Add DisposablePtr<T>, which replaces many repeated implementations of a dispose flag.

This commit is contained in:
Christoph Mallon 2011-08-06 16:30:52 +02:00
parent 2f23ff72c1
commit a5a8833c05
16 changed files with 81 additions and 107 deletions

@ -93,7 +93,7 @@ SeekableAudioStream *SeekableAudioStream::openStreamFile(const Common::String &b
#pragma mark -
LoopingAudioStream::LoopingAudioStream(RewindableAudioStream *stream, uint loops, DisposeAfterUse::Flag disposeAfterUse)
: _parent(stream), _disposeAfterUse(disposeAfterUse), _loops(loops), _completeIterations(0) {
: _parent(stream, disposeAfterUse), _loops(loops), _completeIterations(0) {
assert(stream);
if (!stream->rewind()) {
@ -102,11 +102,6 @@ LoopingAudioStream::LoopingAudioStream(RewindableAudioStream *stream, uint loops
}
}
LoopingAudioStream::~LoopingAudioStream() {
if (_disposeAfterUse == DisposeAfterUse::YES)
delete _parent;
}
int LoopingAudioStream::readBuffer(int16 *buffer, const int numSamples) {
if ((_loops && _completeIterations == _loops) || !numSamples)
return 0;
@ -169,7 +164,7 @@ SubLoopingAudioStream::SubLoopingAudioStream(SeekableAudioStream *stream,
const Timestamp loopStart,
const Timestamp loopEnd,
DisposeAfterUse::Flag disposeAfterUse)
: _parent(stream), _disposeAfterUse(disposeAfterUse), _loops(loops),
: _parent(stream, disposeAfterUse), _loops(loops),
_pos(0, getRate() * (isStereo() ? 2 : 1)),
_loopStart(convertTimeToStreamPos(loopStart, getRate(), isStereo())),
_loopEnd(convertTimeToStreamPos(loopEnd, getRate(), isStereo())),
@ -180,11 +175,6 @@ SubLoopingAudioStream::SubLoopingAudioStream(SeekableAudioStream *stream,
_done = true;
}
SubLoopingAudioStream::~SubLoopingAudioStream() {
if (_disposeAfterUse == DisposeAfterUse::YES)
delete _parent;
}
int SubLoopingAudioStream::readBuffer(int16 *buffer, const int numSamples) {
if (_done)
return 0;
@ -225,7 +215,7 @@ int SubLoopingAudioStream::readBuffer(int16 *buffer, const int numSamples) {
#pragma mark -
SubSeekableAudioStream::SubSeekableAudioStream(SeekableAudioStream *parent, const Timestamp start, const Timestamp end, DisposeAfterUse::Flag disposeAfterUse)
: _parent(parent), _disposeAfterUse(disposeAfterUse),
: _parent(parent, disposeAfterUse),
_start(convertTimeToStreamPos(start, getRate(), isStereo())),
_pos(0, getRate() * (isStereo() ? 2 : 1)),
_length(convertTimeToStreamPos(end, getRate(), isStereo()) - _start) {
@ -234,11 +224,6 @@ SubSeekableAudioStream::SubSeekableAudioStream(SeekableAudioStream *parent, cons
_parent->seek(_start);
}
SubSeekableAudioStream::~SubSeekableAudioStream() {
if (_disposeAfterUse)
delete _parent;
}
int SubSeekableAudioStream::readBuffer(int16 *buffer, const int numSamples) {
int framesLeft = MIN(_length.frameDiff(_pos), numSamples);
int framesRead = _parent->readBuffer(buffer, framesLeft);

@ -23,6 +23,7 @@
#ifndef SOUND_AUDIOSTREAM_H
#define SOUND_AUDIOSTREAM_H
#include "common/ptr.h"
#include "common/scummsys.h"
#include "common/str.h"
#include "common/types.h"
@ -114,7 +115,6 @@ public:
* @param disposeAfterUse Destroy the stream after the LoopingAudioStream has finished playback.
*/
LoopingAudioStream(RewindableAudioStream *stream, uint loops, DisposeAfterUse::Flag disposeAfterUse = DisposeAfterUse::YES);
~LoopingAudioStream();
int readBuffer(int16 *buffer, const int numSamples);
bool endOfData() const;
@ -129,8 +129,7 @@ public:
*/
uint getCompleteIterations() const { return _completeIterations; }
private:
RewindableAudioStream *_parent;
DisposeAfterUse::Flag _disposeAfterUse;
Common::DisposablePtr<RewindableAudioStream> _parent;
uint _loops;
uint _completeIterations;
@ -246,7 +245,6 @@ public:
const Timestamp loopStart,
const Timestamp loopEnd,
DisposeAfterUse::Flag disposeAfterUse = DisposeAfterUse::YES);
~SubLoopingAudioStream();
int readBuffer(int16 *buffer, const int numSamples);
bool endOfData() const { return _done; }
@ -254,8 +252,7 @@ public:
bool isStereo() const { return _parent->isStereo(); }
int getRate() const { return _parent->getRate(); }
private:
SeekableAudioStream *_parent;
DisposeAfterUse::Flag _disposeAfterUse;
Common::DisposablePtr<SeekableAudioStream> _parent;
uint _loops;
Timestamp _pos;
@ -283,7 +280,6 @@ public:
* @param disposeAfterUse Whether the parent stream object should be destroyed on destruction of the SubSeekableAudioStream.
*/
SubSeekableAudioStream(SeekableAudioStream *parent, const Timestamp start, const Timestamp end, DisposeAfterUse::Flag disposeAfterUse = DisposeAfterUse::YES);
~SubSeekableAudioStream();
int readBuffer(int16 *buffer, const int numSamples);
@ -297,8 +293,7 @@ public:
Timestamp getLength() const { return _length; }
private:
SeekableAudioStream *_parent;
DisposeAfterUse::Flag _disposeAfterUse;
Common::DisposablePtr<SeekableAudioStream> _parent;
const Timestamp _start;
const Timestamp _length;

@ -41,8 +41,7 @@ namespace Audio {
// <http://wiki.multimedia.cx/index.php?title=Microsoft_IMA_ADPCM>.
ADPCMStream::ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign)
: _stream(stream),
_disposeAfterUse(disposeAfterUse),
: _stream(stream, disposeAfterUse),
_startpos(stream->pos()),
_endpos(_startpos + size),
_channels(channels),
@ -52,11 +51,6 @@ ADPCMStream::ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Fl
reset();
}
ADPCMStream::~ADPCMStream() {
if (_disposeAfterUse == DisposeAfterUse::YES)
delete _stream;
}
void ADPCMStream::reset() {
memset(&_status, 0, sizeof(_status));
_blockPos[0] = _blockPos[1] = _blockAlign; // To make sure first header is read

@ -33,6 +33,7 @@
#include "audio/audiostream.h"
#include "common/endian.h"
#include "common/ptr.h"
#include "common/stream.h"
#include "common/textconsole.h"
@ -41,8 +42,7 @@ namespace Audio {
class ADPCMStream : public RewindableAudioStream {
protected:
Common::SeekableReadStream *_stream;
const DisposeAfterUse::Flag _disposeAfterUse;
Common::DisposablePtr<Common::SeekableReadStream> _stream;
const int32 _startpos;
const int32 _endpos;
const int _channels;
@ -62,7 +62,6 @@ protected:
public:
ADPCMStream(Common::SeekableReadStream *stream, DisposeAfterUse::Flag disposeAfterUse, uint32 size, int rate, int channels, uint32 blockAlign);
~ADPCMStream();
virtual bool endOfData() const { return (_stream->eos() || _stream->pos() >= _endpos); }
virtual bool isStereo() const { return _channels == 2; }

@ -25,6 +25,7 @@
#ifdef USE_MAD
#include "common/debug.h"
#include "common/ptr.h"
#include "common/stream.h"
#include "common/textconsole.h"
#include "common/util.h"
@ -52,8 +53,7 @@ protected:
MP3_STATE_EOS // end of data reached (may need to loop)
};
Common::SeekableReadStream *_inStream;
DisposeAfterUse::Flag _disposeAfterUse;
Common::DisposablePtr<Common::SeekableReadStream> _inStream;
uint _posInFrame;
State _state;
@ -95,8 +95,7 @@ protected:
};
MP3Stream::MP3Stream(Common::SeekableReadStream *inStream, DisposeAfterUse::Flag dispose) :
_inStream(inStream),
_disposeAfterUse(dispose),
_inStream(inStream, dispose),
_posInFrame(0),
_state(MP3_STATE_INIT),
_length(0, 1000),
@ -134,9 +133,6 @@ MP3Stream::MP3Stream(Common::SeekableReadStream *inStream, DisposeAfterUse::Flag
MP3Stream::~MP3Stream() {
deinitStream();
if (_disposeAfterUse == DisposeAfterUse::YES)
delete _inStream;
}
void MP3Stream::decodeMP3Data() {

@ -51,7 +51,7 @@ template<bool is16Bit, bool isUnsigned, bool isLE>
class RawStream : public SeekableAudioStream {
public:
RawStream(int rate, bool stereo, DisposeAfterUse::Flag disposeStream, Common::SeekableReadStream *stream, const RawStreamBlockList &blocks)
: _rate(rate), _isStereo(stereo), _playtime(0, rate), _stream(stream), _disposeAfterUse(disposeStream), _blocks(blocks), _curBlock(_blocks.begin()), _blockLeft(0), _buffer(0) {
: _rate(rate), _isStereo(stereo), _playtime(0, rate), _stream(stream, disposeStream), _blocks(blocks), _curBlock(_blocks.begin()), _blockLeft(0), _buffer(0) {
assert(_blocks.size() > 0);
@ -82,9 +82,6 @@ public:
}
~RawStream() {
if (_disposeAfterUse == DisposeAfterUse::YES)
delete _stream;
delete[] _buffer;
}
@ -98,15 +95,14 @@ public:
bool seek(const Timestamp &where);
private:
const int _rate; ///< Sample rate of stream
const bool _isStereo; ///< Whether this is an stereo stream
Timestamp _playtime; ///< Calculated total play time
Common::SeekableReadStream *_stream; ///< Stream to read data from
const DisposeAfterUse::Flag _disposeAfterUse; ///< Indicates whether the stream object should be deleted when this RawStream is destructed
const RawStreamBlockList _blocks; ///< Audio block list
const int _rate; ///< Sample rate of stream
const bool _isStereo; ///< Whether this is an stereo stream
Timestamp _playtime; ///< Calculated total play time
Common::DisposablePtr<Common::SeekableReadStream> _stream; ///< Stream to read data from
const RawStreamBlockList _blocks; ///< Audio block list
RawStreamBlockList::const_iterator _curBlock; ///< Current audio block number
int32 _blockLeft; ///< How many bytes are still left in the current block
RawStreamBlockList::const_iterator _curBlock; ///< Current audio block number
int32 _blockLeft; ///< How many bytes are still left in the current block
/**
* Advance one block in the stream in case

@ -29,6 +29,7 @@
#ifdef USE_VORBIS
#include "common/ptr.h"
#include "common/stream.h"
#include "common/textconsole.h"
#include "common/util.h"
@ -89,8 +90,7 @@ static ov_callbacks g_stream_wrap = {
class VorbisStream : public SeekableAudioStream {
protected:
Common::SeekableReadStream *_inStream;
DisposeAfterUse::Flag _disposeAfterUse;
Common::DisposablePtr<Common::SeekableReadStream> _inStream;
bool _isStereo;
int _rate;
@ -121,8 +121,7 @@ protected:
};
VorbisStream::VorbisStream(Common::SeekableReadStream *inStream, DisposeAfterUse::Flag dispose) :
_inStream(inStream),
_disposeAfterUse(dispose),
_inStream(inStream, dispose),
_length(0, 1000),
_bufferEnd(_buffer + ARRAYSIZE(_buffer)) {
@ -150,8 +149,6 @@ VorbisStream::VorbisStream(Common::SeekableReadStream *inStream, DisposeAfterUse
VorbisStream::~VorbisStream() {
ov_clear(&_ovFile);
if (_disposeAfterUse == DisposeAfterUse::YES)
delete _inStream;
}
int VorbisStream::readBuffer(int16 *buffer, const int numSamples) {

@ -163,9 +163,8 @@ private:
uint32 _pauseStartTime;
uint32 _pauseTime;
DisposeAfterUse::Flag _autofreeStream;
RateConverter *_converter;
AudioStream *_stream;
Common::DisposablePtr<AudioStream> _stream;
};
#pragma mark -
@ -492,8 +491,8 @@ Channel::Channel(Mixer *mixer, Mixer::SoundType type, AudioStream *stream,
DisposeAfterUse::Flag autofreeStream, bool reverseStereo, int id, bool permanent)
: _type(type), _mixer(mixer), _id(id), _permanent(permanent), _volume(Mixer::kMaxChannelVolume),
_balance(0), _pauseLevel(0), _samplesConsumed(0), _samplesDecoded(0), _mixerTimeStamp(0),
_pauseStartTime(0), _pauseTime(0), _autofreeStream(autofreeStream), _converter(0),
_stream(stream) {
_pauseStartTime(0), _pauseTime(0), _converter(0),
_stream(stream, autofreeStream) {
assert(mixer);
assert(stream);
@ -503,8 +502,6 @@ Channel::Channel(Mixer *mixer, Mixer::SoundType type, AudioStream *stream,
Channel::~Channel() {
delete _converter;
if (_autofreeStream == DisposeAfterUse::YES)
delete _stream;
}
void Channel::setVolume(const byte volume) {

@ -179,8 +179,7 @@ bool Mp3PspStream::loadStartAudioModule(const char *modname, int partition){
// TODO: make parallel function for unloading the 1.50 modules
Mp3PspStream::Mp3PspStream(Common::SeekableReadStream *inStream, DisposeAfterUse::Flag dispose) :
_inStream(inStream),
_disposeAfterUse(dispose),
_inStream(inStream, dispose),
_pcmLength(0),
_posInFrame(0),
_state(MP3_STATE_INIT),
@ -274,9 +273,6 @@ Mp3PspStream::~Mp3PspStream() {
deinitStream();
releaseStreamME(); // free the memory used for this stream
if (_disposeAfterUse == DisposeAfterUse::YES)
delete _inStream;
}
void Mp3PspStream::deinitStream() {

@ -23,6 +23,7 @@
#ifndef SOUND_MP3_PSP_H
#define SOUND_MP3_PSP_H
#include "common/ptr.h"
#include "common/types.h"
#include "common/scummsys.h"
@ -48,8 +49,7 @@ protected:
byte _codecInBuffer[3072] __attribute__((aligned(64))); // the codec always needs alignment
unsigned long _codecParams[65]__attribute__((aligned(64))); // TODO: change to struct
Common::SeekableReadStream *_inStream;
DisposeAfterUse::Flag _disposeAfterUse;
Common::DisposablePtr<Common::SeekableReadStream> _inStream;
uint32 _pcmLength; // how many pcm samples we have for this type of file (x2 this for stereo)

@ -24,6 +24,7 @@
#include "common/scummsys.h"
#include "common/noncopyable.h"
#include "common/types.h"
namespace Common {
@ -273,6 +274,41 @@ private:
PointerType _pointer;
};
template<typename T>
class DisposablePtr : NonCopyable {
public:
typedef T ValueType;
typedef T *PointerType;
typedef T &ReferenceType;
explicit DisposablePtr(PointerType o, DisposeAfterUse::Flag dispose) : _pointer(o), _dispose(dispose) {}
~DisposablePtr() {
if (_dispose) delete _pointer;
}
ReferenceType operator*() const { return *_pointer; }
PointerType operator->() const { return _pointer; }
/**
* Implicit conversion operator to bool for convenience, to make
* checks like "if (scopedPtr) ..." possible.
*/
operator bool() const { return _pointer; }
/**
* Returns the plain pointer value.
*
* @return the pointer the DisposablePtr manages
*/
PointerType get() const { return _pointer; }
private:
PointerType _pointer;
DisposeAfterUse::Flag _dispose;
};
} // End of namespace Common
#endif

@ -20,6 +20,7 @@
*
*/
#include "common/ptr.h"
#include "common/stream.h"
#include "common/memstream.h"
#include "common/substream.h"
@ -258,8 +259,7 @@ namespace {
*/
class BufferedReadStream : virtual public ReadStream {
protected:
ReadStream *_parentStream;
DisposeAfterUse::Flag _disposeParentStream;
DisposablePtr<ReadStream> _parentStream;
byte *_buf;
uint32 _pos;
bool _eos; // end of stream
@ -278,8 +278,7 @@ public:
};
BufferedReadStream::BufferedReadStream(ReadStream *parentStream, uint32 bufSize, DisposeAfterUse::Flag disposeParentStream)
: _parentStream(parentStream),
_disposeParentStream(disposeParentStream),
: _parentStream(parentStream, disposeParentStream),
_pos(0),
_eos(false),
_bufSize(0),
@ -291,8 +290,6 @@ BufferedReadStream::BufferedReadStream(ReadStream *parentStream, uint32 bufSize,
}
BufferedReadStream::~BufferedReadStream() {
if (_disposeParentStream)
delete _parentStream;
delete[] _buf;
}

@ -23,6 +23,7 @@
#ifndef COMMON_SUBSTREAM_H
#define COMMON_SUBSTREAM_H
#include "common/ptr.h"
#include "common/stream.h"
#include "common/types.h"
@ -38,24 +39,18 @@ namespace Common {
*/
class SubReadStream : virtual public ReadStream {
protected:
ReadStream *_parentStream;
DisposeAfterUse::Flag _disposeParentStream;
DisposablePtr<ReadStream> _parentStream;
uint32 _pos;
uint32 _end;
bool _eos;
public:
SubReadStream(ReadStream *parentStream, uint32 end, DisposeAfterUse::Flag disposeParentStream = DisposeAfterUse::NO)
: _parentStream(parentStream),
_disposeParentStream(disposeParentStream),
: _parentStream(parentStream, disposeParentStream),
_pos(0),
_end(end),
_eos(false) {
assert(parentStream);
}
~SubReadStream() {
if (_disposeParentStream)
delete _parentStream;
}
virtual bool eos() const { return _eos | _parentStream->eos(); }
virtual bool err() const { return _parentStream->err(); }

@ -22,6 +22,7 @@
#include "common/file.h"
#include "common/memstream.h"
#include "common/ptr.h"
#include "common/textconsole.h"
#include "common/util.h"
@ -43,11 +44,10 @@ namespace AGOS {
class BaseSound : Common::NonCopyable {
protected:
Common::File *_file;
Common::DisposablePtr<Common::File> _file;
uint32 *_offsets;
Audio::Mixer *_mixer;
bool _freeOffsets;
DisposeAfterUse::Flag _disposeFile;
public:
BaseSound(Audio::Mixer *mixer, Common::File *file, uint32 base, bool bigEndian, DisposeAfterUse::Flag disposeFileAfterUse = DisposeAfterUse::YES);
@ -62,7 +62,7 @@ public:
};
BaseSound::BaseSound(Audio::Mixer *mixer, Common::File *file, uint32 base, bool bigEndian, DisposeAfterUse::Flag disposeFileAfterUse)
: _mixer(mixer), _file(file), _disposeFile(disposeFileAfterUse) {
: _mixer(mixer), _file(file, disposeFileAfterUse) {
uint res = 0;
uint32 size;
@ -96,7 +96,7 @@ BaseSound::BaseSound(Audio::Mixer *mixer, Common::File *file, uint32 base, bool
}
BaseSound::BaseSound(Audio::Mixer *mixer, Common::File *file, uint32 *offsets, DisposeAfterUse::Flag disposeFileAfterUse)
: _mixer(mixer), _file(file), _disposeFile(disposeFileAfterUse) {
: _mixer(mixer), _file(file, disposeFileAfterUse) {
_offsets = offsets;
_freeOffsets = false;
@ -105,8 +105,6 @@ BaseSound::BaseSound(Audio::Mixer *mixer, Common::File *file, uint32 *offsets, D
BaseSound::~BaseSound() {
if (_freeOffsets)
free(_offsets);
if (_disposeFile == DisposeAfterUse::YES)
delete _file;
}
///////////////////////////////////////////////////////////////////////////////
@ -234,7 +232,7 @@ Audio::AudioStream *WavSound::makeAudioStream(uint sound) {
return NULL;
_file->seek(_offsets[sound], SEEK_SET);
return Audio::makeWAVStream(_file, DisposeAfterUse::NO);
return Audio::makeWAVStream(_file.get(), DisposeAfterUse::NO);
}
void WavSound::playSound(uint sound, uint loopSound, Audio::Mixer::SoundType type, Audio::SoundHandle *handle, bool loop, int vol) {
@ -257,7 +255,7 @@ public:
Audio::AudioStream *VocSound::makeAudioStream(uint sound) {
assert(_offsets);
_file->seek(_offsets[sound], SEEK_SET);
return Audio::makeVOCStream(_file, _flags);
return Audio::makeVOCStream(_file.get(), _flags);
}
void VocSound::playSound(uint sound, uint loopSound, Audio::Mixer::SoundType type, Audio::SoundHandle *handle, bool loop, int vol) {

@ -30,6 +30,7 @@
#include "common/file.h"
#include "common/hash-str.h"
#include "common/keyboard.h"
#include "common/ptr.h"
#include "common/random.h"
#include "common/savefile.h"
#include "common/system.h"
@ -264,15 +265,13 @@ private:
};
class TextResourceParser {
Common::SeekableReadStream *_stream;
DisposeAfterUse::Flag _dispose;
Common::DisposablePtr<Common::SeekableReadStream> _stream;
int _maxLen;
void getLine(char *buf);
public:
TextResourceParser(Common::SeekableReadStream *stream, DisposeAfterUse::Flag dispose);
~TextResourceParser();
void parseInt(int &result);
void parseString(char *result);

@ -42,7 +42,7 @@ Common::SeekableReadStream *ArchiveMan::open(const Common::String &filename) {
}
TextResourceParser::TextResourceParser(Common::SeekableReadStream *stream, DisposeAfterUse::Flag dispose) :
_stream(stream), _dispose(dispose) {
_stream(stream, dispose) {
// NOTE: strangely enough, the code before this refactoring used the size of
// the stream as a fixed maximum length for the parser. Using an updated
@ -50,12 +50,6 @@ TextResourceParser::TextResourceParser(Common::SeekableReadStream *stream, Dispo
_maxLen = _stream->size();
}
TextResourceParser::~TextResourceParser() {
if (_dispose == DisposeAfterUse::YES) {
delete _stream;
}
}
void TextResourceParser::getLine(char *buf) {
byte c;
char *b;