Add code comments

This commit is contained in:
badaix 2025-02-03 21:05:57 +01:00
parent 2aa479adcd
commit fa8abcb26e
2 changed files with 108 additions and 71 deletions

View file

@ -1,6 +1,6 @@
/*** /***
This file is part of snapcast This file is part of snapcast
Copyright (C) 2014-2024 Johannes Pohl Copyright (C) 2014-2025 Johannes Pohl
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -129,9 +129,9 @@ void Config::save()
} }
ClientInfoPtr Config::getClientInfo(const std::string& clientId) const ClientInfoPtr Config::getClientInfo(const std::string& client_id) const
{ {
if (clientId.empty()) if (client_id.empty())
return nullptr; return nullptr;
std::lock_guard<std::recursive_mutex> lock(mutex_); std::lock_guard<std::recursive_mutex> lock(mutex_);
@ -139,7 +139,7 @@ ClientInfoPtr Config::getClientInfo(const std::string& clientId) const
{ {
for (auto client : group->clients) for (auto client : group->clients)
{ {
if (client->id == clientId) if (client->id == client_id)
return client; return client;
} }
} }
@ -148,7 +148,7 @@ ClientInfoPtr Config::getClientInfo(const std::string& clientId) const
} }
GroupPtr Config::addClientInfo(ClientInfoPtr client) GroupPtr Config::addClientInfo(const ClientInfoPtr& client)
{ {
std::lock_guard<std::recursive_mutex> lock(mutex_); std::lock_guard<std::recursive_mutex> lock(mutex_);
GroupPtr group = getGroupFromClient(client); GroupPtr group = getGroupFromClient(client);
@ -162,22 +162,22 @@ GroupPtr Config::addClientInfo(ClientInfoPtr client)
} }
GroupPtr Config::addClientInfo(const std::string& clientId) GroupPtr Config::addClientInfo(const std::string& client_id)
{ {
std::lock_guard<std::recursive_mutex> lock(mutex_); std::lock_guard<std::recursive_mutex> lock(mutex_);
ClientInfoPtr client = getClientInfo(clientId); ClientInfoPtr client = getClientInfo(client_id);
if (!client) if (!client)
client = make_shared<ClientInfo>(clientId); client = make_shared<ClientInfo>(client_id);
return addClientInfo(client); return addClientInfo(client);
} }
GroupPtr Config::getGroup(const std::string& groupId) const GroupPtr Config::getGroup(const std::string& group_id) const
{ {
std::lock_guard<std::recursive_mutex> lock(mutex_); std::lock_guard<std::recursive_mutex> lock(mutex_);
for (const auto& group : groups) for (const auto& group : groups)
{ {
if (group->id == groupId) if (group->id == group_id)
return group; return group;
} }
@ -185,14 +185,14 @@ GroupPtr Config::getGroup(const std::string& groupId) const
} }
GroupPtr Config::getGroupFromClient(const std::string& clientId) GroupPtr Config::getGroupFromClient(const std::string& client_id)
{ {
std::lock_guard<std::recursive_mutex> lock(mutex_); std::lock_guard<std::recursive_mutex> lock(mutex_);
for (const auto& group : groups) for (const auto& group : groups)
{ {
for (const auto& c : group->clients) for (const auto& c : group->clients)
{ {
if (c->id == clientId) if (c->id == client_id)
return group; return group;
} }
} }
@ -200,7 +200,7 @@ GroupPtr Config::getGroupFromClient(const std::string& clientId)
} }
GroupPtr Config::getGroupFromClient(ClientInfoPtr client) GroupPtr Config::getGroupFromClient(const ClientInfoPtr& client)
{ {
return getGroupFromClient(client->id); return getGroupFromClient(client->id);
} }
@ -234,7 +234,7 @@ json Config::getGroups() const
} }
void Config::remove(ClientInfoPtr client) void Config::remove(const ClientInfoPtr& client)
{ {
std::lock_guard<std::recursive_mutex> lock(mutex_); std::lock_guard<std::recursive_mutex> lock(mutex_);
auto group = getGroupFromClient(client); auto group = getGroupFromClient(client);
@ -246,7 +246,7 @@ void Config::remove(ClientInfoPtr client)
} }
void Config::remove(GroupPtr group, bool force) void Config::remove(const GroupPtr& group, bool force)
{ {
std::lock_guard<std::recursive_mutex> lock(mutex_); std::lock_guard<std::recursive_mutex> lock(mutex_);
if (!group) if (!group)

View file

@ -1,6 +1,6 @@
/*** /***
This file is part of snapcast This file is part of snapcast
Copyright (C) 2014-2024 Johannes Pohl Copyright (C) 2014-2025 Johannes Pohl
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -42,6 +42,7 @@ using ClientInfoPtr = std::shared_ptr<ClientInfo>;
using GroupPtr = std::shared_ptr<Group>; using GroupPtr = std::shared_ptr<Group>;
/// Config item base class
struct JsonConfigItem struct JsonConfigItem
{ {
/// Read config item from json object @p j /// Read config item from json object @p j
@ -70,9 +71,11 @@ protected:
} }
}; };
/// Volume config
struct Volume : public JsonConfigItem struct Volume : public JsonConfigItem
{ {
Volume(uint16_t _percent = 100, bool _muted = false) : percent(_percent), muted(_muted) /// c'tor
explicit Volume(uint16_t _percent = 100, bool _muted = false) : percent(_percent), muted(_muted)
{ {
} }
@ -90,18 +93,18 @@ struct Volume : public JsonConfigItem
return j; return j;
} }
uint16_t percent; uint16_t percent; ///< volume in percent
bool muted; bool muted; ///< muted
}; };
/// Host config
struct Host : public JsonConfigItem struct Host : public JsonConfigItem
{ {
Host() : name(""), mac(""), os(""), arch(""), ip("") /// c'tor
{ Host() = default;
}
/// Update name, os and arch to actual values
void update() void update()
{ {
name = getHostName(); name = getHostName();
@ -129,17 +132,18 @@ struct Host : public JsonConfigItem
return j; return j;
} }
std::string name; std::string name; ///< host name
std::string mac; std::string mac; ///< mac address
std::string os; std::string os; /// OS
std::string arch; std::string arch; /// CPU architecture
std::string ip; std::string ip; /// IP address
}; };
/// Client config
struct ClientConfig : public JsonConfigItem struct ClientConfig : public JsonConfigItem
{ {
ClientConfig() : name(""), volume(100), latency(0), instance(1) ClientConfig() : volume(100)
{ {
} }
@ -161,17 +165,18 @@ struct ClientConfig : public JsonConfigItem
return j; return j;
} }
std::string name; std::string name; ///< client name
Volume volume; Volume volume; ///< client volume
int32_t latency; int32_t latency{0}; ///< additional latency
size_t instance; size_t instance{1}; ///< instance id
}; };
/// Snapcast base config
struct Snapcast : public JsonConfigItem struct Snapcast : public JsonConfigItem
{ {
Snapcast(const std::string& _name = "", const std::string& _version = "") : name(_name), version(_version), protocolVersion(1) /// c'tor
explicit Snapcast(std::string _name = "", std::string _version = "") : name(std::move(_name)), version(std::move(_version))
{ {
} }
@ -193,23 +198,26 @@ struct Snapcast : public JsonConfigItem
return j; return j;
} }
std::string name; std::string name; ///< name of the client or server
std::string version; std::string version; ///< software version
int protocolVersion; int protocolVersion{1}; ///< binary protocol version
}; };
/// Snapclient config
struct Snapclient : public Snapcast struct Snapclient : public Snapcast
{ {
Snapclient(const std::string& _name = "", const std::string& _version = "") : Snapcast(_name, _version) explicit Snapclient(std::string _name = "", std::string _version = "") : Snapcast(std::move(_name), std::move(_version))
{ {
} }
}; };
/// Snapserver config
struct Snapserver : public Snapcast struct Snapserver : public Snapcast
{ {
Snapserver(const std::string& _name = "", const std::string& _version = "") : Snapcast(_name, _version), controlProtocolVersion(1) /// c'tor
explicit Snapserver(std::string _name = "", std::string _version = "") : Snapcast(std::move(_name), std::move(_version))
{ {
} }
@ -226,13 +234,14 @@ struct Snapserver : public Snapcast
return j; return j;
} }
int controlProtocolVersion; int controlProtocolVersion{1}; ///< control protocol version
}; };
/// Client config
struct ClientInfo : public JsonConfigItem struct ClientInfo : public JsonConfigItem
{ {
ClientInfo(const std::string& _clientId = "") : id(_clientId), connected(false) explicit ClientInfo(std::string _clientId = "") : id(std::move(_clientId))
{ {
lastSeen.tv_sec = 0; lastSeen.tv_sec = 0;
lastSeen.tv_usec = 0; lastSeen.tv_usec = 0;
@ -262,18 +271,20 @@ struct ClientInfo : public JsonConfigItem
return j; return j;
} }
std::string id; std::string id; ///< unique client id
Host host; Host host; ///< host
Snapclient snapclient; Snapclient snapclient; ///< Snapclient
ClientConfig config; ClientConfig config; ///< Client config
timeval lastSeen; timeval lastSeen; ///< last online
bool connected; bool connected{false}; ///< connected to server?
}; };
/// Group config
struct Group : public JsonConfigItem struct Group : public JsonConfigItem
{ {
Group(const ClientInfoPtr client = nullptr) : muted(false) /// c'tor
explicit Group(const ClientInfoPtr& client = nullptr)
{ {
if (client) if (client)
id = client->id; id = client->id;
@ -314,11 +325,12 @@ struct Group : public JsonConfigItem
return j; return j;
} }
ClientInfoPtr removeClient(const std::string& clientId) /// Remove client with id @p client_id from the group and @return the removed client
ClientInfoPtr removeClient(const std::string& client_id)
{ {
for (auto iter = clients.begin(); iter != clients.end(); ++iter) for (auto iter = clients.begin(); iter != clients.end(); ++iter)
{ {
if ((*iter)->id == clientId) if ((*iter)->id == client_id)
{ {
clients.erase(iter); clients.erase(iter);
return (*iter); return (*iter);
@ -327,7 +339,8 @@ struct Group : public JsonConfigItem
return nullptr; return nullptr;
} }
ClientInfoPtr removeClient(ClientInfoPtr client) /// Remove client @p client from the group and @return the removed client
ClientInfoPtr removeClient(const ClientInfoPtr& client)
{ {
if (!client) if (!client)
return nullptr; return nullptr;
@ -335,17 +348,19 @@ struct Group : public JsonConfigItem
return removeClient(client->id); return removeClient(client->id);
} }
ClientInfoPtr getClient(const std::string& clientId) /// @return client with id @p client_id
ClientInfoPtr getClient(const std::string& client_id)
{ {
for (const auto& client : clients) for (const auto& client : clients)
{ {
if (client->id == clientId) if (client->id == client_id)
return client; return client;
} }
return nullptr; return nullptr;
} }
void addClient(ClientInfoPtr client) /// Add client @p client
void addClient(const ClientInfoPtr& client)
{ {
if (!client) if (!client)
return; return;
@ -365,56 +380,78 @@ struct Group : public JsonConfigItem
*/ */
} }
/// @return if the group is empty
bool empty() const bool empty() const
{ {
return clients.empty(); return clients.empty();
} }
std::string name; std::string name; ///< group name
std::string id; std::string id; ///< group id
std::string streamId; std::string streamId; ///< stream id assigned to this group
bool muted; bool muted{false}; ///< is the group muted?
std::vector<ClientInfoPtr> clients; std::vector<ClientInfoPtr> clients; ///< list of clients in this group
}; };
/// Runtime configuration
class Config class Config
{ {
public: public:
/// singleton c'tor
static Config& instance() static Config& instance()
{ {
static Config instance_; static Config instance_;
return instance_; return instance_;
} }
ClientInfoPtr getClientInfo(const std::string& clientId) const; /// @return client from @p client_id
GroupPtr addClientInfo(const std::string& clientId); ClientInfoPtr getClientInfo(const std::string& client_id) const;
GroupPtr addClientInfo(ClientInfoPtr client); /// Get or create client with id @p client_id and return its group (create a new group for new clients)
void remove(ClientInfoPtr client); /// @return the client's group
void remove(GroupPtr group, bool force = false); GroupPtr addClientInfo(const std::string& client_id);
/// Add client @p client to a group
/// @return the client's group: exising or newly created
GroupPtr addClientInfo(const ClientInfoPtr& client);
/// Remove client @p client from group
void remove(const ClientInfoPtr& client);
/// Remove group @group, @p force removal of a non-empty group
void remove(const GroupPtr& group, bool force = false);
// GroupPtr removeFromGroup(const std::string& groupId, const std::string& clientId); // GroupPtr removeFromGroup(const std::string& groupId, const std::string& clientId);
// GroupPtr setGroupForClient(const std::string& groupId, const std::string& clientId); // GroupPtr setGroupForClient(const std::string& groupId, const std::string& clientId);
GroupPtr getGroupFromClient(const std::string& clientId); /// @return grouo from client with id @client_id
GroupPtr getGroupFromClient(ClientInfoPtr client); GroupPtr getGroupFromClient(const std::string& client_id);
GroupPtr getGroup(const std::string& groupId) const; /// @return group from @p client
GroupPtr getGroupFromClient(const ClientInfoPtr& client);
/// @return group with id @p group_id
GroupPtr getGroup(const std::string& group_id) const;
/// @return groups with client as json
json getGroups() const; json getGroups() const;
/// @return complete server status, including @p streams
json getServerStatus(const json& streams) const; json getServerStatus(const json& streams) const;
/// Save config to file (json format)
void save(); void save();
/// Set directory and user/group of persistent "server.json"
void init(const std::string& root_directory = "", const std::string& user = "", const std::string& group = ""); void init(const std::string& root_directory = "", const std::string& user = "", const std::string& group = "");
/// List of groups
std::vector<GroupPtr> groups; std::vector<GroupPtr> groups;
/// to protect members
std::mutex& getMutex(); std::mutex& getMutex();
private: private:
/// c'tor
Config() = default; Config() = default;
/// d'tor
~Config(); ~Config();
mutable std::recursive_mutex mutex_;
std::mutex client_mutex_; mutable std::recursive_mutex mutex_; ///< to protect members
std::string filename_; std::mutex client_mutex_; ///< returned by "getMutex()", TODO: check this
std::string filename_; ///< filename to persist the config
}; };