mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-01-25 16:54:25 +00:00
Media::Clip::Reader owners use Media::Clip::ReaderPointer smartptr.
This commit is contained in:
parent
344890c533
commit
78815800d0
@ -1522,10 +1522,7 @@ ImagePtr HistoryDocument::replyPreview() {
|
||||
|
||||
HistoryGif::HistoryGif(HistoryItem *parent, DocumentData *document, const QString &caption) : HistoryFileMedia(parent)
|
||||
, _data(document)
|
||||
, _thumbw(1)
|
||||
, _thumbh(1)
|
||||
, _caption(st::minPhotoSize - st::msgPadding.left() - st::msgPadding.right())
|
||||
, _gif(nullptr) {
|
||||
, _caption(st::minPhotoSize - st::msgPadding.left() - st::msgPadding.right()) {
|
||||
setDocumentLinks(_data, true);
|
||||
|
||||
setStatusSize(FileStatusSizeReady);
|
||||
@ -1541,8 +1538,7 @@ HistoryGif::HistoryGif(HistoryItem *parent, const HistoryGif &other) : HistoryFi
|
||||
, _data(other._data)
|
||||
, _thumbw(other._thumbw)
|
||||
, _thumbh(other._thumbh)
|
||||
, _caption(other._caption)
|
||||
, _gif(nullptr) {
|
||||
, _caption(other._caption) {
|
||||
setDocumentLinks(_data, true);
|
||||
|
||||
setStatusSize(other._statusSize);
|
||||
@ -1555,16 +1551,15 @@ void HistoryGif::initDimensions() {
|
||||
|
||||
bool bubble = _parent->hasBubble();
|
||||
int32 tw = 0, th = 0;
|
||||
if (gif() && _gif->state() == Media::Clip::State::Error) {
|
||||
if (_gif && _gif->state() == Media::Clip::State::Error) {
|
||||
if (!_gif->autoplay()) {
|
||||
Ui::showLayer(new InformBox(lang(lng_gif_error)));
|
||||
}
|
||||
App::unregGifItem(_gif);
|
||||
delete _gif;
|
||||
_gif = Media::Clip::BadReader;
|
||||
App::unregGifItem(_gif.get());
|
||||
_gif.setBad();
|
||||
}
|
||||
|
||||
if (gif() && _gif->ready()) {
|
||||
if (_gif && _gif->ready()) {
|
||||
tw = convertScale(_gif->width());
|
||||
th = convertScale(_gif->height());
|
||||
} else {
|
||||
@ -1590,7 +1585,7 @@ void HistoryGif::initDimensions() {
|
||||
_maxw = qMax(tw, int32(st::minPhotoSize));
|
||||
_minh = qMax(th, int32(st::minPhotoSize));
|
||||
_maxw = qMax(_maxw, _parent->infoWidth() + 2 * int32(st::msgDateImgDelta + st::msgDateImgPadding.x()));
|
||||
if (!gif() || !_gif->ready()) {
|
||||
if (!_gif || !_gif->ready()) {
|
||||
_maxw = qMax(_maxw, gifMaxStatusWidth(_data) + 2 * int32(st::msgDateImgDelta + st::msgDateImgPadding.x()));
|
||||
}
|
||||
if (bubble) {
|
||||
@ -1610,7 +1605,7 @@ int HistoryGif::resizeGetHeight(int width) {
|
||||
bool bubble = _parent->hasBubble();
|
||||
|
||||
int tw = 0, th = 0;
|
||||
if (gif() && _gif->ready()) {
|
||||
if (_gif && _gif->ready()) {
|
||||
tw = convertScale(_gif->width());
|
||||
th = convertScale(_gif->height());
|
||||
} else {
|
||||
@ -1645,7 +1640,7 @@ int HistoryGif::resizeGetHeight(int width) {
|
||||
_width = qMax(tw, int32(st::minPhotoSize));
|
||||
_height = qMax(th, int32(st::minPhotoSize));
|
||||
_width = qMax(_width, _parent->infoWidth() + 2 * int32(st::msgDateImgDelta + st::msgDateImgPadding.x()));
|
||||
if (gif() && _gif->ready()) {
|
||||
if (_gif && _gif->ready()) {
|
||||
if (!_gif->started()) {
|
||||
auto inWebPage = (_parent->getMedia() != this);
|
||||
auto roundRadius = inWebPage ? ImageRoundRadius::Small : ImageRoundRadius::Large;
|
||||
@ -1676,7 +1671,7 @@ void HistoryGif::draw(Painter &p, const QRect &r, TextSelection selection, uint6
|
||||
bool loaded = _data->loaded(), displayLoading = (_parent->id < 0) || _data->displayLoading();
|
||||
bool selected = (selection == FullSelection);
|
||||
|
||||
if (loaded && !gif() && _gif != Media::Clip::BadReader && cAutoPlayGif()) {
|
||||
if (loaded && !_gif && !_gif.isBad() && cAutoPlayGif()) {
|
||||
Ui::autoplayMediaInlineAsync(_parent->fullId());
|
||||
}
|
||||
|
||||
@ -1686,7 +1681,7 @@ void HistoryGif::draw(Painter &p, const QRect &r, TextSelection selection, uint6
|
||||
|
||||
int32 captionw = width - st::msgPadding.left() - st::msgPadding.right();
|
||||
|
||||
bool animating = (gif() && _gif->started());
|
||||
bool animating = (_gif && _gif->started());
|
||||
|
||||
if (!animating || _parent->id < 0) {
|
||||
if (displayLoading) {
|
||||
@ -1730,7 +1725,7 @@ void HistoryGif::draw(Painter &p, const QRect &r, TextSelection selection, uint6
|
||||
App::roundRect(p, rthumb, textstyleCurrent()->selectOverlay, overlayCorners);
|
||||
}
|
||||
|
||||
if (radial || (!_gif && ((!loaded && !_data->loading()) || !cAutoPlayGif())) || (_gif == Media::Clip::BadReader)) {
|
||||
if (radial || _gif.isBad() || (!_gif && ((!loaded && !_data->loading()) || !cAutoPlayGif()))) {
|
||||
float64 radialOpacity = (radial && loaded && _parent->id > 0) ? _animation->radial.opacity() : 1;
|
||||
QRect inner(rthumb.x() + (rthumb.width() - st::msgFileSize) / 2, rthumb.y() + (rthumb.height() - st::msgFileSize) / 2, st::msgFileSize, st::msgFileSize);
|
||||
p.setPen(Qt::NoPen);
|
||||
@ -1818,7 +1813,7 @@ HistoryTextState HistoryGif::getState(int x, int y, HistoryStateRequest request)
|
||||
if (x >= skipx && y >= skipy && x < skipx + width && y < skipy + height) {
|
||||
if (_data->uploading()) {
|
||||
result.link = _cancell;
|
||||
} else if (!gif() || !cAutoPlayGif()) {
|
||||
} else if (!_gif || !cAutoPlayGif()) {
|
||||
result.link = _data->loaded() ? _openl : (_data->loading() ? _cancell : _savel);
|
||||
}
|
||||
if (_parent->getMedia() == this) {
|
||||
@ -1891,36 +1886,34 @@ ImagePtr HistoryGif::replyPreview() {
|
||||
}
|
||||
|
||||
bool HistoryGif::playInline(bool autoplay) {
|
||||
if (gif()) {
|
||||
if (_gif) {
|
||||
stopInline();
|
||||
} else if (_data->loaded(DocumentData::FilePathResolveChecked)) {
|
||||
if (!cAutoPlayGif()) {
|
||||
App::stopGifItems();
|
||||
}
|
||||
_gif = new Media::Clip::Reader(_data->location(), _data->data(), [this](Media::Clip::Notification notification) {
|
||||
_gif = Media::Clip::MakeReader(_data->location(), _data->data(), [this](Media::Clip::Notification notification) {
|
||||
_parent->clipCallback(notification);
|
||||
});
|
||||
App::regGifItem(_gif, _parent);
|
||||
if (gif()) _gif->setAutoplay();
|
||||
App::regGifItem(_gif.get(), _parent);
|
||||
if (_gif) _gif->setAutoplay();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void HistoryGif::stopInline() {
|
||||
if (gif()) {
|
||||
App::unregGifItem(_gif);
|
||||
delete _gif;
|
||||
_gif = 0;
|
||||
if (_gif) {
|
||||
App::unregGifItem(_gif.get());
|
||||
}
|
||||
_gif.reset();
|
||||
|
||||
_parent->setPendingInitDimensions();
|
||||
Notify::historyItemLayoutChanged(_parent);
|
||||
}
|
||||
|
||||
HistoryGif::~HistoryGif() {
|
||||
if (gif()) {
|
||||
App::unregGifItem(_gif);
|
||||
deleteAndMark(_gif);
|
||||
if (_gif) {
|
||||
App::unregGifItem(_gif.get());
|
||||
}
|
||||
}
|
||||
|
||||
@ -3071,7 +3064,7 @@ void HistoryGame::draw(Painter &p, const QRect &r, TextSelection selection, uint
|
||||
p.fillRect(bar, barfg);
|
||||
|
||||
if (_titleLines) {
|
||||
p.setPen(st::black);
|
||||
p.setPen(semibold);
|
||||
int32 endskip = 0;
|
||||
if (_title.hasSkipBlock()) {
|
||||
endskip = _parent->skipBlockWidth();
|
||||
|
@ -446,7 +446,7 @@ public:
|
||||
return _data;
|
||||
}
|
||||
Media::Clip::Reader *getClipReader() override {
|
||||
return gif();
|
||||
return _gif.get();
|
||||
}
|
||||
|
||||
bool playInline(bool autoplay) override;
|
||||
@ -491,16 +491,11 @@ protected:
|
||||
|
||||
private:
|
||||
DocumentData *_data;
|
||||
int32 _thumbw, _thumbh;
|
||||
int32 _thumbw = 1;
|
||||
int32 _thumbh = 1;
|
||||
Text _caption;
|
||||
|
||||
Media::Clip::Reader *_gif;
|
||||
Media::Clip::Reader *gif() {
|
||||
return (_gif == Media::Clip::BadReader) ? nullptr : _gif;
|
||||
}
|
||||
const Media::Clip::Reader *gif() const {
|
||||
return (_gif == Media::Clip::BadReader) ? nullptr : _gif;
|
||||
}
|
||||
Media::Clip::ReaderPointer _gif;
|
||||
|
||||
void setStatusSize(int32 newSize) const;
|
||||
void updateStatusText() const;
|
||||
|
@ -112,8 +112,7 @@ void Gif::initDimensions() {
|
||||
void Gif::setPosition(int32 position) {
|
||||
ItemBase::setPosition(position);
|
||||
if (_position < 0) {
|
||||
if (gif()) delete _gif;
|
||||
_gif = 0;
|
||||
_gif.reset();
|
||||
}
|
||||
}
|
||||
|
||||
@ -133,15 +132,15 @@ void Gif::paint(Painter &p, const QRect &clip, const PaintContext *context) cons
|
||||
document->automaticLoad(nullptr);
|
||||
|
||||
bool loaded = document->loaded(), loading = document->loading(), displayLoading = document->displayLoading();
|
||||
if (loaded && !gif() && _gif != Media::Clip::BadReader) {
|
||||
if (loaded && !_gif && !_gif.isBad()) {
|
||||
auto that = const_cast<Gif*>(this);
|
||||
that->_gif = new Media::Clip::Reader(document->location(), document->data(), [that](Media::Clip::Notification notification) {
|
||||
that->_gif = Media::Clip::MakeReader(document->location(), document->data(), [that](Media::Clip::Notification notification) {
|
||||
that->clipCallback(notification);
|
||||
});
|
||||
if (gif()) _gif->setAutoplay();
|
||||
if (_gif) _gif->setAutoplay();
|
||||
}
|
||||
|
||||
bool animating = (gif() && _gif->started());
|
||||
bool animating = (_gif && _gif->started());
|
||||
if (displayLoading) {
|
||||
ensureAnimation();
|
||||
if (!_animation->radial.animating()) {
|
||||
@ -166,7 +165,7 @@ void Gif::paint(Painter &p, const QRect &clip, const PaintContext *context) cons
|
||||
}
|
||||
}
|
||||
|
||||
if (radial || (!_gif && !loaded && !loading) || (_gif == Media::Clip::BadReader)) {
|
||||
if (radial || _gif.isBad() || (!_gif && !loaded && !loading)) {
|
||||
auto radialOpacity = (radial && loaded) ? _animation->radial.opacity() : 1.;
|
||||
if (_animation && _animation->_a_over.animating(context->ms)) {
|
||||
auto over = _animation->_a_over.current();
|
||||
@ -248,7 +247,7 @@ void Gif::clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) {
|
||||
}
|
||||
|
||||
QSize Gif::countFrameSize() const {
|
||||
bool animating = (gif() && _gif->ready());
|
||||
bool animating = (_gif && _gif->ready());
|
||||
int32 framew = animating ? _gif->width() : content_width(), frameh = animating ? _gif->height() : content_height(), height = st::inlineMediaHeight;
|
||||
if (framew * height > frameh * _width) {
|
||||
if (framew < st::maxStickerSize || frameh > height) {
|
||||
@ -274,10 +273,6 @@ QSize Gif::countFrameSize() const {
|
||||
return QSize(framew, frameh);
|
||||
}
|
||||
|
||||
Gif::~Gif() {
|
||||
if (gif()) deleteAndMark(_gif);
|
||||
}
|
||||
|
||||
void Gif::prepareThumb(int32 width, int32 height, const QSize &frame) const {
|
||||
if (DocumentData *document = getShownDocument()) {
|
||||
if (!document->thumb->isNull()) {
|
||||
@ -332,18 +327,16 @@ void Gif::clipCallback(Media::Clip::Notification notification) {
|
||||
using namespace Media::Clip;
|
||||
switch (notification) {
|
||||
case NotificationReinit: {
|
||||
if (gif()) {
|
||||
if (_gif) {
|
||||
if (_gif->state() == State::Error) {
|
||||
delete _gif;
|
||||
_gif = BadReader;
|
||||
_gif.setBad();
|
||||
getShownDocument()->forget();
|
||||
} else if (_gif->ready() && !_gif->started()) {
|
||||
int32 height = st::inlineMediaHeight;
|
||||
QSize frame = countFrameSize();
|
||||
_gif->start(frame.width(), frame.height(), _width, height, ImageRoundRadius::None);
|
||||
} else if (_gif->autoPausedGif() && !Ui::isInlineItemVisible(this)) {
|
||||
delete _gif;
|
||||
_gif = nullptr;
|
||||
_gif.reset();
|
||||
getShownDocument()->forget();
|
||||
}
|
||||
}
|
||||
@ -352,7 +345,7 @@ void Gif::clipCallback(Media::Clip::Notification notification) {
|
||||
} break;
|
||||
|
||||
case NotificationRepaint: {
|
||||
if (gif() && !_gif->currentDisplayed()) {
|
||||
if (_gif && !_gif->currentDisplayed()) {
|
||||
update();
|
||||
}
|
||||
} break;
|
||||
@ -1193,8 +1186,7 @@ void Game::initDimensions() {
|
||||
void Game::setPosition(int32 position) {
|
||||
ItemBase::setPosition(position);
|
||||
if (_position < 0) {
|
||||
if (gif()) delete _gif;
|
||||
_gif = 0;
|
||||
_gif.reset();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1212,15 +1204,15 @@ void Game::paint(Painter &p, const QRect &clip, const PaintContext *context) con
|
||||
document->automaticLoad(nullptr);
|
||||
|
||||
bool loaded = document->loaded(), loading = document->loading(), displayLoading = document->displayLoading();
|
||||
if (loaded && !gif() && _gif != Media::Clip::BadReader) {
|
||||
if (loaded && !_gif && !_gif.isBad()) {
|
||||
auto that = const_cast<Game*>(this);
|
||||
that->_gif = new Media::Clip::Reader(document->location(), document->data(), [that](Media::Clip::Notification notification) {
|
||||
that->_gif = Media::Clip::MakeReader(document->location(), document->data(), [that](Media::Clip::Notification notification) {
|
||||
that->clipCallback(notification);
|
||||
});
|
||||
if (gif()) _gif->setAutoplay();
|
||||
if (_gif) _gif->setAutoplay();
|
||||
}
|
||||
|
||||
bool animating = (gif() && _gif->started());
|
||||
bool animating = (_gif && _gif->started());
|
||||
if (displayLoading) {
|
||||
if (!_radial) {
|
||||
_radial = std_::make_unique<Ui::RadialAnimation>(animation(const_cast<Game*>(this), &Game::step_radial));
|
||||
@ -1342,16 +1334,14 @@ void Game::clipCallback(Media::Clip::Notification notification) {
|
||||
using namespace Media::Clip;
|
||||
switch (notification) {
|
||||
case NotificationReinit: {
|
||||
if (gif()) {
|
||||
if (_gif) {
|
||||
if (_gif->state() == State::Error) {
|
||||
delete _gif;
|
||||
_gif = BadReader;
|
||||
_gif.setBad();
|
||||
getResultDocument()->forget();
|
||||
} else if (_gif->ready() && !_gif->started()) {
|
||||
_gif->start(_frameSize.width(), _frameSize.height(), st::inlineThumbSize, st::inlineThumbSize, ImageRoundRadius::None);
|
||||
} else if (_gif->autoPausedGif() && !Ui::isInlineItemVisible(this)) {
|
||||
delete _gif;
|
||||
_gif = nullptr;
|
||||
_gif.reset();
|
||||
getResultDocument()->forget();
|
||||
}
|
||||
}
|
||||
@ -1360,17 +1350,13 @@ void Game::clipCallback(Media::Clip::Notification notification) {
|
||||
} break;
|
||||
|
||||
case NotificationRepaint: {
|
||||
if (gif() && !_gif->currentDisplayed()) {
|
||||
if (_gif && !_gif->currentDisplayed()) {
|
||||
update();
|
||||
}
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
Game::~Game() {
|
||||
if (gif()) deleteAndMark(_gif);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace Layout
|
||||
} // namespace InlineBots
|
||||
|
@ -77,10 +77,7 @@ public:
|
||||
// ClickHandlerHost interface
|
||||
void clickHandlerActiveChanged(const ClickHandlerPtr &p, bool active) override;
|
||||
|
||||
~Gif();
|
||||
|
||||
private:
|
||||
|
||||
QSize countFrameSize() const;
|
||||
|
||||
enum class StateFlag {
|
||||
@ -93,11 +90,8 @@ private:
|
||||
return ~StateFlags(flag);
|
||||
}
|
||||
|
||||
Media::Clip::Reader *_gif = nullptr;
|
||||
Media::Clip::ReaderPointer _gif;
|
||||
ClickHandlerPtr _delete;
|
||||
bool gif() const {
|
||||
return (!_gif || _gif == Media::Clip::BadReader) ? false : true;
|
||||
}
|
||||
mutable QPixmap _thumb;
|
||||
void prepareThumb(int32 width, int32 height, const QSize &frame) const;
|
||||
|
||||
@ -349,14 +343,9 @@ public:
|
||||
void paint(Painter &p, const QRect &clip, const PaintContext *context) const override;
|
||||
void getState(ClickHandlerPtr &link, HistoryCursorState &cursor, int x, int y) const override;
|
||||
|
||||
~Game();
|
||||
|
||||
private:
|
||||
void countFrameSize();
|
||||
|
||||
bool gif() const {
|
||||
return (!_gif || _gif == Media::Clip::BadReader) ? false : true;
|
||||
}
|
||||
void prepareThumb(int32 width, int32 height) const;
|
||||
|
||||
bool isRadialAnimation(uint64 ms) const;
|
||||
@ -364,7 +353,7 @@ private:
|
||||
|
||||
void clipCallback(Media::Clip::Notification notification);
|
||||
|
||||
Media::Clip::Reader *_gif = nullptr;
|
||||
Media::Clip::ReaderPointer _gif;
|
||||
mutable QPixmap _thumb;
|
||||
mutable std_::unique_ptr<Ui::RadialAnimation> _radial;
|
||||
Text _title, _description;
|
||||
|
@ -567,12 +567,7 @@ void MediaPreviewWidget::fillEmojiString() {
|
||||
}
|
||||
|
||||
void MediaPreviewWidget::resetGifAndCache() {
|
||||
if (_gif) {
|
||||
if (gif()) {
|
||||
delete _gif;
|
||||
}
|
||||
_gif = nullptr;
|
||||
}
|
||||
_gif.reset();
|
||||
_cacheStatus = CacheNotLoaded;
|
||||
_cachedSize = QSize();
|
||||
}
|
||||
@ -592,7 +587,7 @@ QSize MediaPreviewWidget::currentDimensions() const {
|
||||
box = QSize(width() - 2 * st::boxVerticalMargin, height() - 2 * st::boxVerticalMargin);
|
||||
} else {
|
||||
result = _document->dimensions;
|
||||
if (gif() && _gif->ready()) {
|
||||
if (_gif && _gif->ready()) {
|
||||
result = QSize(_gif->width(), _gif->height());
|
||||
}
|
||||
if (_document->sticker()) {
|
||||
@ -636,15 +631,15 @@ QPixmap MediaPreviewWidget::currentImage() const {
|
||||
} else {
|
||||
_document->automaticLoad(nullptr);
|
||||
if (_document->loaded()) {
|
||||
if (!_gif && _gif != Media::Clip::BadReader) {
|
||||
if (!_gif && !_gif.isBad()) {
|
||||
auto that = const_cast<MediaPreviewWidget*>(this);
|
||||
that->_gif = new Media::Clip::Reader(_document->location(), _document->data(), [this, that](Media::Clip::Notification notification) {
|
||||
that->_gif = Media::Clip::MakeReader(_document->location(), _document->data(), [this, that](Media::Clip::Notification notification) {
|
||||
that->clipCallback(notification);
|
||||
});
|
||||
if (gif()) _gif->setAutoplay();
|
||||
if (_gif) _gif->setAutoplay();
|
||||
}
|
||||
}
|
||||
if (gif() && _gif->started()) {
|
||||
if (_gif && _gif->started()) {
|
||||
QSize s = currentDimensions();
|
||||
return _gif->current(s.width(), s.height(), s.width(), s.height(), getms());
|
||||
}
|
||||
@ -681,12 +676,11 @@ void MediaPreviewWidget::clipCallback(Media::Clip::Notification notification) {
|
||||
using namespace Media::Clip;
|
||||
switch (notification) {
|
||||
case NotificationReinit: {
|
||||
if (gif() && _gif->state() == State::Error) {
|
||||
delete _gif;
|
||||
_gif = BadReader;
|
||||
if (_gif && _gif->state() == State::Error) {
|
||||
_gif.setBad();
|
||||
}
|
||||
|
||||
if (gif() && _gif->ready() && !_gif->started()) {
|
||||
if (_gif && _gif->ready() && !_gif->started()) {
|
||||
QSize s = currentDimensions();
|
||||
_gif->start(s.width(), s.height(), s.width(), s.height(), ImageRoundRadius::None);
|
||||
}
|
||||
@ -695,7 +689,7 @@ void MediaPreviewWidget::clipCallback(Media::Clip::Notification notification) {
|
||||
} break;
|
||||
|
||||
case NotificationRepaint: {
|
||||
if (gif() && !_gif->currentDisplayed()) {
|
||||
if (_gif && !_gif->currentDisplayed()) {
|
||||
update();
|
||||
}
|
||||
} break;
|
||||
|
@ -157,10 +157,7 @@ private:
|
||||
Animation _a_shown;
|
||||
DocumentData *_document = nullptr;
|
||||
PhotoData *_photo = nullptr;
|
||||
Media::Clip::Reader *_gif = nullptr;
|
||||
bool gif() const {
|
||||
return (!_gif || _gif == Media::Clip::BadReader) ? false : true;
|
||||
}
|
||||
Media::Clip::ReaderPointer _gif;
|
||||
|
||||
int _emojiSize;
|
||||
QList<EmojiPtr> _emojiList;
|
||||
|
@ -23,6 +23,26 @@ Copyright (c) 2014-2016 John Preston, https://desktop.telegram.org
|
||||
|
||||
#include "media/media_clip_reader.h"
|
||||
|
||||
namespace Media {
|
||||
namespace Clip {
|
||||
|
||||
Reader *const ReaderPointer::BadPointer = SharedMemoryLocation<Reader, 0>();
|
||||
|
||||
ReaderPointer::~ReaderPointer() {
|
||||
if (valid()) {
|
||||
delete _pointer;
|
||||
}
|
||||
_pointer = nullptr;
|
||||
}
|
||||
|
||||
class Tmp;
|
||||
void f(Tmp *t) {
|
||||
delete t;
|
||||
}
|
||||
|
||||
} // namespace Clip
|
||||
} // namespace Media
|
||||
|
||||
namespace {
|
||||
|
||||
AnimationManager *_manager = nullptr;
|
||||
|
@ -29,7 +29,58 @@ namespace Media {
|
||||
namespace Clip {
|
||||
|
||||
class Reader;
|
||||
static Reader * const BadReader = SharedMemoryLocation<Reader, 0>();
|
||||
class ReaderPointer {
|
||||
public:
|
||||
ReaderPointer(std::nullptr_t = nullptr) {
|
||||
}
|
||||
explicit ReaderPointer(Reader *pointer) : _pointer(pointer) {
|
||||
}
|
||||
ReaderPointer(const ReaderPointer &other) = delete;
|
||||
ReaderPointer &operator=(const ReaderPointer &other) = delete;
|
||||
ReaderPointer(ReaderPointer &&other) : _pointer(createAndSwap(other._pointer)) {
|
||||
}
|
||||
ReaderPointer &operator=(ReaderPointer &&other) {
|
||||
swap(other);
|
||||
return *this;
|
||||
}
|
||||
void swap(ReaderPointer &other) {
|
||||
qSwap(_pointer, other._pointer);
|
||||
}
|
||||
Reader *get() const {
|
||||
return valid() ? _pointer : nullptr;
|
||||
}
|
||||
Reader *operator->() const {
|
||||
return get();
|
||||
}
|
||||
void setBad() {
|
||||
reset();
|
||||
_pointer = BadPointer;
|
||||
}
|
||||
void reset() {
|
||||
ReaderPointer temp;
|
||||
swap(temp);
|
||||
}
|
||||
bool isBad() const {
|
||||
return (_pointer == BadPointer);
|
||||
}
|
||||
bool valid() const {
|
||||
return _pointer && !isBad();
|
||||
}
|
||||
explicit operator bool() const {
|
||||
return valid();
|
||||
}
|
||||
~ReaderPointer();
|
||||
|
||||
private:
|
||||
Reader *_pointer = nullptr;
|
||||
static Reader *const BadPointer;
|
||||
|
||||
};
|
||||
|
||||
template <typename ...Args>
|
||||
inline ReaderPointer MakeReader(Args&&... args) {
|
||||
return ReaderPointer(new Reader(std_::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
class Manager;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user