gearmulator

Emulation of classic VA synths of the late 90s/2000s that are based on Motorola 56300 family DSPs
Log | Files | Refs | Submodules | README | LICENSE

server.cpp (2615B)


      1 #include "server.h"
      2 
      3 #include <ptypes/pinet.h>
      4 
      5 #include "bridgeLib/types.h"
      6 #include "networkLib/logging.h"
      7 
      8 namespace bridgeServer
      9 {
     10 	Server::Server(int _argc, char** _argv)
     11 		: m_config(_argc, _argv)
     12 		, m_plugins(m_config)
     13 		, m_romPool(m_config)
     14 		, m_tcpServer([this](std::unique_ptr<networkLib::TcpStream> _stream){onClientConnected(std::move(_stream));}
     15 		, bridgeLib::g_tcpServerPort)
     16 		, m_lastDeviceStateUpdate(std::chrono::system_clock::now())
     17 	{
     18 	}
     19 
     20 	Server::~Server()
     21 	{
     22 		exit(true);
     23 		m_cvWait.notify_one();
     24 		m_clients.clear();
     25 	}
     26 
     27 	void Server::run()
     28 	{
     29 		while(!m_exit)
     30 		{
     31 			std::unique_lock lock(m_cvWaitMutex);
     32 			m_cvWait.wait_for(lock, std::chrono::seconds(10));
     33 
     34 			cleanupClients();
     35 			doPeriodicDeviceStateUpdate();
     36 		}
     37 	}
     38 
     39 	void Server::onClientConnected(std::unique_ptr<networkLib::TcpStream> _stream)
     40 	{
     41 		const auto s = _stream->getPtypesStream();
     42 		const std::string name = std::string(ptypes::iptostring(s->get_ip())) + ":" + std::to_string(s->get_port());
     43 
     44 		std::scoped_lock lock(m_mutexClients);
     45 		m_clients.emplace_back(std::make_unique<ClientConnection>(*this, std::move(_stream), name));
     46 	}
     47 
     48 	void Server::onClientException(const ClientConnection&, const networkLib::NetException& _e)
     49 	{
     50 		m_cvWait.notify_one();
     51 	}
     52 
     53 	void Server::exit(const bool _exit)
     54 	{
     55 		m_exit = _exit;
     56 	}
     57 
     58 	bridgeLib::DeviceState Server::getCachedDeviceState(const bridgeLib::SessionId& _id)
     59 	{
     60 		const auto it = m_cachedDeviceStates.find(_id);
     61 
     62 		if(it == m_cachedDeviceStates.end())
     63 		{
     64 			static bridgeLib::DeviceState s;
     65 			return s;
     66 		}
     67 
     68 		auto res = std::move(it->second);
     69 		m_cachedDeviceStates.erase(it);
     70 		return res;
     71 	}
     72 
     73 	void Server::cleanupClients()
     74 	{
     75 		std::scoped_lock lock(m_mutexClients);
     76 
     77 		for(auto it = m_clients.begin(); it != m_clients.end();)
     78 		{
     79 			const auto& c = *it;
     80 			if(!c->isValid())
     81 			{
     82 				const auto& deviceState = c->getDeviceState();
     83 
     84 				if(deviceState.isValid())
     85 					m_cachedDeviceStates[c->getPluginDesc().sessionId] = deviceState;
     86 
     87 				it = m_clients.erase(it);
     88 				LOGNET(networkLib::LogLevel::Info, "Client removed, now " << m_clients.size() << " clients left");
     89 			}
     90 			else
     91 			{
     92 				++it;
     93 			}
     94 		}
     95 	}
     96 
     97 	void Server::doPeriodicDeviceStateUpdate()
     98 	{
     99 		std::scoped_lock lock(m_mutexClients);
    100 
    101 		const auto now = std::chrono::system_clock::now();
    102 
    103 		const auto diff = std::chrono::duration_cast<std::chrono::minutes>(now - m_lastDeviceStateUpdate);
    104 
    105 		if(diff.count() < static_cast<int>(m_config.deviceStateRefreshMinutes))
    106 			return;
    107 
    108 		m_lastDeviceStateUpdate = now;
    109 
    110 		for (const auto& c : m_clients)
    111 			c->sendDeviceState(synthLib::StateTypeGlobal);
    112 	}
    113 }