Merge branch '138-toggle-free-look-with-hotkey' into main/gingo-test
[ryzomcore.git] / ryzom / client / src / interface_v3 / flying_text_manager.cpp
blob37daf2f9ed08ab67d7d95247dfafda3400e62130
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2013 Laszlo KIS-ADAM (dfighter) <dfighter1985@gmail.com>
6 // Copyright (C) 2020 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
7 //
8 // This program is free software: you can redistribute it and/or modify
9 // it under the terms of the GNU Affero General Public License as
10 // published by the Free Software Foundation, either version 3 of the
11 // License, or (at your option) any later version.
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU Affero General Public License for more details.
18 // You should have received a copy of the GNU Affero General Public License
19 // along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "stdpch.h"
24 #include "flying_text_manager.h"
25 #include "interface_manager.h"
26 #include "group_in_scene.h"
27 #include "nel/gui/view_text.h"
30 using namespace std;
31 using namespace NLMISC;
34 // 500 seems to add at max 200Ko in memory (estimation done with the WindowTaskManager, so not really accurate)
35 const uint MaxFlyingText= 500;
38 // ***************************************************************************
39 CFlyingTextManager::CFlyingTextManager()
41 _CharacterWindowOffsetX= 0;
44 // ***************************************************************************
45 CFlyingTextManager::~CFlyingTextManager()
47 // must have been released
48 nlassert(_InScenePool.empty() && _InSceneCurrent.empty());
51 // ***************************************************************************
52 void CFlyingTextManager::initInGame()
54 CInterfaceManager *pIM = CInterfaceManager::getInstance();
55 nlassert (pIM);
57 // must have been released
58 nlassert(_InScenePool.empty() && _InSceneCurrent.empty());
60 // get the root ptr
61 _Root= "ui:interface";
63 // create all
64 _InScenePool.reserve(MaxFlyingText);
65 for(uint i=0;i<MaxFlyingText;i++)
67 // create the in scene group
68 string id = "in_scene_flying_text_"+toString (i);
69 std::vector<std::pair<std::string,std::string> > templateParams;
70 templateParams.push_back (std::pair<std::string,std::string>("id", id));
71 CInterfaceGroup *groupInfo = CWidgetManager::getInstance()->getParser()->createGroupInstance ("in_scene_flying_text",
72 "ui:interface", templateParams);
73 // if ok
74 if(groupInfo)
76 CGroupInfo gi;
77 gi.GroupInScene= dynamic_cast<CGroupInScene*>(groupInfo);
78 gi.ViewText= dynamic_cast<CViewText*>(groupInfo->getView("text"));
79 // if ok append, else delete and abort
80 if(gi.GroupInScene && gi.GroupInScene)
82 _InScenePool.push_back(gi);
83 /* don't link to the interface now. Prefer do this to avoid big number of window to parse
84 each frame for nothing because they are hid.
85 This save 1ms per frame for 1000 window created but not displayed....
86 NB: the cost of link/unlink instead of a setActive() is negligible in effect
88 gi.GroupInScene->setActive(true);
89 nlassert(gi.GroupInScene->getParent()==NULL);
91 else
93 delete groupInfo;
98 // misc
99 fromString(CWidgetManager::getInstance()->getParser()->getDefine("in_scene_flying_char_offsetx"), _CharacterWindowOffsetX);
102 // ***************************************************************************
103 void CFlyingTextManager::releaseInGame()
105 // **** unlink all nodes from interface
106 TInSceneCurrentMap::iterator it= _InSceneCurrent.begin();
107 for(;it!=_InSceneCurrent.end();it++)
109 it->second.UsedThisFrame= false;
111 releaseNotUsedFlyingText();
112 nlassert(_InSceneCurrent.empty());
114 // **** delete the pool
115 for(uint i=0;i<_InScenePool.size();i++)
117 // since unlinked from window list and group list, just delete
118 delete _InScenePool[i].GroupInScene;
120 _InScenePool.clear();
123 // ***************************************************************************
124 void CFlyingTextManager::addFlyingText(void *key, const string &text, const NLMISC::CVector &pos, CRGBA color, float scale, sint offsetX)
126 // key exist in the map?
127 TInSceneCurrentMap::iterator it= _InSceneCurrent.find(key);
128 // no, try to allocate a new entry
129 if(it==_InSceneCurrent.end())
131 // no more free group, abort
132 if(_InScenePool.empty())
133 return;
134 // else take an entry
135 it= _InSceneCurrent.insert(make_pair(key, _InScenePool.back())).first;
136 // and no more free
137 _InScenePool.pop_back();
138 // link to interface
139 linkToInterface(it->second);
142 // this entry is used
143 CGroupInfo &gi= it->second;
144 gi.UsedThisFrame= true;
146 // update infos
147 gi.ViewText->setText(text);
148 gi.ViewText->setColor(color);
149 gi.GroupInScene->Position= pos;
150 gi.GroupInScene->Scale= scale;
151 gi.GroupInScene->setOffsetX(offsetX);
154 // ***************************************************************************
155 void CFlyingTextManager::releaseNotUsedFlyingText()
157 // for all elements of inscene current
158 TInSceneCurrentMap::iterator it= _InSceneCurrent.begin();
159 for(;it!=_InSceneCurrent.end();)
161 // if used this frame, don't remove
162 if(it->second.UsedThisFrame)
164 it->second.UsedThisFrame= false;
165 it++;
167 // else new free slot
168 else
170 // erase from interface
171 unlinkToInterface(it->second);
172 // back to pool
173 _InScenePool.push_back(it->second);
174 // erase from map
175 TInSceneCurrentMap::iterator itTmp= it++;
176 _InSceneCurrent.erase(itTmp);
182 // ***************************************************************************
183 void CFlyingTextManager::linkToInterface(CGroupInfo &gi)
185 if(!_Root)
186 return;
188 // should not be linked
189 nlassert(gi.GroupInScene->getParent()==NULL);
191 // add to group and window list
192 CInterfaceManager *pIM= CInterfaceManager::getInstance();
193 CWidgetManager::getInstance()->addWindowToMasterGroup("ui:interface", gi.GroupInScene);
194 gi.GroupInScene->setParent(_Root);
195 _Root->addGroup (gi.GroupInScene);
198 // ***************************************************************************
199 void CFlyingTextManager::unlinkToInterface(CGroupInfo &gi)
201 if(!_Root)
202 return;
204 // should be linked
205 nlassert(gi.GroupInScene->getParent()!=NULL);
207 // remove from group and window list
208 CInterfaceManager *pIM= CInterfaceManager::getInstance();
209 CWidgetManager::getInstance()->unMakeWindow(gi.GroupInScene);
210 // remove but don't delete
211 gi.GroupInScene->getParent()->delGroup(gi.GroupInScene, true);
212 gi.GroupInScene->setParent(NULL);