Start adding notification support

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@854 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
beveloper 2002-08-22 23:34:33 +00:00
parent d0aedf22d8
commit eae26d3da1
6 changed files with 390 additions and 38 deletions

View File

@ -0,0 +1,51 @@
/*
* Copyright 2002, Marcus Overhagen. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _NOTIFICATION_MANAGER_H
#define _NOTIFICATION_MANAGER_H
namespace BPrivate {
namespace media {
class NotificationManager
{
public:
NotificationManager();
~NotificationManager();
status_t Register(const BMessenger &notifyHandler, const media_node &node, int32 notificationType);
status_t Unregister(const BMessenger &notifyHandler, const media_node &node, int32 notificationType);
status_t ReportError(const media_node &node, BMediaNode::node_error what, const BMessage * info);
void NodesCreated(const media_node_id *ids, int32 count);
void NodesDeleted(const media_node_id *ids, int32 count);
void ConnectionMade(const media_input &input, const media_output &output, const media_format &format);
void ConnectionBroken(const media_source &source, const media_destination &destination);
void BuffersCreated(); // XXX fix
void BuffersDeleted(const media_buffer_id *ids, int32 count);
// XXX header file lists: B_MEDIA_TRANSPORT_STATE, /* "state", "location", "realtime" */
void FormatChanged(const media_source &source, const media_destination &destination, const media_format &format);
status_t ParameterChanged(const media_node &node, int32 parameterid);
void WebChanged(const media_node &node); // XXX fix
// XXX header file lists: B_MEDIA_DEFAULT_CHANGED /* "default", "node" -- handled by BMediaRoster */
status_t NewParameterValue(const media_node &node, int32 parameterid, bigtime_t when, const void *param, size_t paramsize);
void FlavorsChanged(media_addon_id addonis, int32 newcount, int32 gonecount);
void NodeStopped(const media_node &node, bigtime_t when); // XXX fix
static bool IsValidNotificationType(int32 notificationType);
private:
status_t SendMessageToMediaServer(BMessage *msg);
private:
BMessenger *fMessenger;
};
}; // namespace media
}; // namespace BPrivate
extern BPrivate::media::NotificationManager *_NotificationManager;
#endif // _NOTIFICATION_MANAGER_H

View File

@ -5,6 +5,7 @@
***********************************************************************/
#include <Controllable.h>
#include "debug.h"
#include "NotificationManager.h"
/*************************************************************
* protected BControllable
@ -78,9 +79,8 @@ BControllable::HandleMessage(int32 message,
status_t
BControllable::BroadcastChangedParameter(int32 id)
{
UNIMPLEMENTED();
return B_ERROR;
CALLED();
return _NotificationManager->ParameterChanged(Node(), id);
}
@ -90,9 +90,8 @@ BControllable::BroadcastNewParameterValue(bigtime_t when,
void *newValue,
size_t valueSize)
{
UNIMPLEMENTED();
return B_ERROR;
CALLED();
return _NotificationManager->NewParameterValue(Node(), id, when, newValue, valueSize);
}

View File

@ -44,6 +44,7 @@ SharedLibrary media :
# Internal Functionality
PortPool.cpp
DormantNodeManager.cpp
NotificationManager.cpp
SystemTimeSource.cpp
BufferIdCache.cpp
SharedBufferList.cpp

View File

@ -14,6 +14,7 @@
#include "SystemTimeSource.h"
#include "debug.h"
#include "ServerInterface.h"
#include "NotificationManager.h"
// don't rename this one, it's used and exported for binary compatibility
int32 BMediaNode::_m_changeTag = 0;
@ -212,11 +213,10 @@ status_t
BMediaNode::ReportError(node_error what,
const BMessage *info)
{
UNIMPLEMENTED();
// XXX Transmits the error code specified by whichError to anyone
// XXX that's receiving notifications from this node (see
// XXX BMediaRoster::StartWatching() and BMediaRoster::StopWatching() on).
return B_OK;
CALLED();
// Transmits the error code specified by what to anyone
// that's receiving notifications from this node
return _NotificationManager->ReportError(Node(), what, info);
}
@ -227,7 +227,8 @@ BMediaNode::NodeStopped(bigtime_t whenPerformance)
// called by derived classes when they have
// finished handling a stop request.
// XXX notify anyone who is listening for stop notifications!
// notify anyone who is listening for stop notifications!
_NotificationManager->NodeStopped(Node(), whenPerformance);
// XXX If your node is a BBufferProducer, downstream consumers
// XXX will be notified that your node stopped (automatically, no less)

View File

@ -17,6 +17,7 @@
#include "PortPool.h"
#include "ServerInterface.h"
#include "DormantNodeManager.h"
#include "NotificationManager.h"
static BMessenger *ServerMessenger = 0;
static team_id team;
@ -316,6 +317,19 @@ BMediaRoster::Connect(const media_source & from,
media_format * io_format,
media_output * out_output,
media_input * out_input)
{
return BMediaRoster::Connect(from, to, io_format, out_output, out_input, 0);
}
status_t
BMediaRoster::Connect(const media_source & from,
const media_destination & to,
media_format * io_format,
media_output * out_output,
media_input * out_input,
uint32 in_flags,
void * _reserved)
{
CALLED();
if (io_format == NULL || out_output == NULL || out_input == NULL)
@ -443,20 +457,6 @@ failed:
return rv;
}
status_t
BMediaRoster::Connect(const media_source & from,
const media_destination & to,
media_format * io_format,
media_output * out_output,
media_input * out_input,
uint32 in_flags,
void * _reserved)
{
UNIMPLEMENTED();
return B_ERROR;
}
status_t
BMediaRoster::Disconnect(media_node_id source_node,
@ -832,8 +832,12 @@ BMediaRoster::GetAllOutputsFor(const media_node & node,
status_t
BMediaRoster::StartWatching(const BMessenger & where)
{
UNIMPLEMENTED();
return B_ERROR;
CALLED();
if (!where.IsValid()) {
TRACE("BMediaRoster::StartWatching: messenger invalid!\n");
return B_BAD_VALUE;
}
return _NotificationManager->Register(where, media_node::null, B_MEDIA_WILDCARD);
}
@ -841,8 +845,16 @@ status_t
BMediaRoster::StartWatching(const BMessenger & where,
int32 notificationType)
{
UNIMPLEMENTED();
return B_ERROR;
CALLED();
if (!where.IsValid()) {
TRACE("BMediaRoster::StartWatching: messenger invalid!\n");
return B_BAD_VALUE;
}
if (!BPrivate::media::NotificationManager::IsValidNotificationType(notificationType)) {
TRACE("BMediaRoster::StartWatching: notificationType invalid!\n");
return B_BAD_VALUE;
}
return _NotificationManager->Register(where, media_node::null, notificationType);
}
@ -851,16 +863,29 @@ BMediaRoster::StartWatching(const BMessenger & where,
const media_node & node,
int32 notificationType)
{
UNIMPLEMENTED();
return B_ERROR;
CALLED();
if (!where.IsValid()) {
TRACE("BMediaRoster::StartWatching: messenger invalid!\n");
return B_BAD_VALUE;
}
if (node.node == 0) {
TRACE("BMediaRoster::StartWatching: node invalid!\n");
return B_MEDIA_BAD_NODE;
}
if (!BPrivate::media::NotificationManager::IsValidNotificationType(notificationType)) {
TRACE("BMediaRoster::StartWatching: notificationType invalid!\n");
return B_BAD_VALUE;
}
return _NotificationManager->Register(where, node, notificationType);
}
status_t
BMediaRoster::StopWatching(const BMessenger & where)
{
UNIMPLEMENTED();
return B_ERROR;
CALLED();
// messenger may already be invalid, so we don't check this
return _NotificationManager->Unregister(where, media_node::null, B_MEDIA_WILDCARD);
}
@ -868,8 +893,13 @@ status_t
BMediaRoster::StopWatching(const BMessenger & where,
int32 notificationType)
{
UNIMPLEMENTED();
return B_ERROR;
CALLED();
// messenger may already be invalid, so we don't check this
if (!BPrivate::media::NotificationManager::IsValidNotificationType(notificationType)) {
TRACE("BMediaRoster::StopWatching: notificationType invalid!\n");
return B_BAD_VALUE;
}
return _NotificationManager->Unregister(where, media_node::null, notificationType);
}
@ -878,8 +908,17 @@ BMediaRoster::StopWatching(const BMessenger & where,
const media_node & node,
int32 notificationType)
{
UNIMPLEMENTED();
return B_ERROR;
CALLED();
// messenger may already be invalid, so we don't check this
if (node.node == 0) {
TRACE("BMediaRoster::StopWatching: node invalid!\n");
return B_MEDIA_BAD_NODE;
}
if (!BPrivate::media::NotificationManager::IsValidNotificationType(notificationType)) {
TRACE("BMediaRoster::StopWatching: notificationType invalid!\n");
return B_BAD_VALUE;
}
return _NotificationManager->Unregister(where, node, notificationType);
}

View File

@ -0,0 +1,261 @@
/*
* Copyright 2002, Marcus Overhagen. All rights reserved.
* Distributed under the terms of the MIT License.
*/
/* This is a interface class for media kit notifications.
* It is private to the media kit which uses it to pass
* notifications up to the media_server which will broadcast
* them.
*/
#include <Messenger.h>
#include <MediaNode.h>
#include "debug.h"
#include "PortPool.h"
#include "ServerInterface.h"
#include "NotificationManager.h"
static BPrivate::media::NotificationManager manager;
BPrivate::media::NotificationManager *_NotificationManager = &manager;
namespace BPrivate {
namespace media {
NotificationManager::NotificationManager()
: fMessenger(new BMessenger())
{
CALLED();
}
NotificationManager::~NotificationManager()
{
CALLED();
delete fMessenger;
}
status_t
NotificationManager::Register(const BMessenger &notifyHandler, const media_node &node, int32 notificationType)
{
CALLED();
BMessage msg(MEDIA_SERVER_REQUEST_NOTIFICATIONS);
return SendMessageToMediaServer(&msg);
}
status_t
NotificationManager::Unregister(const BMessenger &notifyHandler, const media_node &node, int32 notificationType)
{
CALLED();
BMessage msg(MEDIA_SERVER_CANCEL_NOTIFICATIONS);
return SendMessageToMediaServer(&msg);
}
status_t
NotificationManager::ReportError(const media_node &node, BMediaNode::node_error what, const BMessage * info)
{
/* Transmits the error code specified by whichError to anyone that's receiving notifications from
* this node. If info isn't NULL, it's used as a model message for the error notification message.
* The message field "be:node_id" will contain the node ID.
*/
CALLED();
// sanity check the what value
switch (what) {
case BMediaNode::B_NODE_FAILED_START:
case BMediaNode::B_NODE_FAILED_STOP:
case BMediaNode::B_NODE_FAILED_SEEK:
case BMediaNode::B_NODE_FAILED_SET_RUN_MODE:
case BMediaNode::B_NODE_FAILED_TIME_WARP:
case BMediaNode::B_NODE_FAILED_PREROLL:
case BMediaNode::B_NODE_FAILED_SET_TIME_SOURCE_FOR:
case BMediaNode::B_NODE_IN_DISTRESS:
break;
default:
TRACE("BMediaNode::ReportError (NotificationManager::ReportError): invalid what!\n");
return B_BAD_VALUE;
}
BMessage msg;
if (info)
msg = *info;
msg.what = what;
return SendMessageToMediaServer(&msg);
}
void
NotificationManager::NodesCreated(const media_node_id *ids, int32 count)
{
CALLED();
BMessage msg(B_MEDIA_NODE_CREATED);
SendMessageToMediaServer(&msg);
}
void
NotificationManager::NodesDeleted(const media_node_id *ids, int32 count)
{
CALLED();
BMessage msg(B_MEDIA_NODE_DELETED);
SendMessageToMediaServer(&msg);
}
void
NotificationManager::ConnectionMade(const media_input &input, const media_output &output, const media_format &format)
{
CALLED();
BMessage msg(B_MEDIA_CONNECTION_MADE);
SendMessageToMediaServer(&msg);
}
void
NotificationManager::ConnectionBroken(const media_source &source, const media_destination &destination)
{
CALLED();
BMessage msg(B_MEDIA_CONNECTION_BROKEN);
SendMessageToMediaServer(&msg);
}
void
NotificationManager::BuffersCreated() // XXX fix
{
CALLED();
BMessage msg(B_MEDIA_BUFFER_CREATED);
SendMessageToMediaServer(&msg);
}
void
NotificationManager::BuffersDeleted(const media_buffer_id *ids, int32 count)
{
CALLED();
BMessage msg(B_MEDIA_BUFFER_DELETED);
SendMessageToMediaServer(&msg);
}
void
NotificationManager::FormatChanged(const media_source &source, const media_destination &destination, const media_format &format)
{
CALLED();
BMessage msg(B_MEDIA_FORMAT_CHANGED);
SendMessageToMediaServer(&msg);
}
status_t
NotificationManager::ParameterChanged(const media_node &node, int32 parameterid)
{
CALLED();
BMessage msg(B_MEDIA_PARAMETER_CHANGED);
return B_OK;
}
void
NotificationManager::WebChanged(const media_node &node) // XXX fix
{
CALLED();
BMessage msg(B_MEDIA_WEB_CHANGED);
}
status_t
NotificationManager::NewParameterValue(const media_node &node, int32 parameterid, bigtime_t when, const void *param, size_t paramsize)
{
CALLED();
BMessage msg(B_MEDIA_NEW_PARAMETER_VALUE);
return SendMessageToMediaServer(&msg);
}
void
NotificationManager::FlavorsChanged(media_addon_id addonis, int32 newcount, int32 gonecount)
{
CALLED();
BMessage msg(B_MEDIA_FLAVORS_CHANGED);
SendMessageToMediaServer(&msg);
}
void
NotificationManager::NodeStopped(const media_node &node, bigtime_t when) // XXX fix
{
CALLED();
BMessage msg(B_MEDIA_NODE_STOPPED);
SendMessageToMediaServer(&msg);
}
status_t
NotificationManager::SendMessageToMediaServer(BMessage *msg)
{
#define TIMEOUT 1000000
BMessage reply;
status_t rv;
if (!fMessenger->IsValid()) {
TRACE("NotificationManager::SendMessageToMediaServer: setting new messenger target\n");
*fMessenger = BMessenger(NEW_MEDIA_SERVER_SIGNATURE);
}
rv = fMessenger->SendMessage(msg, &reply, TIMEOUT);
if (rv != B_OK) {
TRACE("NotificationManager::SendMessageToMediaServer: failed to send message\n");
} else {
rv = reply.what;
}
return rv;
}
bool
NotificationManager::IsValidNotificationType(int32 notificationType)
{
switch (notificationType) {
case BMediaNode::B_NODE_FAILED_START:
case BMediaNode::B_NODE_FAILED_STOP:
case BMediaNode::B_NODE_FAILED_SEEK:
case BMediaNode::B_NODE_FAILED_SET_RUN_MODE:
case BMediaNode::B_NODE_FAILED_TIME_WARP:
case BMediaNode::B_NODE_FAILED_PREROLL:
case BMediaNode::B_NODE_FAILED_SET_TIME_SOURCE_FOR:
case BMediaNode::B_NODE_IN_DISTRESS:
case B_MEDIA_WILDCARD:
case B_MEDIA_NODE_CREATED:
case B_MEDIA_NODE_DELETED:
case B_MEDIA_CONNECTION_MADE:
case B_MEDIA_CONNECTION_BROKEN:
case B_MEDIA_BUFFER_CREATED:
case B_MEDIA_BUFFER_DELETED:
case B_MEDIA_TRANSPORT_STATE:
case B_MEDIA_PARAMETER_CHANGED:
case B_MEDIA_FORMAT_CHANGED:
case B_MEDIA_WEB_CHANGED:
case B_MEDIA_DEFAULT_CHANGED:
case B_MEDIA_NEW_PARAMETER_VALUE:
case B_MEDIA_NODE_STOPPED:
case B_MEDIA_FLAVORS_CHANGED:
return true;
default:
return false;
}
}
}; // namespace media
}; // namespace BPrivate