1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
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>
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/>.
24 #include "flying_text_manager.h"
25 #include "interface_manager.h"
26 #include "group_in_scene.h"
27 #include "nel/gui/view_text.h"
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();
57 // must have been released
58 nlassert(_InScenePool
.empty() && _InSceneCurrent
.empty());
61 _Root
= "ui:interface";
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
);
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
);
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())
134 // else take an entry
135 it
= _InSceneCurrent
.insert(make_pair(key
, _InScenePool
.back())).first
;
137 _InScenePool
.pop_back();
139 linkToInterface(it
->second
);
142 // this entry is used
143 CGroupInfo
&gi
= it
->second
;
144 gi
.UsedThisFrame
= true;
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;
167 // else new free slot
170 // erase from interface
171 unlinkToInterface(it
->second
);
173 _InScenePool
.push_back(it
->second
);
175 TInSceneCurrentMap::iterator itTmp
= it
++;
176 _InSceneCurrent
.erase(itTmp
);
182 // ***************************************************************************
183 void CFlyingTextManager::linkToInterface(CGroupInfo
&gi
)
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
)
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
);