Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions src/common/factory.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**
* @file src/common/factory.cpp
* @brief Factory helpers for unsupported platforms.
*/
// local includes
#include "display_device/factory.h"

#if !defined(_WIN32) && !defined(__APPLE__)

namespace display_device {
std::unique_ptr<SettingsManagerInterface> makeSettingsManager(const SettingsManagerFactoryConfig &) {
return nullptr;
}

std::unique_ptr<DisplayPowerInterface> makeDisplayPower() {
return nullptr;
}
} // namespace display_device

#endif
41 changes: 41 additions & 0 deletions src/common/include/display_device/factory.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/**
* @file src/common/include/display_device/factory.h
* @brief Factory helpers for platform display device interfaces.
*/
#pragma once

// system includes
#include <chrono>
#include <memory>
#include <optional>

// local includes
#include "audio_context_interface.h"
#include "display_power_interface.h"
#include "settings_manager_interface.h"
#include "settings_persistence_interface.h"

namespace display_device {
/**
* @brief Dependencies and platform-neutral options for creating a settings manager.
*/
struct SettingsManagerFactoryConfig {
std::shared_ptr<AudioContextInterface> m_audio_context_api {}; ///< Optional audio context interface.
std::shared_ptr<SettingsPersistenceInterface> m_settings_persistence_api {}; ///< Optional settings persistence interface.
bool m_throw_on_persistence_load_error {}; ///< Throw when persisted settings cannot be loaded or parsed.
std::optional<std::chrono::milliseconds> m_hdr_blank_delay {}; ///< Optional HDR blanking workaround delay on supported platforms.
};

/**
* @brief Create the default settings manager for the current platform.
* @param config Dependencies and platform-neutral options.
* @returns A settings manager, or nullptr when the platform is unsupported.
*/
[[nodiscard]] std::unique_ptr<SettingsManagerInterface> makeSettingsManager(const SettingsManagerFactoryConfig &config = {});

/**
* @brief Create the default display power manager for the current platform.
* @returns A display power manager, or nullptr when the platform is unsupported.
*/
[[nodiscard]] std::unique_ptr<DisplayPowerInterface> makeDisplayPower();
} // namespace display_device
28 changes: 28 additions & 0 deletions src/macos/factory.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* @file src/macos/factory.cpp
* @brief Factory helpers for macOS platform interfaces.
*/
// class header include
#include "display_device/factory.h"

// local includes
#include "display_device/macos/display_power.h"
#include "display_device/macos/mac_api_layer.h"
#include "display_device/macos/mac_display_device.h"
#include "display_device/macos/settings_manager.h"

namespace display_device {
std::unique_ptr<SettingsManagerInterface> makeSettingsManager(const SettingsManagerFactoryConfig &config) {
auto api_layer {std::make_shared<MacApiLayer>()};
return std::make_unique<MacSettingsManager>(
std::make_shared<MacDisplayDevice>(api_layer),
config.m_audio_context_api,
std::make_unique<MacPersistentState>(config.m_settings_persistence_api, config.m_throw_on_persistence_load_error),
MacWorkarounds {}
);
}

std::unique_ptr<DisplayPowerInterface> makeDisplayPower() {
return std::make_unique<MacDisplayPower>(std::make_shared<MacApiLayer>());
}
} // namespace display_device
3 changes: 2 additions & 1 deletion src/macos/mac_display_device_general.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ namespace display_device {
}
}

devices.emplace_back(device_id, display_name, friendly_name, edid, info);
// Keep braced aggregate construction; emplace_back(args...) relies on parenthesized aggregate init, which older libc++ rejects.
devices.push_back(EnumeratedDevice {device_id, display_name, friendly_name, edid, info}); // NOSONAR
}

return devices;
Expand Down
30 changes: 30 additions & 0 deletions src/windows/factory.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* @file src/windows/factory.cpp
* @brief Factory helpers for Windows platform interfaces.
*/
// class header include
#include "display_device/factory.h"

// local includes
#include "display_device/windows/display_power.h"
#include "display_device/windows/settings_manager.h"
#include "display_device/windows/win_api_layer.h"
#include "display_device/windows/win_display_device.h"

namespace display_device {
std::unique_ptr<SettingsManagerInterface> makeSettingsManager(const SettingsManagerFactoryConfig &config) {
auto api_layer {std::make_shared<WinApiLayer>()};
return std::make_unique<SettingsManager>(
std::make_shared<WinDisplayDevice>(api_layer),
config.m_audio_context_api,
std::make_unique<PersistentState>(config.m_settings_persistence_api, config.m_throw_on_persistence_load_error),
WinWorkarounds {
.m_hdr_blank_delay = config.m_hdr_blank_delay
}
);
}

std::unique_ptr<DisplayPowerInterface> makeDisplayPower() {
return std::make_unique<WinDisplayPower>(std::make_shared<WinApiLayer>());
}
} // namespace display_device
6 changes: 4 additions & 2 deletions src/windows/win_display_device_general.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,11 @@ namespace display_device {
m_w_api->getHdrState(best_path)
};

available_devices.emplace_back(device_id, display_name, friendly_name, edid, info);
// Keep braced aggregate construction; emplace_back(args...) relies on parenthesized aggregate init, which older libc++ rejects.
available_devices.push_back(EnumeratedDevice {device_id, display_name, friendly_name, edid, info}); // NOSONAR
} else {
available_devices.emplace_back(device_id, display_name, friendly_name, edid, std::nullopt);
// Keep braced aggregate construction; emplace_back(args...) relies on parenthesized aggregate init, which older libc++ rejects.
available_devices.push_back(EnumeratedDevice {device_id, display_name, friendly_name, edid, std::nullopt}); // NOSONAR
}
}

Expand Down
38 changes: 38 additions & 0 deletions tests/unit/general/test_factory.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// system includes
#include <chrono>

// local includes
#include "display_device/factory.h"
#include "fixtures/fixtures.h"

namespace {
using namespace std::chrono_literals;

// Specialized TEST macro(s) for this test file
#define TEST_S(...) DD_MAKE_TEST(TEST, Factory, __VA_ARGS__)
} // namespace

TEST_S(MakeSettingsManager) {
display_device::SettingsManagerFactoryConfig config {
.m_hdr_blank_delay = 10ms
};

const auto settings_manager {display_device::makeSettingsManager(config)};

#if defined(_WIN32) || defined(__APPLE__)
ASSERT_NE(settings_manager, nullptr);
EXPECT_TRUE(settings_manager->resetPersistence());
#else
EXPECT_EQ(settings_manager, nullptr);
#endif
}

TEST_S(MakeDisplayPower) {
const auto display_power {display_device::makeDisplayPower()};

#if defined(_WIN32) || defined(__APPLE__)
EXPECT_NE(display_power, nullptr);
#else
EXPECT_EQ(display_power, nullptr);
#endif
}
Loading