Save set id that failed to load.
This commit is contained in:
parent
2e82e7a3c9
commit
ab5a226056
2 changed files with 81 additions and 50 deletions
|
|
@ -31,12 +31,18 @@ constexpr auto kUniversalSize = 72;
|
|||
constexpr auto kImagesPerRow = 32;
|
||||
constexpr auto kImageRowsPerSprite = 16;
|
||||
|
||||
constexpr auto kSetVersion = uint32(1);
|
||||
constexpr auto kCacheVersion = uint32(5);
|
||||
constexpr auto kSetVersion = uint32(2);
|
||||
constexpr auto kCacheVersion = uint32(6);
|
||||
constexpr auto kMaxId = uint32(1 << 8);
|
||||
|
||||
constexpr auto kScaleForTouchBar = 150;
|
||||
|
||||
enum class ConfigResult {
|
||||
Invalid,
|
||||
BadVersion,
|
||||
Good,
|
||||
};
|
||||
|
||||
// Right now we can't allow users of Ui::Emoji to create custom sizes.
|
||||
// Any Instance::Instance() can invalidate Universal.id() and sprites.
|
||||
// So all Instance::Instance() should happen before async generations.
|
||||
|
|
@ -69,6 +75,7 @@ auto InstanceNormal = std::unique_ptr<Instance>();
|
|||
auto InstanceLarge = std::unique_ptr<Instance>();
|
||||
auto Universal = std::shared_ptr<UniversalImages>();
|
||||
auto CanClearUniversal = false;
|
||||
auto WaitingToSwitchBackToId = 0;
|
||||
auto Updates = rpl::event_stream<>();
|
||||
|
||||
#if defined Q_OS_MAC && !defined OS_MAC_OLD
|
||||
|
|
@ -138,7 +145,17 @@ int ReadCurrentSetId() {
|
|||
: 0;
|
||||
}
|
||||
|
||||
void ApplyUniversalImages(std::shared_ptr<UniversalImages> images) {
|
||||
Universal = std::move(images);
|
||||
CanClearUniversal = false;
|
||||
MainEmojiMap.clear();
|
||||
OtherEmojiMap.clear();
|
||||
Updates.fire({});
|
||||
}
|
||||
|
||||
void SwitchToSetPrepared(int id, std::shared_ptr<UniversalImages> images) {
|
||||
WaitingToSwitchBackToId = 0;
|
||||
|
||||
auto setting = QFile(CurrentSettingPath());
|
||||
if (!id) {
|
||||
setting.remove();
|
||||
|
|
@ -147,11 +164,34 @@ void SwitchToSetPrepared(int id, std::shared_ptr<UniversalImages> images) {
|
|||
stream.setVersion(QDataStream::Qt_5_1);
|
||||
stream << qint32(id);
|
||||
}
|
||||
Universal = std::move(images);
|
||||
CanClearUniversal = false;
|
||||
MainEmojiMap.clear();
|
||||
OtherEmojiMap.clear();
|
||||
Updates.fire({});
|
||||
ApplyUniversalImages(std::move(images));
|
||||
}
|
||||
|
||||
[[nodiscard]] ConfigResult ValidateConfig(int id) {
|
||||
Expects(IsValidSetId(id));
|
||||
|
||||
if (!id) {
|
||||
return ConfigResult::Good;
|
||||
}
|
||||
constexpr auto kSizeLimit = 65536;
|
||||
auto config = QFile(internal::SetDataPath(id) + "/config.json");
|
||||
if (!config.open(QIODevice::ReadOnly) || config.size() > kSizeLimit) {
|
||||
return ConfigResult::Invalid;
|
||||
}
|
||||
auto error = QJsonParseError{ 0, QJsonParseError::NoError };
|
||||
const auto document = QJsonDocument::fromJson(
|
||||
base::parse::stripComments(config.readAll()),
|
||||
&error);
|
||||
config.close();
|
||||
if (error.error != QJsonParseError::NoError) {
|
||||
return ConfigResult::Invalid;
|
||||
}
|
||||
if (document.object()["id"].toInt() != id) {
|
||||
return ConfigResult::Invalid;
|
||||
} else if (document.object()["version"].toInt() != kSetVersion) {
|
||||
return ConfigResult::BadVersion;
|
||||
}
|
||||
return ConfigResult::Good;
|
||||
}
|
||||
|
||||
void ClearCurrentSetIdSync() {
|
||||
|
|
@ -161,12 +201,14 @@ void ClearCurrentSetIdSync() {
|
|||
if (!id) {
|
||||
return;
|
||||
}
|
||||
QDir(internal::SetDataPath(id)).removeRecursively();
|
||||
|
||||
const auto newId = 0;
|
||||
auto universal = std::make_shared<UniversalImages>(newId);
|
||||
universal->ensureLoaded();
|
||||
SwitchToSetPrepared(newId, std::move(universal));
|
||||
|
||||
// Start loading the set when possible.
|
||||
ApplyUniversalImages(std::move(universal));
|
||||
WaitingToSwitchBackToId = id;
|
||||
}
|
||||
|
||||
void SaveToFile(int id, const QImage &image, int size, int index) {
|
||||
|
|
@ -288,37 +330,12 @@ std::vector<QImage> LoadSprites(int id) {
|
|||
}) | ranges::to_vector;
|
||||
}
|
||||
|
||||
bool ValidateConfig(int id) {
|
||||
Expects(IsValidSetId(id));
|
||||
|
||||
if (!id) {
|
||||
return true;
|
||||
}
|
||||
constexpr auto kSizeLimit = 65536;
|
||||
auto config = QFile(internal::SetDataPath(id) + "/config.json");
|
||||
if (!config.open(QIODevice::ReadOnly) || config.size() > kSizeLimit) {
|
||||
return false;
|
||||
}
|
||||
auto error = QJsonParseError{ 0, QJsonParseError::NoError };
|
||||
const auto document = QJsonDocument::fromJson(
|
||||
base::parse::stripComments(config.readAll()),
|
||||
&error);
|
||||
config.close();
|
||||
if (error.error != QJsonParseError::NoError) {
|
||||
return false;
|
||||
}
|
||||
if (document.object()["id"].toInt() != id
|
||||
|| document.object()["version"].toInt() != kSetVersion) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<QImage> LoadAndValidateSprites(int id) {
|
||||
Expects(IsValidSetId(id));
|
||||
Expects(SpritesCount > 0);
|
||||
|
||||
if (!ValidateConfig(id)) {
|
||||
const auto config = ValidateConfig(id);
|
||||
if (config != ConfigResult::Good) {
|
||||
return {};
|
||||
}
|
||||
auto result = LoadSprites(id);
|
||||
|
|
@ -526,6 +543,18 @@ int CurrentSetId() {
|
|||
return Universal->id();
|
||||
}
|
||||
|
||||
int NeedToSwitchBackToId() {
|
||||
return WaitingToSwitchBackToId;
|
||||
}
|
||||
|
||||
void ClearNeedSwitchToId() {
|
||||
if (!WaitingToSwitchBackToId) {
|
||||
return;
|
||||
}
|
||||
WaitingToSwitchBackToId = 0;
|
||||
QFile(CurrentSettingPath()).remove();
|
||||
}
|
||||
|
||||
void SwitchToSet(int id, Fn<void(bool)> callback) {
|
||||
Expects(IsValidSetId(id));
|
||||
|
||||
|
|
|
|||
|
|
@ -32,14 +32,16 @@ void ClearIrrelevantCache();
|
|||
// Thread safe, callback is called on main thread.
|
||||
void SwitchToSet(int id, Fn<void(bool)> callback);
|
||||
|
||||
int CurrentSetId();
|
||||
bool SetIsReady(int id);
|
||||
rpl::producer<> Updated();
|
||||
[[nodiscard]] int CurrentSetId();
|
||||
[[nodiscard]] int NeedToSwitchBackToId();
|
||||
void ClearNeedSwitchToId();
|
||||
[[nodiscard]] bool SetIsReady(int id);
|
||||
[[nodiscard]] rpl::producer<> Updated();
|
||||
|
||||
int GetSizeNormal();
|
||||
int GetSizeLarge();
|
||||
[[nodiscard]] int GetSizeNormal();
|
||||
[[nodiscard]] int GetSizeLarge();
|
||||
#if defined Q_OS_MAC && !defined OS_MAC_OLD
|
||||
int GetSizeTouchbar();
|
||||
[[nodiscard]] int GetSizeTouchbar();
|
||||
#endif
|
||||
|
||||
class One {
|
||||
|
|
@ -113,7 +115,7 @@ private:
|
|||
|
||||
};
|
||||
|
||||
inline EmojiPtr FromUrl(const QString &url) {
|
||||
[[nodiscard]] inline EmojiPtr FromUrl(const QString &url) {
|
||||
auto start = qstr("emoji://e.");
|
||||
if (url.startsWith(start)) {
|
||||
return internal::ByIndex(url.midRef(start.size()).toInt()); // skip emoji://e.
|
||||
|
|
@ -121,21 +123,21 @@ inline EmojiPtr FromUrl(const QString &url) {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
inline EmojiPtr Find(const QChar *start, const QChar *end, int *outLength = nullptr) {
|
||||
[[nodiscard]] inline EmojiPtr Find(const QChar *start, const QChar *end, int *outLength = nullptr) {
|
||||
return internal::Find(start, end, outLength);
|
||||
}
|
||||
|
||||
inline EmojiPtr Find(const QString &text, int *outLength = nullptr) {
|
||||
[[nodiscard]] inline EmojiPtr Find(const QString &text, int *outLength = nullptr) {
|
||||
return Find(text.constBegin(), text.constEnd(), outLength);
|
||||
}
|
||||
|
||||
QString IdFromOldKey(uint64 oldKey);
|
||||
[[nodiscard]] QString IdFromOldKey(uint64 oldKey);
|
||||
|
||||
inline EmojiPtr FromOldKey(uint64 oldKey) {
|
||||
[[nodiscard]] inline EmojiPtr FromOldKey(uint64 oldKey) {
|
||||
return Find(IdFromOldKey(oldKey));
|
||||
}
|
||||
|
||||
inline int ColorIndexFromCode(uint32 code) {
|
||||
[[nodiscard]] inline int ColorIndexFromCode(uint32 code) {
|
||||
switch (code) {
|
||||
case 0xD83CDFFBU: return 1;
|
||||
case 0xD83CDFFCU: return 2;
|
||||
|
|
@ -146,7 +148,7 @@ inline int ColorIndexFromCode(uint32 code) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
inline int ColorIndexFromOldKey(uint64 oldKey) {
|
||||
[[nodiscard]] inline int ColorIndexFromOldKey(uint64 oldKey) {
|
||||
return ColorIndexFromCode(uint32(oldKey & 0xFFFFFFFFLLU));
|
||||
}
|
||||
|
||||
|
|
@ -175,7 +177,7 @@ private:
|
|||
|
||||
};
|
||||
|
||||
const std::shared_ptr<UniversalImages> &SourceImages();
|
||||
[[nodiscard]] const std::shared_ptr<UniversalImages> &SourceImages();
|
||||
void ClearSourceImages(const std::shared_ptr<UniversalImages> &images);
|
||||
|
||||
} // namespace Emoji
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue