/* * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or * its licensors. * * For complete copyright and license terms please see the LICENSE at the root of this * distribution (the "License"). All use of this software is governed by the License, * or, if provided, by the license below or the license accompanying this file. Do not * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ // Original file Copyright Crytek GMBH or its affiliates, used under license. #include "CryLegacy_precompiled.h" #include "CommunicationChannelManager.h" #include bool CommunicationChannelManager::LoadChannel(const XmlNodeRef& channelNode, const CommChannelID& parentID) { if (!_stricmp(channelNode->getTag(), "Channel")) { const char* name = 0; if (!channelNode->getAttr("name", &name)) { AIWarning("Missing 'name' attribute for 'Channel' tag at line %d...", channelNode->getLine()); return false; } float minSilence = 0.0f; channelNode->getAttr("minSilence", minSilence); float flushSilence = minSilence; channelNode->getAttr("flushSilence", flushSilence); float actorMinSilence = 0.0f; channelNode->getAttr("actorMinSilence", actorMinSilence); bool ignoreActorSilence = false; channelNode->getAttr("ignoreActorSilence", ignoreActorSilence); //By default channels flush state on an abort request size_t priority = 0; channelNode->getAttr("priority", priority); SCommunicationChannelParams params; params.name = name; params.minSilence = minSilence; params.flushSilence = flushSilence; params.parentID = parentID; params.priority = priority; params.type = SCommunicationChannelParams::Global; params.actorMinSilence = actorMinSilence; params.ignoreActorSilence = ignoreActorSilence; if (channelNode->haveAttr("type")) { const char* type; channelNode->getAttr("type", &type); if (!_stricmp(type, "global")) { params.type = SCommunicationChannelParams::Global; } else if (!_stricmp(type, "group")) { params.type = SCommunicationChannelParams::Group; } else if (!_stricmp(type, "personal")) { params.type = SCommunicationChannelParams::Personal; } else { AIWarning("Invalid 'type' attribute for 'Channel' tag at line %d...", channelNode->getLine()); return false; } } std::pair iresult = m_params.insert( ChannelParams::value_type(GetChannelID(params.name.c_str()), params)); if (!iresult.second) { if (iresult.first->second.name == name) { AIWarning("Channel '%s' redefinition at line %d...", name, channelNode->getLine()); } else { AIWarning("Channel name '%s' hash collision!", name); } return false; } int childCount = channelNode->getChildCount(); CommChannelID channelID = GetChannelID(name); for (int i = 0; i < childCount; ++i) { XmlNodeRef childChannelNode = channelNode->getChild(i); if (!LoadChannel(childChannelNode, channelID)) { return false; } } } else { AIWarning("Unexpected tag '%s' found at line %d...", channelNode->getTag(), channelNode->getLine()); return false; } return true; } void CommunicationChannelManager::Clear() { Reset(); m_params.clear(); } void CommunicationChannelManager::Reset() { m_globalChannels.clear(); m_groupChannels.clear(); m_personalChannels.clear(); } void CommunicationChannelManager::Update(float updateTime) { FUNCTION_PROFILER(gEnv->pSystem, PROFILE_AI); Channels::iterator glit = m_globalChannels.begin(); Channels::iterator glend = m_globalChannels.end(); for (; glit != glend; ++glit) { glit->second->Update(updateTime); } GroupChannels::iterator grit = m_groupChannels.begin(); GroupChannels::iterator grend = m_groupChannels.end(); for (; grit != grend; ++grit) { Channels::iterator it = grit->second.begin(); Channels::iterator end = grit->second.end(); for (; it != end; ++it) { it->second->Update(updateTime); } } PersonalChannels::iterator prit = m_personalChannels.begin(); PersonalChannels::iterator prend = m_personalChannels.end(); for (; prit != prend; ++prit) { Channels::iterator it = prit->second.begin(); Channels::iterator end = prit->second.end(); for (; it != end; ++it) { it->second->Update(updateTime); } } } CommChannelID CommunicationChannelManager::GetChannelID(const char* name) const { return CommChannelID(CryStringUtils::CalculateHashLowerCase(name)); } const SCommunicationChannelParams& CommunicationChannelManager::GetChannelParams(const CommChannelID& channelID) const { ChannelParams::const_iterator it = m_params.find(channelID); static SCommunicationChannelParams noChannel; if (it == m_params.end()) { return noChannel; } else { return it->second; } } CommunicationChannel::Ptr CommunicationChannelManager::GetChannel(const CommChannelID& channelID, EntityId sourceId) { ChannelParams::iterator it = m_params.find(channelID); if (it != m_params.end()) { const SCommunicationChannelParams& params = it->second; switch (params.type) { case SCommunicationChannelParams::Global: { CommunicationChannel::Ptr& channel = stl::map_insert_or_get(m_globalChannels, channelID); if (!channel) { CommunicationChannel::Ptr parent = params.parentID ? GetChannel(params.parentID, sourceId) : CommunicationChannel::Ptr(0); channel.reset(new CommunicationChannel(parent, params, channelID)); } return channel; } case SCommunicationChannelParams::Group: { int groupID = 0; Channels& groupChannels = stl::map_insert_or_get(m_groupChannels, groupID); CommunicationChannel::Ptr& channel = stl::map_insert_or_get(groupChannels, channelID); if (!channel) { CommunicationChannel::Ptr parent = params.parentID ? GetChannel(params.parentID, sourceId) : CommunicationChannel::Ptr(0); channel.reset(new CommunicationChannel(parent, params, channelID)); } return channel; } case SCommunicationChannelParams::Personal: { Channels& personalChannels = stl::map_insert_or_get(m_personalChannels, sourceId); CommunicationChannel::Ptr& channel = stl::map_insert_or_get(personalChannels, channelID); if (!channel) { CommunicationChannel::Ptr parent = params.parentID ? GetChannel(params.parentID, sourceId) : CommunicationChannel::Ptr(0); channel.reset(new CommunicationChannel(parent, params, channelID)); } return channel; } default: assert(0); break; } } assert(0); return 0; }