Skip to content
Merged
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
14 changes: 13 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ jobs:
libxtst libxkbcommon libdrm libinput wayland-protocols benchmark \
xorg-xwayland pipewire cmake \
libavif libheif aom rav1e libdecor libxdamage \
luajit
luajit \
catch2 gcovr
- uses: actions/checkout@v6
with:
submodules: recursive
Expand All @@ -38,3 +39,14 @@ jobs:
# export CC=clang CXX=clang++
# meson setup build-clang/ -Dinput_emulation=disabled --werror --auto-features=enabled
# ninja -C build-clang/
- name: Run unit tests and collect coverage
run: |
export CC=gcc CXX=g++
meson configure -Db_coverage=true build-gcc
meson test -C build-gcc --suite gamescope -v
gcovr -f src --xml -o coverage.xml -s build-gcc
- name: Upload coverage report
uses: actions/upload-artifact@v7
with:
name: code coverage
path: coverage.xml
5 changes: 5 additions & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,11 @@ if get_option('enable_gamescope')
subdir('src')
endif

if get_option('enable_tests')
subdir('tests')
endif


# Handle default script/config/looks stuff
meson.add_install_script('default_extras_install.sh')

Expand Down
1 change: 1 addition & 0 deletions meson_options.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ option('input_emulation' , type: 'feature', description: 'Support for
option('enable_gamescope', type : 'boolean', value : true, description: 'Build Gamescope executable')
option('enable_gamescope_wsi_layer', type : 'boolean', value : true, description: 'Build Gamescope layer')
option('enable_openvr_support', type : 'boolean', value : true, description: 'OpenVR Integrations')
option('enable_tests', type : 'boolean', value : true, description: 'Build unit tests')
option('benchmark', type: 'feature', description: 'Benchmark tools')
17 changes: 1 addition & 16 deletions src/Script/Script.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@
#include "convar.h"
#include "color_helpers.h"
#include "../log.hpp"
#include "Utils/DirHelpers.h"

#include <filesystem>
#include <algorithm>

std::string_view GetHomeDir();

namespace gamescope
{
using namespace std::literals;
Expand All @@ -18,20 +17,6 @@ namespace gamescope
static ConVar<bool> cv_script_use_local_scripts{ "script_use_local_scripts", false, "Whether or not to use the local scripts (../config) as opposed to the ones in /etc/gamescope.d" };
static ConVar<bool> cv_script_use_user_scripts{ "script_use_user_scripts", true, "Whether or not to use user config scripts ($XDG_CONFIG_DIR/gamescope) at all." };

static std::string_view GetConfigDir()
{
static std::string s_sConfigDir = []() -> std::string
{
const char *pszConfigHome = getenv( "XDG_CONFIG_HOME" );
if ( pszConfigHome && *pszConfigHome )
return pszConfigHome;

return std::string{ GetHomeDir() } + "/.config";
}();

return s_sConfigDir;
}

static inline void PanicFunction( sol::optional<std::string> oMsg )
{
s_ScriptLog.errorf( "Lua is in a panic state and will now abort() the application" );
Expand Down
44 changes: 44 additions & 0 deletions src/Utils/DirHelpers.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#include "DirHelpers.h"

#include <sys/types.h>
#include <pwd.h>
#include <unistd.h>

namespace gamescope {
std::string_view GetHomeDir()
{
static std::string s_sHomeDir = []() -> std::string
{
const char *pszHomeDir = getenv( "HOME" );
if ( pszHomeDir )
return pszHomeDir;

return getpwuid( getuid() )->pw_dir;
}();
return s_sHomeDir;
}

std::string GetLocalUsrDir()
{
return std::string{ GetHomeDir() } + "/.local";
}

std::string GetUsrDir()
{
return "/usr";
}

std::string_view GetConfigDir()
{
static std::string s_sConfigDir = []() -> std::string
{
const char *pszConfigHome = getenv( "XDG_CONFIG_HOME" );
if ( pszConfigHome && *pszConfigHome )
return pszConfigHome;

return std::string{ GetHomeDir() } + "/.config";
}();

return s_sConfigDir;
}
}
11 changes: 11 additions & 0 deletions src/Utils/DirHelpers.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#pragma once

#include <string>

namespace gamescope
{
std::string_view GetHomeDir();
std::string GetLocalUsrDir();
std::string GetUsrDir();
std::string_view GetConfigDir();
}
2 changes: 2 additions & 0 deletions src/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ required_wlroots_features = ['xwayland']
src = [
'Backends/HeadlessBackend.cpp',
'Backends/WaylandBackend.cpp',
'Utils/DirHelpers.cpp',
'Utils/TempFiles.cpp',
'Utils/Version.cpp',
'Utils/Process.cpp',
Expand Down Expand Up @@ -206,6 +207,7 @@ gamescope_version = configure_file(
gamescope_core_src = [
'convar.cpp',
'log.cpp',
'Utils/DirHelpers.cpp',
'Utils/Process.cpp',
'Utils/Version.cpp',
]
Expand Down
37 changes: 4 additions & 33 deletions src/reshade_effect_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include "reshade_effect_manager.hpp"
#include "log.hpp"
#include "Utils/DirHelpers.h"

#include "steamcompmgr.hpp"

Expand All @@ -13,17 +14,12 @@
#include "gamescope-reshade-protocol.h"

#include "reshade_api_format.hpp"
#include "convar.h"

#include <stb_image.h>
#define STB_IMAGE_RESIZE_IMPLEMENTATION
#include <stb_image_resize.h>

#include <mutex>
#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>
#include <iostream>

// This is based on wl_array_for_each from `wayland-util.h` in the Wayland client library.
#define uint8_array_for_each(pos, data, size) \
Expand All @@ -36,31 +32,6 @@ static std::mutex g_runtimeUniformsMutex;

extern int g_nOutputRefresh;

const char *homedir;

std::string_view GetHomeDir()
{
static std::string s_sHomeDir = []() -> std::string
{
const char *pszHomeDir = getenv( "HOME" );
if ( pszHomeDir )
return pszHomeDir;

return getpwuid( getuid() )->pw_dir;
}();
return s_sHomeDir;
}

static std::string GetLocalUsrDir()
{
return std::string{ GetHomeDir() } + "/.local";
}

static std::string GetUsrDir()
{
return "/usr";
}

static LogScope reshade_log("gamescope_reshade");

///////////////
Expand Down Expand Up @@ -967,8 +938,8 @@ bool ReshadeEffectPipeline::init(CVulkanDevice *device, const ReshadeEffectKey &

std::string gamescope_reshade_share_path = "/share/gamescope/reshade";

std::string local_reshade_path = GetLocalUsrDir() + gamescope_reshade_share_path;
std::string global_reshade_path = GetUsrDir() + gamescope_reshade_share_path;
std::string local_reshade_path = gamescope::GetLocalUsrDir() + gamescope_reshade_share_path;
std::string global_reshade_path = gamescope::GetUsrDir() + gamescope_reshade_share_path;

pp.add_include_path(local_reshade_path + "/Shaders");
pp.add_include_path(global_reshade_path + "/Shaders");
Expand Down Expand Up @@ -1993,4 +1964,4 @@ void reshade_effect_manager_enable_effect()
void reshade_effect_manager_disable_effect()
{
gamescope_clear_reshade_effect();
}
}
16 changes: 16 additions & 0 deletions tests/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
catch2_dep = dependency('catch2-with-main', required: true)

srcdir = '../src'
unittest_src = []
foreach src : gamescope_core_src + ['Script/Script.cpp', 'convar_script.cpp']
unittest_src += srcdir / src
endforeach

test_convar = executable(
'test_convar',
unittest_src + ['test_convar.cpp'],
include_directories: [srcdir, sol2_include],
dependencies: [catch2_dep, luajit_dep, cap_dep, drm_dep, glm_dep, wlroots_dep],
cpp_args: gamescope_cpp_args,
)
test('convar', test_convar)
49 changes: 49 additions & 0 deletions tests/test_convar.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#include <catch2/catch_test_macros.hpp>

#include "convar.h"
#include "Script/Script.h"

using namespace gamescope;

TEST_CASE("ConVar", "[convar]") {
ConVar<bool> cv_bool_var {"foobar", true, "switch on and off"};
REQUIRE(cv_bool_var.GetName() == "foobar");
REQUIRE(cv_bool_var.GetDescription() == "switch on and off");
REQUIRE(cv_bool_var.Get() == true);
cv_bool_var.SetValue(false);
REQUIRE(cv_bool_var.Get() == false);

{
auto proxy = CScriptScopedLock().Manager().Gamescope().Convars.Base["foobar"];
REQUIRE(proxy.valid() == true);
ConVar<bool>* cv = proxy;
REQUIRE(cv->GetName() == "foobar");
REQUIRE(cv->GetDescription() == "switch on and off");
REQUIRE(cv->Get() == false);
cv->SetValue(true);
REQUIRE(cv_bool_var.Get() == true);
}

{
auto proxy = CScriptScopedLock().Manager().Gamescope().Convars.Base["nobar"];
REQUIRE(proxy.valid() == false);
}

{
auto proxy = CScriptScopedLock()->script("return gamescope.convars.foobar");
REQUIRE(proxy.valid() == true);
ConVar<bool>* cv = proxy;
REQUIRE(cv->GetName() == "foobar");
REQUIRE(cv->GetDescription() == "switch on and off");
REQUIRE(cv->Get() == true);
cv->SetValue(false);
REQUIRE(cv_bool_var.Get() == false);
}

{
auto proxy = CScriptScopedLock()->script("return gamescope.convars.nobar");
REQUIRE(proxy.valid() == true);
ConVar<bool>* cv = proxy;
REQUIRE(cv == nullptr);
}
}