improved messages and structure of the program
This commit is contained in:
parent
454e86a982
commit
3c044249f4
31 changed files with 91 additions and 77 deletions
BIN
assets/Queen - Another One Bites the Dust.mp3
Normal file
BIN
assets/Queen - Another One Bites the Dust.mp3
Normal file
Binary file not shown.
|
@ -7,15 +7,20 @@
|
|||
#include "RemotePeer.hpp"
|
||||
|
||||
|
||||
struct Context {
|
||||
int socket = -1;
|
||||
addrinfo* broadcastAddressInfo = nullptr;
|
||||
std::shared_ptr<RemotePeer> server = nullptr;
|
||||
/**
|
||||
* Information about the current state of our machine.
|
||||
* Used everywhere to determinate how to behave.
|
||||
*/
|
||||
class Context {
|
||||
public:
|
||||
int socket = -1; /// current socket file descriptor, used to communicate
|
||||
addrinfo* broadcastAddressInfo = nullptr; /// address used to broadcast messages
|
||||
std::shared_ptr<RemotePeer> server = nullptr; /// peer currently used as the server
|
||||
|
||||
Peer me;
|
||||
Peer me; /// information about our own machine
|
||||
std::map<
|
||||
std::uint32_t,
|
||||
std::shared_ptr<RemotePeer>
|
||||
> remotePeers {};
|
||||
std::chrono::high_resolution_clock::time_point latestPeerDiscovery;
|
||||
> remotePeers {}; /// information about other machines
|
||||
std::chrono::high_resolution_clock::time_point latestPeerDiscovery; /// time of the latest discovered machine
|
||||
};
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#include "EventManager.hpp"
|
||||
#include "Manager.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
|
@ -11,20 +11,19 @@
|
|||
#include <random>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include "events/types.hpp"
|
||||
#include "events/audio/AudioEvent.hpp"
|
||||
#include "events/info/InfoEvent.hpp"
|
||||
#include "events/pong/PongEvent.hpp"
|
||||
#include "events/search/SearchEvent.hpp"
|
||||
#include "behavior/events/types.hpp"
|
||||
#include "behavior/events/audio/AudioEvent.hpp"
|
||||
#include "behavior/events/info/InfoEvent.hpp"
|
||||
#include "behavior/events/pong/PongEvent.hpp"
|
||||
#include "behavior/events/search/SearchEvent.hpp"
|
||||
#include "packets/base/Packet.hpp"
|
||||
#include "tasks/client/ClientTask.hpp"
|
||||
#include "tasks/server/ServerTask.hpp"
|
||||
#include "tasks/undefined/UndefinedTask.hpp"
|
||||
#include "behavior/tasks/client/ClientTask.hpp"
|
||||
#include "behavior/tasks/server/ServerTask.hpp"
|
||||
#include "behavior/tasks/undefined/UndefinedTask.hpp"
|
||||
|
||||
|
||||
EventManager::EventManager(const std::string& address, const std::string& port, const bool useIpv6) {
|
||||
std::cout << "address: " << address << " (" << (useIpv6 ? "IPv6" : "IPv4") << ")" << std::endl;
|
||||
std::cout << "port: " << port << std::endl;
|
||||
Manager::Manager(const std::string& address, const std::string& port, const bool useIpv6) {
|
||||
std::cout << "Broadcast address: " << address << ":" << port << " (" << (useIpv6 ? "IPv6" : "IPv4") << ")" << std::endl;
|
||||
|
||||
// register the different events type
|
||||
this->eventRegistry = {
|
||||
|
@ -121,10 +120,10 @@ EventManager::EventManager(const std::string& address, const std::string& port,
|
|||
}
|
||||
|
||||
|
||||
void EventManager::loop() {
|
||||
void Manager::loop() {
|
||||
// run an event receiver and sender
|
||||
this->senderThread = std::thread(&EventManager::loopSender, this);
|
||||
this->receiverThread = std::thread(&EventManager::loopReceiver, this);
|
||||
this->senderThread = std::thread(&Manager::loopSender, this);
|
||||
this->receiverThread = std::thread(&Manager::loopReceiver, this);
|
||||
|
||||
this->senderThread.join();
|
||||
this->receiverThread.join();
|
||||
|
@ -133,9 +132,9 @@ void EventManager::loop() {
|
|||
}
|
||||
|
||||
|
||||
void EventManager::loopSender() {
|
||||
void Manager::loopSender() {
|
||||
while (true) {
|
||||
std::cout << "[Sender] Status: " + std::to_string(static_cast<int>(this->context.me.status)) << std::endl;
|
||||
std::cout << "[Sender] Handling status: " + std::to_string(static_cast<int>(this->context.me.status)) << std::endl;
|
||||
|
||||
// get the corresponding task class
|
||||
std::shared_ptr<drp::task::BaseTask> task;
|
||||
|
@ -152,7 +151,7 @@ void EventManager::loopSender() {
|
|||
}
|
||||
|
||||
|
||||
void EventManager::loopReceiver() {
|
||||
void Manager::loopReceiver() {
|
||||
// prepare space for the sender address
|
||||
sockaddr_storage fromAddress {};
|
||||
socklen_t fromAddressLength = sizeof(fromAddress);
|
||||
|
@ -185,10 +184,12 @@ void EventManager::loopReceiver() {
|
|||
try {
|
||||
event = this->eventRegistry.at(static_cast<drp::event::EventType>(packetContent.eventType));
|
||||
} catch (const std::out_of_range& exception) {
|
||||
std::cerr << "Unsupported event type." << std::endl;
|
||||
std::cerr << "[Receiver] Unsupported event type." << std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
std::cout << "[Receiver] handling event: " << std::to_string(packetContent.eventType) << std::endl;
|
||||
|
||||
// ask the event class to handle the event
|
||||
event->handle(
|
||||
this->context,
|
|
@ -5,15 +5,20 @@
|
|||
#include <thread>
|
||||
|
||||
#include "Context.hpp"
|
||||
#include "events/types.hpp"
|
||||
#include "events/base/BaseEvent.hpp"
|
||||
#include "tasks/types.hpp"
|
||||
#include "tasks/base/BaseTask.hpp"
|
||||
#include "behavior/events/types.hpp"
|
||||
#include "behavior/events/base/BaseEvent.hpp"
|
||||
#include "behavior/tasks/types.hpp"
|
||||
#include "behavior/tasks/base/BaseTask.hpp"
|
||||
|
||||
|
||||
class EventManager {
|
||||
/**
|
||||
* The Manager.
|
||||
* Manage how should the program behave depending on its current state, or the message it receive.
|
||||
*/
|
||||
// TODO(Faraphel): could be split in two part.
|
||||
class Manager {
|
||||
public:
|
||||
EventManager(const std::string& address, const std::string& port, bool useIpv6 = false);
|
||||
Manager(const std::string& address, const std::string& port, bool useIpv6 = false);
|
||||
|
||||
void loop();
|
||||
void loopSender();
|
|
@ -3,7 +3,10 @@
|
|||
#include <chrono>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include "tasks/types.hpp"
|
||||
#include "behavior/tasks/types.hpp"
|
||||
|
||||
|
||||
// TODO(Faraphel): should be split in multiple files.
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
#include <iostream>
|
||||
#include <bits/unique_lock.h>
|
||||
|
||||
#include "../../packets/audio/AudioPacketData.hpp"
|
||||
#include "../../packets/base/PacketData.hpp"
|
||||
#include "packets/audio/AudioPacketData.hpp"
|
||||
#include "packets/base/PacketData.hpp"
|
||||
|
||||
|
||||
namespace drp::event {
|
||||
|
@ -27,7 +27,7 @@ AudioEvent::~AudioEvent() {
|
|||
Pa_StopStream(this->stream);
|
||||
// close the audio stream
|
||||
if (const PaError error = Pa_CloseStream(this->stream))
|
||||
std::cerr << "[Client] Could not close the stream: " << std::string(Pa_GetErrorText(error)) << std::endl;
|
||||
std::cerr << "[Event - Audio] Could not close the stream: " << std::string(Pa_GetErrorText(error)) << std::endl;
|
||||
}
|
||||
|
||||
|
||||
|
@ -71,7 +71,7 @@ void AudioEvent::updateAudioStream(const int channels, const std::uint32_t sampl
|
|||
nullptr,
|
||||
nullptr
|
||||
) != paNoError)
|
||||
throw std::runtime_error("[Client] Could not open the stream: " + std::string(Pa_GetErrorText(error)));
|
||||
throw std::runtime_error("[Event - Audio] Could not open the stream: " + std::string(Pa_GetErrorText(error)));
|
||||
|
||||
// update the new audio values
|
||||
this->streamChannels = channels;
|
||||
|
@ -101,7 +101,7 @@ void AudioEvent::loopPlay() {
|
|||
std::this_thread::sleep_until(audioPacket.timePlay);
|
||||
|
||||
auto cTimePlay = std::chrono::high_resolution_clock::to_time_t(audioPacket.timePlay);
|
||||
std::cout << "[Client] Playing: " << std::ctime(&cTimePlay) << std::endl;
|
||||
std::cout << "[Event - Audio] Playing: " << std::ctime(&cTimePlay) << std::endl;
|
||||
|
||||
// immediately stop playing music
|
||||
// this avoids an offset created if this client's clock is too ahead of the others
|
||||
|
@ -110,7 +110,7 @@ void AudioEvent::loopPlay() {
|
|||
|
||||
// play the new audio data
|
||||
if (const int error = Pa_StartStream(this->stream) != paNoError)
|
||||
throw std::runtime_error("[Client] Could not start the PortAudio stream: " + std::string(Pa_GetErrorText(error)));
|
||||
throw std::runtime_error("[Event - Audio] Could not start the PortAudio stream: " + std::string(Pa_GetErrorText(error)));
|
||||
|
||||
// write the new audio data into the audio buffer
|
||||
const int error = Pa_WriteStream(
|
||||
|
@ -125,10 +125,10 @@ void AudioEvent::loopPlay() {
|
|||
// the output might be very slightly underflowed,
|
||||
// causing a very small period where no noise will be played.
|
||||
case paOutputUnderflowed:
|
||||
std::cerr << "[Client] Underflowed!" << std::endl;
|
||||
break;
|
||||
|
||||
default:
|
||||
std::cerr << "[Client] Could not write to the audio stream: " << Pa_GetErrorText(error) << std::endl;
|
||||
std::cerr << "[Event - Audio] Could not write to the audio stream: " << Pa_GetErrorText(error) << std::endl;
|
||||
}
|
||||
|
||||
// remove the audio chunk
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../packets/audio/AudioPacketData.hpp"
|
||||
#include "packets/audio/AudioPacketData.hpp"
|
||||
|
||||
|
||||
namespace drp::event {
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../packets/base/Packet.hpp"
|
||||
#include "../../Context.hpp"
|
||||
#include "packets/base/Packet.hpp"
|
||||
#include "Context.hpp"
|
||||
|
||||
|
||||
namespace drp::event {
|
|
@ -3,7 +3,7 @@
|
|||
#include <iostream>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include "../../packets/info/InfoPacketData.hpp"
|
||||
#include "packets/info/InfoPacketData.hpp"
|
||||
|
||||
|
||||
namespace drp::event {
|
||||
|
@ -15,7 +15,7 @@ void InfoEvent::handle(
|
|||
const sockaddr_storage& fromAddress,
|
||||
const socklen_t fromAddressLength
|
||||
) {
|
||||
std::cout << "Received peer information." << std::endl;
|
||||
std::cout << "[Event - Info] Received peer information." << std::endl;
|
||||
|
||||
// get the peer information
|
||||
const auto packetData = packet::info::InfoPacketData::fromGeneric(content);
|
|
@ -12,7 +12,7 @@ void PongEvent::handle(
|
|||
const sockaddr_storage& fromAddress,
|
||||
const socklen_t fromAddressLength
|
||||
) {
|
||||
std::cout << "[Receiver] Pong." << std::endl;
|
||||
std::cout << "[Event - Pong] Pong." << std::endl;
|
||||
}
|
||||
|
||||
|
|
@ -6,8 +6,8 @@
|
|||
#include <iostream>
|
||||
#include <ostream>
|
||||
|
||||
#include "../../packets/base/SecurityMode.hpp"
|
||||
#include "../../packets/info/InfoPacketData.hpp"
|
||||
#include "packets/base/SecurityMode.hpp"
|
||||
#include "packets/info/InfoPacketData.hpp"
|
||||
|
||||
|
||||
namespace drp {
|
||||
|
@ -42,11 +42,11 @@ void event::SearchEvent::handle(
|
|||
reinterpret_cast<const sockaddr*>(&fromAddress),
|
||||
fromAddressLength
|
||||
) == -1) {
|
||||
std::cerr << "[Receiver] Could not send information: " << strerror(errno) << std::endl;
|
||||
std::cerr << "[Event - Search] Could not send information: " << strerror(errno) << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
std::cout << "[Receiver] Sent back information." << std::endl;
|
||||
std::cout << "[Event - Search] Sent back information." << std::endl;
|
||||
}
|
||||
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../Context.hpp"
|
||||
#include "Context.hpp"
|
||||
|
||||
|
||||
namespace drp::task {
|
|
@ -22,7 +22,7 @@ void ClientTask::handle(Context& context) {
|
|||
// TODO(Faraphel): only once ?
|
||||
FILE* chronyProcess = popen(("chronyc add server " + std::string(host) + " 2>&1").c_str(), "r");
|
||||
if (pclose(chronyProcess) == -1)
|
||||
std::cerr << "Failed to connect to chrony server !" << std::endl;
|
||||
std::cerr << "[Task - Client] Failed to connect to chrony server !" << std::endl;
|
||||
|
||||
// TODO(Faraphel): check if the server is still reachable.
|
||||
// if connection lost, go back to undefined mode.
|
|
@ -10,10 +10,10 @@
|
|||
#include <thread>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include "../../packets/audio/AudioPacketData.hpp"
|
||||
#include "../../packets/base/Packet.hpp"
|
||||
#include "../../packets/base/SecurityMode.hpp"
|
||||
#include "../../utils/audio.hpp"
|
||||
#include "packets/audio/AudioPacketData.hpp"
|
||||
#include "packets/base/Packet.hpp"
|
||||
#include "packets/base/SecurityMode.hpp"
|
||||
#include "utils/audio.hpp"
|
||||
|
||||
|
||||
namespace drp::task {
|
||||
|
@ -28,7 +28,7 @@ ServerTask::ServerTask() {
|
|||
int error;
|
||||
this->mpgHandle = mpg123_new(nullptr, &error);
|
||||
if (this->mpgHandle == nullptr)
|
||||
throw std::runtime_error("[Server] Could not create a mpg123 handle.");
|
||||
throw std::runtime_error("[Task - Server] Could not create a mpg123 handle.");
|
||||
|
||||
// open the mp3 file
|
||||
// TODO(Faraphel): mp3 file as argument
|
||||
|
@ -36,7 +36,7 @@ ServerTask::ServerTask() {
|
|||
this->mpgHandle,
|
||||
"./assets/Queen - Another One Bites the Dust.mp3"
|
||||
) != MPG123_OK)
|
||||
throw std::runtime_error("[Server] Could not open file.");
|
||||
throw std::runtime_error("[Task - Server] Could not open file.");
|
||||
|
||||
// get the format of the file
|
||||
if (mpg123_getformat(
|
||||
|
@ -45,7 +45,7 @@ ServerTask::ServerTask() {
|
|||
&this->channels,
|
||||
&this->encoding
|
||||
) != MPG123_OK)
|
||||
throw std::runtime_error("[Server] Could not get the format of the file.");
|
||||
throw std::runtime_error("[Task - Server] Could not get the format of the file.");
|
||||
}
|
||||
|
||||
ServerTask::~ServerTask() {
|
||||
|
@ -79,7 +79,7 @@ void ServerTask::handle(Context& context) {
|
|||
std::size(audioPacket.content),
|
||||
&done
|
||||
) != MPG123_OK) {
|
||||
std::cerr << "[Server] Could not read audio data from file." << std::endl;
|
||||
std::cerr << "[Task - Server] Could not read audio data from file." << std::endl;
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
return;
|
||||
}
|
||||
|
@ -109,12 +109,12 @@ void ServerTask::handle(Context& context) {
|
|||
context.broadcastAddressInfo->ai_addr,
|
||||
context.broadcastAddressInfo->ai_addrlen
|
||||
) == -1) {
|
||||
std::cerr << "[Server] Could not send audio packet: " << strerror(errno) << std::endl;
|
||||
std::cerr << "[Task - Server] Could not send audio packet: " << strerror(errno) << std::endl;
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
return;
|
||||
}
|
||||
|
||||
std::cout << "[Server] Sent: " << done << " bytes" << std::endl;
|
||||
std::cout << "[Task - Server] Sent: " << done << " bytes" << std::endl;
|
||||
|
||||
// wait for the duration of the audio chunk
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(static_cast<std::uint64_t>(
|
|
@ -9,17 +9,17 @@
|
|||
#include <algorithm>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include "../../Context.hpp"
|
||||
#include "../../packets/base/Packet.hpp"
|
||||
#include "../../packets/base/SecurityMode.hpp"
|
||||
#include "../../packets/search/SearchPacketData.hpp"
|
||||
#include "Context.hpp"
|
||||
#include "packets/base/Packet.hpp"
|
||||
#include "packets/base/SecurityMode.hpp"
|
||||
#include "packets/search/SearchPacketData.hpp"
|
||||
|
||||
|
||||
namespace drp::task {
|
||||
|
||||
|
||||
void UndefinedTask::handle(Context& context) {
|
||||
std::cout << "List of peers: " << std::endl;
|
||||
std::cout << "[Task - Undefined] List of peers: " << std::endl;
|
||||
for (const auto& peer : context.remotePeers)
|
||||
std::cout <<
|
||||
"\tPeer(id=" << peer.second->information.id << ", " <<
|
||||
|
@ -63,7 +63,7 @@ void UndefinedTask::handle(Context& context) {
|
|||
|
||||
// check if we are this peer
|
||||
if (context.me.id == serverCandidate->first) {
|
||||
std::cout << "Becoming server..." << std::endl;
|
||||
std::cout << "[Task - Undefined] Becoming server..." << std::endl;
|
||||
// set ourselves as the server
|
||||
context.server = serverCandidate->second;
|
||||
context.me.status = TaskType::SERVER;
|
||||
|
@ -87,7 +87,7 @@ void UndefinedTask::handle(Context& context) {
|
|||
|
||||
packet.setContent(packetData.toGeneric());
|
||||
|
||||
std::cout << "Looking for new peers." << std::endl;
|
||||
std::cout << "[Task - Undefined] Looking for new peers." << std::endl;
|
||||
|
||||
// send the search message
|
||||
if (sendto(
|
||||
|
@ -98,7 +98,7 @@ void UndefinedTask::handle(Context& context) {
|
|||
context.broadcastAddressInfo->ai_addr,
|
||||
context.broadcastAddressInfo->ai_addrlen
|
||||
) == -1)
|
||||
std::cerr << "[Sender] Could not send search event: " << strerror(errno) << std::endl;
|
||||
std::cerr << "[Task - Undefined] Could not send search event: " << strerror(errno) << std::endl;
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
#include <portaudio.h>
|
||||
#include <stdexcept>
|
||||
#include "argparse/argparse.hpp"
|
||||
#include "EventManager.hpp"
|
||||
#include "Manager.hpp"
|
||||
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
|
@ -26,7 +26,7 @@ int main(int argc, char* argv[]) {
|
|||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
auto eventManager = EventManager(
|
||||
auto eventManager = Manager(
|
||||
parser.get<std::string>("--host"),
|
||||
parser.get<std::string>("--port"),
|
||||
parser.get<bool>("-6")
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#include <chrono>
|
||||
#include <cstdint>
|
||||
|
||||
#include "../../events/types.hpp"
|
||||
#include "behavior/events/types.hpp"
|
||||
#include "../base/PacketData.hpp"
|
||||
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
#include <cstring>
|
||||
|
||||
#include "PacketContent.hpp"
|
||||
#include "../../events/types.hpp"
|
||||
#include "behavior/events/types.hpp"
|
||||
|
||||
|
||||
namespace drp::packet::base {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../RemotePeer.hpp"
|
||||
#include "../../events/types.hpp"
|
||||
#include "RemotePeer.hpp"
|
||||
#include "behavior/events/types.hpp"
|
||||
#include "../base/PacketData.hpp"
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue