mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-22 22:13:35 +02:00
9fbeacb688
Fixes two bugs, one was definitely happening, and 2nd one that is causing undefined behavior and may work only in some std implementations - VideoPlayer would attempt to access subtitles widget after VideoPlayer itself was destroyed in onPlaybackFinished call - std::function was destroyed from a function that is being called by it. Replaced with 1-method interface to avoid usage of std::function in this scenario
75 lines
2.0 KiB
C++
75 lines
2.0 KiB
C++
/*
|
|
* VideoWidget.h, part of VCMI engine
|
|
*
|
|
* Authors: listed in file AUTHORS in main folder
|
|
*
|
|
* License: GNU General Public License v2.0 or later
|
|
* Full text of license available in license.txt file, in main folder
|
|
*
|
|
*/
|
|
#pragma once
|
|
|
|
#include "../gui/CIntObject.h"
|
|
|
|
#include "../lib/filesystem/ResourcePath.h"
|
|
#include "../lib/json/JsonNode.h"
|
|
|
|
class IVideoHolder;
|
|
class IVideoInstance;
|
|
class CMultiLineLabel;
|
|
|
|
class VideoWidgetBase : public CIntObject
|
|
{
|
|
std::unique_ptr<IVideoInstance> videoInstance;
|
|
std::unique_ptr<CMultiLineLabel> subTitle;
|
|
|
|
std::pair<std::unique_ptr<ui8[]>, si64> audioData = {nullptr, 0};
|
|
int audioHandle = -1;
|
|
bool playAudio = false;
|
|
float scaleFactor = 1.0;
|
|
JsonNode subTitleData;
|
|
|
|
void loadAudio(const VideoPath & file);
|
|
void startAudio();
|
|
void stopAudio();
|
|
std::string getSubTitleLine(double timestamp);
|
|
|
|
protected:
|
|
VideoWidgetBase(const Point & position, const VideoPath & video, bool playAudio);
|
|
VideoWidgetBase(const Point & position, const VideoPath & video, bool playAudio, float scaleFactor);
|
|
|
|
virtual void onPlaybackFinished() = 0;
|
|
void playVideo(const VideoPath & video);
|
|
|
|
public:
|
|
~VideoWidgetBase();
|
|
|
|
void activate() override;
|
|
void deactivate() override;
|
|
void show(Canvas & to) override;
|
|
void showAll(Canvas & to) override;
|
|
void tick(uint32_t msPassed) override;
|
|
|
|
void setPlaybackFinishedCallback(std::function<void()>);
|
|
};
|
|
|
|
class VideoWidget final: public VideoWidgetBase
|
|
{
|
|
VideoPath loopedVideo;
|
|
|
|
void onPlaybackFinished() final;
|
|
public:
|
|
VideoWidget(const Point & position, const VideoPath & prologue, const VideoPath & looped, bool playAudio);
|
|
VideoWidget(const Point & position, const VideoPath & looped, bool playAudio);
|
|
};
|
|
|
|
class VideoWidgetOnce final: public VideoWidgetBase
|
|
{
|
|
IVideoHolder * owner;
|
|
|
|
void onPlaybackFinished() final;
|
|
public:
|
|
VideoWidgetOnce(const Point & position, const VideoPath & video, bool playAudio, IVideoHolder * owner);
|
|
VideoWidgetOnce(const Point & position, const VideoPath & video, bool playAudio, float scaleFactor, IVideoHolder * owner);
|
|
};
|