syndilights/open-lighting-architecture/ola-0.8.4/olad/Port.cpp

241 lines
5.7 KiB
C++

/*
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Port.cpp
* Base implementation of the Port class.
* Copyright (C) 2005-2009 Simon Newton
*
* Unfortunately this file contains a lot of code duplication.
*/
#include <string>
#include "ola/Logging.h"
#include "olad/Device.h"
#include "olad/Port.h"
namespace ola {
/*
* Create a new basic input port
*/
BasicInputPort::BasicInputPort(AbstractDevice *parent,
unsigned int port_id,
const TimeStamp *wake_time):
m_port_id(port_id),
m_priority(DmxSource::PRIORITY_DEFAULT),
m_priority_mode(PRIORITY_MODE_INHERIT),
m_port_string(""),
m_universe(NULL),
m_device(parent),
m_wakeup_time(wake_time) {
}
bool BasicInputPort::SetUniverse(Universe *new_universe) {
Universe *old_universe = GetUniverse();
if (old_universe == new_universe)
return true;
if (PreSetUniverse(old_universe, new_universe)) {
m_universe = new_universe;
PostSetUniverse(old_universe, new_universe);
return true;
}
return false;
}
string BasicInputPort::UniqueId() const {
if (m_port_string.empty()) {
std::stringstream str;
if (m_device)
str << m_device->UniqueId() << "-I-" << m_port_id;
m_port_string = str.str();
}
return m_port_string;
}
bool BasicInputPort::SetPriority(uint8_t priority) {
if (priority > DmxSource::PRIORITY_MAX)
return false;
m_priority = priority;
return true;
}
/*
* Called when there is new data for this port
*/
void BasicInputPort::DmxChanged() {
if (GetUniverse()) {
const DmxBuffer &buffer = ReadDMX();
uint8_t priority = (PriorityCapability() == CAPABILITY_FULL &&
GetPriorityMode() == PRIORITY_MODE_INHERIT ?
InheritedPriority() :
GetPriority());
m_dmx_source.UpdateData(buffer, *m_wakeup_time, priority);
GetUniverse()->PortDataChanged(this);
}
}
/*
* Handle an RDM Request on this port.
* @param request the RDMRequest object, ownership is transferred to us
*/
bool BasicInputPort::HandleRDMRequest(const ola::rdm::RDMRequest *request) {
if (m_universe)
return m_universe->HandleRDMRequest(this, request);
else
delete request;
return false;
}
/*
* Handle a response message
* @param response, the RDMResponse object, ownership is transferred to us
*/
bool BasicInputPort::HandleRDMResponse(
const ola::rdm::RDMResponse *response) {
OLA_WARN << "In base HandleRDMResponse, something has gone wrong with RDM" <<
" request routing";
delete response;
return true;
}
/*
* Trigger the RDM Discovery procedure for this universe
*/
void BasicInputPort::TriggerRDMDiscovery() {
if (m_universe)
m_universe->RunRDMDiscovery();
}
void BasicOutputPort::NewUIDList(const ola::rdm::UIDSet &uids) {
if (m_universe)
m_universe->NewUIDList(uids, this);
}
/*
* Create a new BasicOutputPort
*/
BasicOutputPort::BasicOutputPort(AbstractDevice *parent,
unsigned int port_id,
bool start_rdm_discovery_on_patch):
m_port_id(port_id),
m_discover_on_patch(start_rdm_discovery_on_patch),
m_priority(DmxSource::PRIORITY_DEFAULT),
m_priority_mode(PRIORITY_MODE_INHERIT),
m_port_string(""),
m_universe(NULL),
m_device(parent) {
}
bool BasicOutputPort::SetUniverse(Universe *new_universe) {
Universe *old_universe = GetUniverse();
if (old_universe == new_universe)
return true;
if (PreSetUniverse(old_universe, new_universe)) {
m_universe = new_universe;
PostSetUniverse(old_universe, new_universe);
if (m_discover_on_patch)
RunRDMDiscovery();
return true;
}
return false;
}
string BasicOutputPort::UniqueId() const {
if (m_port_string.empty()) {
std::stringstream str;
if (m_device)
str << m_device->UniqueId() << "-O-" << m_port_id;
m_port_string = str.str();
}
return m_port_string;
}
bool BasicOutputPort::SetPriority(uint8_t priority) {
if (priority > DmxSource::PRIORITY_MAX)
return false;
m_priority = priority;
return true;
}
/*
* Handle an RDMRequest, subclasses can implement this to support RDM
*/
bool BasicOutputPort::HandleRDMRequest(const ola::rdm::RDMRequest *request) {
// broadcasts go to every port
if (!request->DestinationUID().IsBroadcast())
OLA_WARN << "In base HandleRDMRequest, something has gone wrong with RDM"
<< " request routing";
delete request;
return true;
}
/*
* Handle a response message
*/
bool BasicOutputPort::HandleRDMResponse(
const ola::rdm::RDMResponse *response) {
if (m_universe)
return m_universe->HandleRDMResponse(this, response);
else
delete response;
return false;
}
/*
* This is a noop for ports that don't support RDM
*/
void BasicOutputPort::RunRDMDiscovery() {
}
/*
* This allows switching based on Port type.
*/
template<class PortClass>
bool IsInputPort() {
return true;
}
template<>
bool IsInputPort<OutputPort>() {
return false;
}
template<>
bool IsInputPort<InputPort>() {
return true;
}
} // ola