view src/core/anime.cc @ 187:9613d72b097e

*: multiple performance improvements like marking `static const` when it makes sense... date: change old stupid heap-based method to a structure which should make copying the thing actually make a copy. also many performance-based changes, like removing the std::tie dependency and forward-declaring nlohmann json *: replace every instance of QString::fromUtf8 to Strings::ToQString. the main difference is that our function will always convert exactly what is in the string, while some other times it would only convert up to the nearest NUL byte
author Paper <mrpapersonic@gmail.com>
date Wed, 06 Dec 2023 13:43:54 -0500
parents 6ef31dbb90ca
children 975a3f0965e2
line wrap: on
line source

/*
 * anime.cpp: defining of custom anime-related
 * datatypes & variables
 */
#include "core/anime.h"
#include "core/date.h"
#include "core/session.h"

#include <algorithm>
#include <string>
#include <vector>

namespace Anime {

/* User list data */
bool Anime::IsInUserList() const {
	if (list_info_.get())
		return true;
	return false;
}

void Anime::AddToUserList() {
	list_info_.reset(new ListInformation);
}

void Anime::RemoveFromUserList() {
	list_info_.reset();
}

ListStatus Anime::GetUserStatus() const {
	assert(list_info_.get());
	return list_info_->status;
}

int Anime::GetUserProgress() const {
	assert(list_info_.get());
	return list_info_->progress;
}

int Anime::GetUserScore() const {
	assert(list_info_.get());
	return list_info_->score;
}

std::string Anime::GetUserPresentableScore() const {
	assert(list_info_.get());
	const int score = list_info_->score;
	if (score == 0)
		return "";

	switch (session.config.anime_list.score_format) {
		case ScoreFormat::POINT_10_DECIMAL:
			return std::to_string(score / 10) + "." + std::to_string(score % 10);
		case ScoreFormat::POINT_10:
			return std::to_string(score / 10);
		case ScoreFormat::POINT_5: {
			std::string stars = "";

			for (int i = 0; i < 100; i += 20)
				stars.append((i <= score) ? "★" : "☆");

			return stars;
		}
		case ScoreFormat::POINT_3: {
			if (score >= 100)
				return ":)";
			else if (score >= 66)
				return ":|";
			else if (score >= 33)
				return ":(";
			else
				return "";
		}
		default:
		case ScoreFormat::POINT_100:
			return std::to_string(score);
	}
}

Date Anime::GetUserDateStarted() const {
	assert(list_info_.get());
	return list_info_->started;
}

Date Anime::GetUserDateCompleted() const {
	assert(list_info_.get());
	return list_info_->completed;
}

bool Anime::GetUserIsPrivate() const {
	assert(list_info_.get());
	return list_info_->is_private;
}

unsigned int Anime::GetUserRewatchedTimes() const {
	assert(list_info_.get());
	return list_info_->rewatched_times;
}

bool Anime::GetUserIsRewatching() const {
	assert(list_info_.get());
	return list_info_->rewatching;
}

uint64_t Anime::GetUserTimeUpdated() const {
	assert(list_info_.get());
	return list_info_->updated;
}

std::string Anime::GetUserNotes() const {
	assert(list_info_.get());
	return list_info_->notes;
}

void Anime::SetUserStatus(ListStatus status) {
	assert(list_info_.get());
	list_info_->status = status;
}

void Anime::SetUserScore(int score) {
	assert(list_info_.get());
	list_info_->score = score;
}

void Anime::SetUserProgress(int progress) {
	assert(list_info_.get());
	list_info_->progress = progress;
}

void Anime::SetUserDateStarted(Date const& started) {
	assert(list_info_.get());
	list_info_->started = started;
}

void Anime::SetUserDateCompleted(Date const& completed) {
	assert(list_info_.get());
	list_info_->completed = completed;
}

void Anime::SetUserIsPrivate(bool is_private) {
	assert(list_info_.get());
	list_info_->is_private = is_private;
}

void Anime::SetUserRewatchedTimes(int rewatched) {
	assert(list_info_.get());
	list_info_->rewatched_times = rewatched;
}

void Anime::SetUserIsRewatching(bool rewatching) {
	assert(list_info_.get());
	list_info_->rewatching = rewatching;
}

void Anime::SetUserTimeUpdated(uint64_t updated) {
	assert(list_info_.get());
	list_info_->updated = updated;
}

void Anime::SetUserNotes(std::string const& notes) {
	assert(list_info_.get());
	list_info_->notes = notes;
}

/* Series data */
int Anime::GetId() const {
	return info_.id;
}

std::string Anime::GetRomajiTitle() const {
	return info_.title.romaji;
}

std::string Anime::GetEnglishTitle() const {
	return info_.title.english;
}

std::string Anime::GetNativeTitle() const {
	return info_.title.native;
}

std::vector<std::string> Anime::GetTitleSynonyms() const {
	std::vector<std::string> result;
#define IN_VECTOR(v, k) (std::count(v.begin(), v.end(), k))
#define ADD_TO_SYNONYMS(v, k) \
	if (!k.empty() && !IN_VECTOR(v, k) && k != GetUserPreferredTitle()) \
	v.push_back(k)
	ADD_TO_SYNONYMS(result, info_.title.english);
	ADD_TO_SYNONYMS(result, info_.title.romaji);
	ADD_TO_SYNONYMS(result, info_.title.native);
	for (auto& synonym : info_.synonyms) {
		ADD_TO_SYNONYMS(result, synonym);
	}
#undef ADD_TO_SYNONYMS
#undef IN_VECTOR
	return result;
}

int Anime::GetEpisodes() const {
	return info_.episodes;
}

SeriesStatus Anime::GetAiringStatus() const {
	return info_.status;
}

Date Anime::GetAirDate() const {
	return info_.air_date;
}

std::vector<std::string> Anime::GetGenres() const {
	return info_.genres;
}

std::vector<std::string> Anime::GetProducers() const {
	return info_.producers;
}

SeriesFormat Anime::GetFormat() const {
	return info_.format;
}

SeriesSeason Anime::GetSeason() const {
	return info_.season;
}

int Anime::GetAudienceScore() const {
	return info_.audience_score;
}

std::string Anime::GetSynopsis() const {
	return info_.synopsis;
}

int Anime::GetDuration() const {
	return info_.duration;
}

std::string Anime::GetPosterUrl() const {
	return info_.poster_url;
}

std::string Anime::GetServiceUrl() const {
	/* todo: add support for other services... */
	return "https://anilist.co/anime/" + std::to_string(GetId());
}

void Anime::SetId(int id) {
	info_.id = id;
}

void Anime::SetRomajiTitle(std::string const& title) {
	info_.title.romaji = title;
}

void Anime::SetEnglishTitle(std::string const& title) {
	info_.title.english = title;
}

void Anime::SetNativeTitle(std::string const& title) {
	info_.title.native = title;
}

void Anime::SetTitleSynonyms(std::vector<std::string> const& synonyms) {
	info_.synonyms = synonyms;
}

void Anime::AddTitleSynonym(std::string const& synonym) {
	info_.synonyms.push_back(synonym);
}

void Anime::SetEpisodes(int episodes) {
	info_.episodes = episodes;
}

void Anime::SetAiringStatus(SeriesStatus status) {
	info_.status = status;
}

void Anime::SetAirDate(Date const& date) {
	info_.air_date = date;
}

void Anime::SetGenres(std::vector<std::string> const& genres) {
	info_.genres = genres;
}

void Anime::SetProducers(std::vector<std::string> const& producers) {
	info_.producers = producers;
}

void Anime::SetFormat(SeriesFormat format) {
	info_.format = format;
}

void Anime::SetSeason(SeriesSeason season) {
	info_.season = season;
}

void Anime::SetAudienceScore(int audience_score) {
	info_.audience_score = audience_score;
}

void Anime::SetSynopsis(std::string synopsis) {
	info_.synopsis = synopsis;
}

void Anime::SetDuration(int duration) {
	info_.duration = duration;
}

void Anime::SetPosterUrl(std::string url) {
	info_.poster_url = url;
}

std::string Anime::GetUserPreferredTitle() const {
	switch (session.config.anime_list.language) {
		case TitleLanguage::NATIVE: return (GetNativeTitle().empty()) ? GetRomajiTitle() : GetNativeTitle();
		case TitleLanguage::ENGLISH: return (GetEnglishTitle().empty()) ? GetRomajiTitle() : GetEnglishTitle();
		default: break;
	}
	return GetRomajiTitle();
}

} // namespace Anime