view dep/animia/src/animia.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 54c5d80a737e
children 2d5823df870f
line wrap: on
line source

#include "animia.h"
#include "animia/fd.h"
#include "animia/strategies.h"
#include "animia/types.h"
#include "animia/util.h"
#include "animia/win.h"

#include <set>
#include <string>
#include <vector>

namespace animia {

namespace internal {

static bool IsExecutableInList(const Player& player, const std::string& name) {
	std::string stem;
#ifdef WIN32
	if (!util::Stem(name, stem))
#endif
		stem = name;

	for (const auto& pattern : player.executables)
		if (util::CheckPattern(pattern, stem))
			return true;

	return false;
}

static bool IsWindowInList(const Player& player, const std::string& name) {
	for (const auto& pattern : player.windows)
		if (util::CheckPattern(pattern, name))
			return true;

	return false;
}

static bool PlayerHasStrategy(const Player& player, const Strategy& strategy) {
	for (const auto& pstrategy : player.strategies)
		if (pstrategy == strategy)
			return true;

	return false;
}

} // namespace internal

bool GetResults(const std::vector<Player>& players, std::vector<Result>& results) {
	/* Start out with file descriptors. */
	auto process_proc = [&](const Process& process) -> bool {
		for (const auto& player : players) {
			if (!internal::PlayerHasStrategy(player, Strategy::OpenFiles))
				continue;

			if (!internal::IsExecutableInList(player, process.name))
				continue;

			results.push_back({ResultType::Process, player, process, {}, {}});
			break;
		}
		return true;
	};

	if (!internal::fd.EnumerateOpenProcesses(process_proc))
		return false;

	/* Then add our cool windows.
	   Note: X11 is stupid and there's no reliable way to get a PID from a given window.
	         This is because some windows might not even have a process attached to them.
	         We should set the PID of the process if we can get it, but that'll be for when
	         I can actually be arsed to implement the X11 backend. */
	auto window_proc = [&](const Process& process, const Window& window) -> bool {
		for (const auto& player : players) {
			if (!internal::PlayerHasStrategy(player, Strategy::WindowTitle))
				continue;

			if (!internal::IsWindowInList(player, window.class_name))
				continue;

			results.push_back({ResultType::Window, player, process, window, {}});
			break;
		}
		return true;
	};

	if (!internal::win.EnumerateWindows(window_proc))
		return false;

	return internal::ApplyStrategies(results);
}

} // namespace animia