Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backported Time-Sync into upstream #22

Merged
merged 14 commits into from
May 31, 2024
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
FROM devkitpro/devkitppc

COPY --from=ghcr.io/wiiu-env/wiiupluginsystem:20230719 /artifacts $DEVKITPRO
COPY --from=ghcr.io/wiiu-env/libnotifications:20230621 /artifacts $DEVKITPRO
COPY --from=ghcr.io/wiiu-env/wiiupluginsystem:20240505 /artifacts $DEVKITPRO
COPY --from=ghcr.io/wiiu-env/libnotifications:20240426 /artifacts $DEVKITPRO

RUN git config --global --add safe.directory /project

Expand Down
65 changes: 33 additions & 32 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ WUT_ROOT := $(DEVKITPRO)/wut
# PLUGIN_AUTHOR sets the author of the plugin.
# PLUGIN_LICENSE sets the license of the plugin.
#-------------------------------------------------------------------------------
PLUGIN_NAME := "Wii U Time Sync"
PLUGIN_DESCRIPTION := "A plugin that synchronizes a Wii U\'s clock to the Internet."
PLUGIN_VERSION := "v2.1.1"
PLUGIN_AUTHOR := "Nightkingale, Daniel K. O."
PLUGIN_LICENSE := "MIT"
PLUGIN_NAME := Wii U Time Sync
PLUGIN_DESCRIPTION := A plugin that synchronizes the system clock to the Internet.
PLUGIN_VERSION := v2.1.1
PLUGIN_AUTHOR := Nightkingale, Daniel K. O.
PLUGIN_LICENSE := MIT

#-------------------------------------------------------------------------------
# TARGET is the name of the output.
Expand All @@ -33,11 +33,11 @@ PLUGIN_LICENSE := "MIT"
# DATA is a list of directories containing data files.
# INCLUDES is a list of directories containing header files.
#-------------------------------------------------------------------------------
TARGET := Wii_U_Time_Sync
BUILD := build
SOURCES := source source/wupsxx
DATA := data
INCLUDES := include include/wupsxx
TARGET := Wii_U_Time_Sync
BUILD := build
SOURCES := source source/net source/wupsxx
DATA := data
INCLUDES := include

#-------------------------------------------------------------------------------
# DEBUG sets the debug flag for the plugin.
Expand All @@ -48,40 +48,41 @@ INCLUDES := include include/wupsxx
DEBUG := 0

# This appends the git hash to the version string.
ifeq ($(DEBUG), 1)
ifeq ($(DEBUG),1)
GIT_HASH := $(shell git rev-parse --short HEAD)
PLUGIN_VERSION := $(PLUGIN_VERSION)-$(GIT_HASH)
endif

#-------------------------------------------------------------------------------
# options for code generation
#-------------------------------------------------------------------------------
WARN_FLAGS := -Wall -Wextra -Wundef -Wpointer-arith -Wcast-align
WARN_FLAGS := -Wall -Wextra -Wundef -Wpointer-arith -Wcast-align

OPTFLAGS := -O2 -fipa-pta -ffunction-sections
OPTFLAGS := -O2 -fipa-pta -ffunction-sections

CFLAGS := $(WARN_FLAGS) $(OPTFLAGS) $(MACHDEP)
CFLAGS := $(WARN_FLAGS) $(OPTFLAGS) $(MACHDEP)

CXXFLAGS := $(CFLAGS) -std=c++23
CXXFLAGS := $(CFLAGS) -std=c++23

DEFINES := '-DPLUGIN_NAME="$(PLUGIN_NAME)"' \
'-DPLUGIN_DESCRIPTION="$(PLUGIN_DESCRIPTION)"' \
'-DPLUGIN_VERSION="$(PLUGIN_VERSION)"' \
'-DPLUGIN_AUTHOR="$(PLUGIN_AUTHOR)"' \
'-DPLUGIN_LICENSE="$(PLUGIN_LICENSE)"'

# Note: INCLUDE will be defined later, so CPPFLAGS has to be of the recursive flavor.
CPPFLAGS = $(INCLUDE) -D__WIIU__ -D__WUT__ -D__WUPS__ \
-DPLUGIN_NAME=\"$(PLUGIN_NAME)\" \
-DPLUGIN_DESCRIPTION=\"$(PLUGIN_DESCRIPTION)\" \
-DPLUGIN_VERSION=\"$(PLUGIN_VERSION)\" \
-DPLUGIN_AUTHOR=\"$(PLUGIN_AUTHOR)\" \
-DPLUGIN_LICENSE=\"$(PLUGIN_LICENSE)\"

ASFLAGS := -g $(ARCH)

LDFLAGS = -g \
$(ARCH) \
$(RPXSPECS) \
$(WUPSSPECS) \
-Wl,-Map,$(notdir $*.map) \
$(OPTFLAGS)

LIBS := -lnotifications -lwups -lwut
CPPFLAGS = $(INCLUDE) -D__WIIU__ -D__WUT__ -D__WUPS__ $(DEFINES)

ASFLAGS := -g $(ARCH)

LDFLAGS = -g \
$(ARCH) \
$(RPXSPECS) \
$(WUPSSPECS) \
-Wl,-Map,$(notdir $*.map) \
$(CXXFLAGS)

LIBS := -lnotifications -lwups -lwut

#-------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level
Expand Down
117 changes: 117 additions & 0 deletions include/async_queue.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
// SPDX-License-Identifier: MIT

#ifndef ASYNC_QUEUE_HPP
#define ASYNC_QUEUE_HPP

#include <condition_variable>
#include <mutex>
#include <optional>
#include <queue>
#include <utility> // forward(), move()


template<typename T,
typename Q = std::queue<T>>
class async_queue {

std::mutex mutex;
std::condition_variable empty_cond;
Q queue;
bool should_stop = false;

public:

struct stop_request {};

// Makes the pool usable again after a stop().
void
reset()
{
std::lock_guard guard{mutex};
should_stop = false;
}


// This will make all future pop() calls throw a stop_request{}.
// It also wakes up all threads waiting on empty_cond.
void
stop()
{
std::lock_guard guard{mutex};
should_stop = true;
empty_cond.notify_all(); // make sure all threads can see the updated flag
}


bool
is_stopping() const
{
std::lock_guard guard{mutex};
return should_stop;
}


bool
empty()
const
{
std::lock_guard guard{mutex};
return queue.empty();
}


template<typename U>
void
push(U&& x)
{
std::lock_guard guard{mutex};
queue.push(std::forward<U>(x));
empty_cond.notify_one();
}


T
pop()
{
std::unique_lock guard{mutex};
// Stop waiting if a stop was requested, or the queue as data.
empty_cond.wait(guard, [this] { return should_stop || !queue.empty(); });
if (should_stop)
throw stop_request{};
T result = std::move(queue.front());
queue.pop();
return result;
}


template<typename U>
bool
try_push(U&& x)
{
std::unique_lock guard{mutex, std::try_to_lock};
if (!guard)
return false;
queue.push(std::forward<U>(x));
return true;
}


std::optional<T>
try_pop()
{
std::unique_lock guard{mutex, std::try_to_lock};
if (!guard)
return {};
if (queue.empty())
return {};
if (should_stop)
throw stop_request{};
T result = std::move(queue.front());
queue.pop();
return result;
}

};


#endif
54 changes: 41 additions & 13 deletions include/cfg.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,64 @@
#ifndef CFG_HPP
#define CFG_HPP

#include <chrono>
#include <string>


namespace cfg {

namespace key {
extern const char* hours;
extern const char* minutes;
extern const char* auto_tz;
extern const char* msg_duration;
extern const char* notify;
extern const char* server;
extern const char* sync;
extern const char* threads;
extern const char* tolerance;
extern const char* utc_offset;
}

extern int hours;
extern int minutes;
extern int msg_duration;
extern bool notify;
extern std::string server;
extern bool sync;
extern int tolerance;

namespace label {
extern const char* auto_tz;
extern const char* msg_duration;
extern const char* notify;
extern const char* server;
extern const char* sync;
extern const char* threads;
extern const char* tolerance;
extern const char* utc_offset;
}

namespace defaults {
extern const bool auto_tz;
extern const int msg_duration;
extern const int notify;
extern const std::string server;
extern const bool sync;
extern const int threads;
extern const int tolerance;
}

void load();

extern bool auto_tz;
extern int msg_duration;
extern int notify;
extern std::string server;
extern bool sync;
extern int threads;
extern int tolerance;
extern std::chrono::minutes utc_offset;


void load();
void reload();
void save();
void migrate_old_config();

// send the hours and minutes variables to the utc module
void update_utc_offset();
std::chrono::minutes get_utc_offset();
void set_utc_offset(std::chrono::minutes tz_offset);

}
} // namespace cfg

#endif
42 changes: 42 additions & 0 deletions include/clock_item.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// SPDX-License-Identifier: MIT

#ifndef CLOCK_ITEM_HPP
#define CLOCK_ITEM_HPP

#include <map>
#include <memory> // unique_ptr<>
#include <string>

#include "wupsxx/text_item.hpp"


struct clock_item : wups::config::text_item {

struct server_info {
text_item* name = nullptr;
text_item* correction = nullptr;
text_item* latency = nullptr;
};


std::string now_str;
std::string stats_str;
std::map<std::string, server_info> server_infos;

clock_item();

static
std::unique_ptr<clock_item> create();


void on_input(WUPSConfigSimplePadData input,
WUPS_CONFIG_SIMPLE_INPUT repeat) override;


void refresh_now_str();

void run();

};

#endif
6 changes: 1 addition & 5 deletions include/config_screen.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,6 @@
#include "wupsxx/category.hpp"


struct config_screen : wups::category {

config_screen();

};
wups::config::category make_config_screen();

#endif
9 changes: 4 additions & 5 deletions include/core.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,20 @@
#ifndef CORE_HPP
#define CORE_HPP

#include <utility> // pair<>
#include <string>
#include <utility> // pair<>

#include <netinet/in.h> // struct sockaddr_in
#include "net/address.hpp"


namespace core {

std::pair<double, double> ntp_query(struct sockaddr_in address);
std::pair<double, double> ntp_query(net::address address);

void sync_clock();
void run();

std::string local_clock_to_string();

} // namespace core


#endif
2 changes: 1 addition & 1 deletion include/http_client.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@

#include <string>


namespace http {

std::string get(const std::string& url);

} // namespace http


#endif
Loading