[Radar] Switch from using frames in keeping track of ranges to using a bitset

Renames ALERT_TYPE_* to STAT_TYPE_* and ERadarAlertType to ERadarStatType
Removes mIn*Frame and accessors for these in favor of checking for the bit in mStats
Use mStats instead of mAgeAlert now.
Moves the range leave handling out of getAlive and into setPosition, where it logically belongs

Should fix Issue 43: Radar reports multiple times for agent entry upon rendering
This commit is contained in:
Lirusaito
2013-07-21 04:43:01 -04:00
parent 3650a56407
commit 845088166a
2 changed files with 43 additions and 82 deletions

View File

@@ -73,18 +73,9 @@ const F32 DEAD_KEEP_TIME = 10.0f;
extern U32 gFrameCount;
typedef enum e_radar_alert_type
{
ALERT_TYPE_SIM = 1,
ALERT_TYPE_DRAW = 2,
ALERT_TYPE_SHOUTRANGE = 4,
ALERT_TYPE_CHATRANGE = 8,
ALERT_TYPE_AGE = 16,
} ERadarAlertType;
namespace
{
void chat_avatar_status(std::string name, LLUUID key, ERadarAlertType type, bool entering)
void chat_avatar_status(std::string name, LLUUID key, ERadarStatType type, bool entering)
{
if(gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) return; //RLVa:LF Don't announce people are around when blind, that cheats the system.
static LLCachedControl<bool> radar_chat_alerts(gSavedSettings, "RadarChatAlerts");
@@ -100,35 +91,35 @@ void chat_avatar_status(std::string name, LLUUID key, ERadarAlertType type, bool
args["[NAME]"] = name;
switch(type)
{
case ALERT_TYPE_SIM:
case STAT_TYPE_SIM:
if (radar_alert_sim)
{
args["[RANGE]"] = self->getString("the_sim");
}
break;
case ALERT_TYPE_DRAW:
case STAT_TYPE_DRAW:
if (radar_alert_draw)
{
args["[RANGE]"] = self->getString("draw_distance");
}
break;
case ALERT_TYPE_SHOUTRANGE:
case STAT_TYPE_SHOUTRANGE:
if (radar_alert_shout_range)
{
args["[RANGE]"] = self->getString("shout_range");
}
break;
case ALERT_TYPE_CHATRANGE:
case STAT_TYPE_CHATRANGE:
if (radar_alert_chat_range)
{
args["[RANGE]"] = self->getString("chat_range");
}
break;
case ALERT_TYPE_AGE:
case STAT_TYPE_AGE:
if (radar_alert_age)
{
LLChat chat;
@@ -139,6 +130,9 @@ void chat_avatar_status(std::string name, LLUUID key, ERadarAlertType type, bool
LLFloaterChat::addChat(chat);
}
break;
default:
llassert(type);
break;
}
if (args.find("[RANGE]") != args.end())
{
@@ -169,10 +163,9 @@ void chat_avatar_status(std::string name, LLUUID key, ERadarAlertType type, bool
LLAvatarListEntry::LLAvatarListEntry(const LLUUID& id, const std::string &name, const LLVector3d &position) :
mID(id), mName(name), mPosition(position), mMarked(false), mFocused(false),
mUpdateTimer(), mFrame(gFrameCount), mInSimFrame(U32_MAX), mInDrawFrame(U32_MAX),
mInChatFrame(U32_MAX), mInShoutFrame(U32_MAX),
mUpdateTimer(), mFrame(gFrameCount), mStats(),
mActivityType(ACTIVITY_NEW), mActivityTimer(),
mIsInList(false), mAge(-1), mAgeAlert(false), mTime(time(NULL))
mIsInList(false), mAge(-1), mTime(time(NULL))
{
LLAvatarPropertiesProcessor::getInstance()->addObserver(mID, this);
LLAvatarPropertiesProcessor::getInstance()->sendAvatarPropertiesRequest(mID);
@@ -196,13 +189,12 @@ void LLAvatarListEntry::processProperties(void* data, EAvatarProcessorType type)
int year, month, day;
sscanf(pAvatarData->born_on.c_str(),"%d/%d/%d",&month,&day,&year);
mAge = (day_clock::local_day() - date(year, month, day)).days();
if (!mAgeAlert && mAge >= 0) //Only announce age once per entry.
if (!mStats[STAT_TYPE_AGE] && mAge >= 0) //Only announce age once per entry.
{
static const LLCachedControl<U32> sAvatarAgeAlertDays(gSavedSettings, "AvatarAgeAlertDays");
if ((U32)mAge < sAvatarAgeAlertDays)
{
mAgeAlert = true;
chat_avatar_status(mName, mID, ALERT_TYPE_AGE, true);
chat_avatar_status(mName, mID, STAT_TYPE_AGE, mStats[STAT_TYPE_AGE] = true);
}
}
// If one wanted more information that gets displayed on profiles to be displayed, here would be the place to do it.
@@ -215,37 +207,22 @@ void LLAvatarListEntry::setPosition(LLVector3d position, bool this_sim, bool dra
mPosition = position;
mFrame = gFrameCount;
if (this_sim)
if (this_sim != mStats[STAT_TYPE_SIM])
{
if (mInSimFrame == U32_MAX)
{
chat_avatar_status(mName, mID, ALERT_TYPE_SIM, true);
}
mInSimFrame = mFrame;
chat_avatar_status(mName, mID, STAT_TYPE_SIM, mStats[STAT_TYPE_SIM] = this_sim);
}
if (drawn)
if (drawn != mStats[STAT_TYPE_DRAW])
{
if (mInDrawFrame == U32_MAX)
{
chat_avatar_status(mName, mID, ALERT_TYPE_DRAW, true);
}
mInDrawFrame = mFrame;
chat_avatar_status(mName, mID, STAT_TYPE_DRAW, mStats[STAT_TYPE_DRAW] = drawn);
}
if (shoutrange)
if (shoutrange != mStats[STAT_TYPE_SHOUTRANGE])
{
if (mInShoutFrame == U32_MAX)
{
chat_avatar_status(mName, mID, ALERT_TYPE_SHOUTRANGE, true);
}
mInShoutFrame = mFrame;
chat_avatar_status(mName, mID, STAT_TYPE_SHOUTRANGE, mStats[STAT_TYPE_SHOUTRANGE] = shoutrange);
}
if (chatrange)
if (chatrange != mStats[STAT_TYPE_CHATRANGE])
{
if (mInChatFrame == U32_MAX)
{
chat_avatar_status(mName, mID, ALERT_TYPE_CHATRANGE, true);
}
mInChatFrame = mFrame;
chat_avatar_status(mName, mID, STAT_TYPE_CHATRANGE, mStats[STAT_TYPE_CHATRANGE] = chatrange);
}
mUpdateTimer.start();
@@ -254,26 +231,6 @@ void LLAvatarListEntry::setPosition(LLVector3d position, bool this_sim, bool dra
bool LLAvatarListEntry::getAlive()
{
U32 current = gFrameCount;
if (mInSimFrame != U32_MAX && (current - mInSimFrame) >= 2)
{
mInSimFrame = U32_MAX;
chat_avatar_status(mName, mID, ALERT_TYPE_SIM, false);
}
if (mInDrawFrame != U32_MAX && (current - mInDrawFrame) >= 2)
{
mInDrawFrame = U32_MAX;
chat_avatar_status(mName, mID, ALERT_TYPE_DRAW, false);
}
if (mInShoutFrame != U32_MAX && (current - mInShoutFrame) >= 2)
{
mInShoutFrame = U32_MAX;
chat_avatar_status(mName, mID, ALERT_TYPE_SHOUTRANGE, false);
}
if (mInChatFrame != U32_MAX && (current - mInChatFrame) >= 2)
{
mInChatFrame = U32_MAX;
chat_avatar_status(mName, mID, ALERT_TYPE_CHATRANGE, false);
}
return ((current - mFrame) <= 2);
}
@@ -579,7 +536,7 @@ void LLFloaterAvatarList::updateAvatarList()
// Announce position
F32 dist = (F32)(position - mypos).magVec();
entry->setPosition(position, gAgent.getRegion()->pointInRegionGlobal(position), avatarp, dist < 20.0, dist < 100.0);
entry->setPosition(position, gAgent.getRegion()->pointInRegionGlobal(position), avatarp, dist < 20.0, dist < 96.0);
// Mark as typing if they are typing
if (avatarp && avatarp->isTyping()) entry->setActivity(LLAvatarListEntry::ACTIVITY_TYPING);
@@ -659,6 +616,7 @@ void LLFloaterAvatarList::expireAvatarList()
}
else
{
entry->setPosition(entry->getPosition(), false, false, false, false); // Dead and gone
if(mAvatars.back() == *it)
{
mAvatars.pop_back();
@@ -837,7 +795,7 @@ void LLFloaterAvatarList::refreshAvatarList()
if (UnknownAltitude)
{
strcpy(temp, "?");
if (entry->isDrawn())
if (entry->mStats[STAT_TYPE_DRAW])
{
color = sRadarTextDrawDist;
}
@@ -858,7 +816,7 @@ void LLFloaterAvatarList::refreshAvatarList()
}
else
{
if (entry->isDrawn())
if (entry->mStats[STAT_TYPE_DRAW])
{
color = sRadarTextDrawDist;
}
@@ -1646,7 +1604,7 @@ void LLFloaterAvatarList::onSelectName()
LLAvatarListEntry* entry = getAvatarEntry(agent_id);
if (entry)
{
BOOL enabled = entry->isDrawn();
BOOL enabled = entry->mStats[STAT_TYPE_DRAW];
childSetEnabled("focus_btn", enabled);
childSetEnabled("prev_in_list_btn", enabled);
childSetEnabled("next_in_list_btn", enabled);

View File

@@ -19,6 +19,7 @@
#include "llscrolllistctrl.h"
#include <time.h>
#include <bitset>
#include <map>
#include <set>
@@ -26,6 +27,16 @@
class LLFloaterAvatarList;
enum ERadarStatType
{
STAT_TYPE_SIM,
STAT_TYPE_DRAW,
STAT_TYPE_SHOUTRANGE,
STAT_TYPE_CHATRANGE,
STAT_TYPE_AGE,
STAT_TYPE_SIZE
};
/**
* @brief This class is used to hold data about avatars.
* We cache data about avatars to avoid repeating requests in this class.
@@ -109,10 +120,6 @@ enum ACTIVITY_TYPE
bool isMarked() const { return mMarked; }
bool isDrawn() const { return (mInDrawFrame != U32_MAX); }
bool isInSim() const { return (mInSimFrame != U32_MAX); }
/**
* @brief 'InList' signifies that the entry has been displayed in the floaters avatar list
* Until this happens our focusprev/focusnext logic should ignore this entry.
@@ -146,9 +153,13 @@ private:
bool mMarked;
bool mFocused;
bool mIsInList;
bool mAgeAlert;
int mAge;
/**
* @brief Bitset to keep track of what stats still hold true about the avatar
*/
std::bitset<STAT_TYPE_SIZE> mStats;
/**
* @brief Timer to keep track of whether avatars are still there
*/
@@ -163,14 +174,6 @@ private:
* @brief Last frame when this avatar was updated
*/
U32 mFrame;
//last frame when this avatar was in sim
U32 mInSimFrame;
//last frame when this avatar was in draw
U32 mInDrawFrame;
//last frame when this avatar was in shout range
U32 mInShoutFrame;
//last frame when this avatar was in chat range
U32 mInChatFrame;
};