📄 hxtac.cpp
字号:
/* ***** BEGIN LICENSE BLOCK *****
* Version: RCSL 1.0/RPSL 1.0
*
* Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved.
*
* The contents of this file, and the files included with this file, are
* subject to the current version of the RealNetworks Public Source License
* Version 1.0 (the "RPSL") available at
* http://www.helixcommunity.org/content/rpsl unless you have licensed
* the file under the RealNetworks Community Source License Version 1.0
* (the "RCSL") available at http://www.helixcommunity.org/content/rcsl,
* in which case the RCSL will apply. You may also obtain the license terms
* directly from RealNetworks. You may not use this file except in
* compliance with the RPSL or, if you have a valid RCSL with RealNetworks
* applicable to this file, the RCSL. Please see the applicable RPSL or
* RCSL for the rights, obligations and limitations governing use of the
* contents of the file.
*
* This file is part of the Helix DNA Technology. RealNetworks is the
* developer of the Original Code and owns the copyrights in the portions
* it created.
*
* This file, and the files included with this file, is distributed and made
* available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
*
* Technology Compatibility Kit Test Suite(s) Location:
* http://www.helixcommunity.org/content/tck
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** */
#include "hxcom.h"
#include "hxtypes.h"
#include "hxcomm.h"
#include "hxausvc.h"
#include "ihxpckts.h"
#include "hxengin.h"
#include "hxcore.h"
#include "hxmap.h"
#include "hxgroup.h"
#include "basgroup.h"
#include "advgroup.h"
#include "hxplay.h"
#include "hxstrutl.h"
#include "hxtac.h"
#include "hxheap.h"
#ifdef _DEBUG
#undef HX_THIS_FILE
static const char HX_THIS_FILE[] = __FILE__;
#endif
// note: these constants much match the order of szTACNames
#define TitlePosition 0
#define AuthorPosition 1
#define CopyrightPosition 2
#define AbstractPosition 3
#define KeywordsPosition 4
#define DescriptionPosition 5
static const char* const szTACNames[] =
{
"Title",
"Author",
"Copyright",
"Abstract",
"Keywords",
"Description"
};
// init static data
UINT32 const TACData::NoFind = 9;
/////////////////////////////////////////////////////////////////////////
// Method:
// HXMasterTAC::HXMasterTAC
// Purpose:
// Constructor
//
HXMasterTAC::HXMasterTAC(HXBasicGroupManager* pGroupManager) :
m_tacStatus(TAC_Pending)
, m_pTACPropWatch(NULL)
, m_pTACProps(NULL)
, m_lRefCount(0)
#if defined(HELIX_FEATURE_REGISTRY)
, m_pRegistry(NULL)
#endif /* HELIX_FEATURE_REGISTRY */
, m_ptacPropIDs(NULL)
{
m_pGroupManager = pGroupManager;
HX_ADDREF(m_pGroupManager);
m_pTACProps = new CHXHeader();
m_pTACProps->AddRef();
// init master tac prop ID array
for (int n=0; n<NUMB_TAC_NAMES; n++)
{
m_masterTACPropIDs[n] = 0;
}
}
/////////////////////////////////////////////////////////////////////////
// Method:
// HXMasterTAC::~HXMasterTAC
// Purpose:
// Destructor
//
HXMasterTAC::~HXMasterTAC()
{
HX_RELEASE(m_pTACProps);
#if defined(HELIX_FEATURE_REGISTRY)
HX_RELEASE(m_pRegistry);
#endif /* HELIX_FEATURE_REGISTRY */
HX_DELETE(m_ptacPropIDs);
}
void HXMasterTAC::Close()
{
// clear TAC prop watches and release prop watch object
if (m_pTACPropWatch)
{
ResetTAC();
HX_RELEASE(m_pTACPropWatch);
}
HX_RELEASE(m_pGroupManager);
}
BOOL
HXMasterTAC::IsTACComplete(IHXValues* pProps)
{
BOOL bResult = TRUE;
UINT16 nIdx = 0;
IHXBuffer* pValue = NULL;
if (!pProps)
{
bResult = FALSE;
goto cleanup;
}
for(nIdx = 0; nIdx < NUMB_TAC_NAMES - 1; nIdx++)
{
if (HXR_OK != pProps->GetPropertyCString(szTACNames[nIdx], pValue) || !pValue)
{
bResult = FALSE;
break;
}
HX_RELEASE(pValue);
}
cleanup:
HX_RELEASE(pValue);
return bResult;
}
void HXMasterTAC::SetRegistry(HXClientRegistry* pRegistry, UINT32 playerID)
{
#if defined(HELIX_FEATURE_REGISTRY)
// save the reg ptr and addref
m_pRegistry = pRegistry;
m_pRegistry->AddRef();
// and create properties in player's space
char szPropName[1024]; /* Flawfinder: ignore */
IHXBuffer* pPlayerName = NULL;
HX_ASSERT(playerID != 0);
if (HXR_OK == m_pRegistry->GetPropName(playerID, pPlayerName))
{
for (int n=0; n<NUMB_TAC_NAMES; n++)
{
// add each master TAC prop
SafeSprintf(szPropName, 1024, "%s.%s", (char*) pPlayerName->GetBuffer(), szTACNames[n]);
m_masterTACPropIDs[n] = m_pRegistry->AddStr(szPropName, NULL);
}
HX_RELEASE(pPlayerName);
}
// create prop watch object
m_pRegistry->CreatePropWatch(m_pTACPropWatch);
m_pTACPropWatch->Init((IHXPropWatchResponse*) this);
#endif /* HELIX_FEATURE_REGISTRY */
}
/*
* IUnknown methods
*/
/////////////////////////////////////////////////////////////////////////
// Method:
// IUnknown::QueryInterface
// Purpose:
// Implement this to export the interfaces supported by your
// object.
//
STDMETHODIMP HXMasterTAC::QueryInterface(REFIID riid, void** ppvObj)
{
QInterfaceList qiList[] =
{
{ GET_IIDHANDLE(IID_IHXPropWatchResponse), (IHXPropWatchResponse*)this },
{ GET_IIDHANDLE(IID_IUnknown), (IUnknown*)(IHXPropWatchResponse*)this },
};
return ::QIFind(qiList, QILISTSIZE(qiList), riid, ppvObj);
}
/////////////////////////////////////////////////////////////////////////
// Method:
// IUnknown::AddRef
// Purpose:
// Everyone usually implements this the same... feel free to use
// this implementation.
//
STDMETHODIMP_(ULONG32) HXMasterTAC::AddRef()
{
return InterlockedIncrement(&m_lRefCount);
}
/////////////////////////////////////////////////////////////////////////
// Method:
// IUnknown::Release
// Purpose:
// Everyone usually implements this the same... feel free to use
// this implementation.
//
STDMETHODIMP_(ULONG32) HXMasterTAC::Release()
{
if (InterlockedDecrement(&m_lRefCount) > 0)
{
return m_lRefCount;
}
delete this;
return 0;
}
#if defined(HELIX_FEATURE_REGISTRY)
// IHXPropWatchResponse methods
STDMETHODIMP
HXMasterTAC::AddedProp(const UINT32 id,
const HXPropType propType,
const UINT32 ulParentHash)
{
return HXR_NOTIMPL;
}
STDMETHODIMP
HXMasterTAC::ModifiedProp(const UINT32 id,
const HXPropType propType,
const UINT32 ulParentHash)
{
if (m_ptacPropIDs)
{
// first see which prop this is (0-3) and copy data
// to equivilent unfied Player prop
UINT32 masterID = 0;
TACData* pTACData = NULL;
IHXBuffer* pValue = NULL;
LISTPOSITION pos = m_ptacPropIDs->GetHeadPosition();
while (pos)
{
// get next tac data object
pTACData = (TACData*) m_ptacPropIDs->GetNext(pos);
// find the equivilent master prop ID
masterID = pTACData->FindMasterIndex(id);
if (masterID != TACData::NoFind)
{
// get prop from ID
m_pRegistry->GetStrById(id, pValue);
if (pValue)
{
// set new master tac prop
m_pRegistry->SetStrById(m_masterTACPropIDs[masterID], pValue);
HX_RELEASE(pValue);
}
break;
}
}
}
return HXR_OK;
}
STDMETHODIMP
HXMasterTAC::DeletedProp(const UINT32 id,
const UINT32 ulParentHash)
{
HRESULT hRes = HXR_OK;
// clear TAC prop watches and release prop watch object
if (m_pTACPropWatch)
{
if (m_ptacPropIDs)
{
TACData* pTACData = NULL;
LISTPOSITION pos = m_ptacPropIDs->GetHeadPosition();
while (pos)
{
// get next TAC data object
pTACData = (TACData*) m_ptacPropIDs->GetNext(pos);
// see if this ID is part of this TAC data object
if (pTACData->IsIDPresent(id))
{
pTACData->Clear(id);
break;
}
}
}
// clear the watch now
hRes = m_pTACPropWatch->ClearWatchById(id);
}
return hRes;
}
#endif /* HELIX_FEATURE_REGISTRY */
/************************************************************************
* Method:
* HXMasterTAC::ResetTAC
* Purpose:
* Reset all TAC related members in preparation for next group
*
*/
void HXMasterTAC::ResetTAC(BOOL bResetStatus /*=TRUE*/, BOOL bClearMasterProps /*=FALSE*/)
{
if (bResetStatus)
{
m_tacStatus = TAC_Pending;
}
TACData* pTACData = NULL;
if (m_ptacPropIDs)
{
LISTPOSITION pos = m_ptacPropIDs->GetHeadPosition();
while (pos)
{
// get next TAC data object
pTACData = (TACData*) m_ptacPropIDs->GetNext(pos);
// clear all watches set
pTACData->ClearAll(m_pTACPropWatch);
// free tac data object
delete pTACData;
pTACData = NULL;
}
// remove all list entries
m_ptacPropIDs->RemoveAll();
HX_DELETE(m_ptacPropIDs);
}
// clear the master tac props value if this flag is set
if (bClearMasterProps)
{
HX_RELEASE(m_pTACProps);
m_pTACProps = new CHXHeader();
m_pTACProps->AddRef();
#if defined(HELIX_FEATURE_REGISTRY)
// set values in registry
IHXBuffer* pValue = NULL;
for (int i=0; i<NUMB_TAC_NAMES; i++)
{
UCHAR nullString[1];
*nullString = '\0';
// set to blank string
pValue = new CHXBuffer();
pValue->AddRef();
pValue->Set(nullString, 1);
m_pRegistry->SetStrById(m_masterTACPropIDs[i], pValue);
HX_RELEASE(pValue);
}
#endif /* HELIX_FEATURE_REGISTRY */
}
}
/************************************************************************
* Method:
* HXMasterTAC::CheckTrackAndSourceOnTrackStarted
* Purpose:
* Private function used to examine track props for TAC info
*
*/
BOOL HXMasterTAC::CheckTrackAndSourceOnTrackStarted(INT32 nGroup,
INT32 nTrack,
UINT32 sourceID)
{
BOOL res = TRUE;
// if we have no tac yet, or, if we have a Source TAC set and
// in fact the track props have TAC info, try for Track props...
if (m_tacStatus == TAC_Pending || m_tacStatus == TAC_Source)
{
// see if track props have TAC info
if (!CheckTrackForTACInfo(nGroup, nTrack))
{
// finally, if Track Props have no TAC, check the Source props!
res = CheckSourceForTACInfo(nGroup, nTrack, sourceID);
}
}
return res;
}
/************************************************************************
* Method:
* HXMasterTAC::CheckGroupForTACInfo
* Purpose:
* Private function used to examine group props for TAC info
*
*/
BOOL HXMasterTAC::CheckGroupForTACInfo(INT32 nGroup)
{
BOOL bFoundTAC = FALSE;
// first get the group object's properties using the IHXGroup
IHXGroup* pGroup = NULL;
if (m_pGroupManager &&
HXR_OK == m_pGroupManager->GetGroup((UINT16) nGroup, pGroup))
{
// now get the props
IHXValues* pGroupProps = pGroup->GetGroupProperties();
// now search the group props for TAC info
RetrieveTACProperties(pGroupProps);
if (m_pTACProps && IsTACComplete(m_pTACProps))
{
SetTAC(m_pTACProps, TAC_Group);
bFoundTAC = TRUE;
}
else if (pGroupProps) // the group has no TAC props, so check the individidual tracks
{
for (int n=0; !bFoundTAC && n<pGroup->GetTrackCount(); n++)
{
// now get the next track
IHXValues* pTrack = NULL;
if (HXR_OK == pGroup->GetTrack((UINT16) n, pTrack))
{
// now search the props for TAC info
RetrieveTACProperties(pTrack);
if (m_pTACProps && IsTACComplete(m_pTACProps))
{
// promote track props to group
IHXBuffer* pValue = NULL;
UINT16 nIdx;
for(nIdx = 0; nIdx < NUMB_TAC_NAMES; nIdx++)
{
m_pTACProps->GetPropertyCString(szTACNames[nIdx], pValue);
if (pValue)
{
pGroupProps->SetPropertyCString(szTACNames[nIdx], pValue);
HX_RELEASE(pValue);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -