AnnConsole.cpp
Go to the documentation of this file.
1 // This is an open source non-commercial project. Dear PVS-Studio, please check it.
2 // PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
3 
4 #include "AnnConsole.hpp"
5 #include "AnnEngine.hpp"
6 #include "AnnGetter.hpp"
7 #include "AnnLogger.hpp"
8 
9 #include <Ogre.h>
10 #include <Overlay/OgreFont.h>
11 #include <Overlay/OgreFontManager.h>
12 #include <OgreRenderOperation.h>
13 #include <Hlms/Unlit/OgreHlmsUnlitDatablock.h>
14 #include <OgreHardwarePixelBuffer.h>
15 
16 using namespace Annwvyn;
17 
19  AnnSubSystem("OnScreenConsole"),
20  modified(false),
21  consoleNode(nullptr),
22  offset(0, 0.125f, -0.75f),
23  visibility(false),
24  lastUpdate{ 0 },
25  refreshRate{ 1.0 / 15.0 },
26  historyStatus{ -1 },
27  cursorPos{ 0 }
28 {
29  /*
30  * The displaySurface is a perfect rectangle drawn by 2 polygons (triangles). The position in object-space are defined as following
31  * on the "points" array :
32  * 0 +---------------+ 2
33  * | / |
34  * | / |
35  * | / |
36  * | / |
37  * 1 +---------------+ 3
38  * Texture coordinates are also mapped. To display properly, the texture should respect the same aspect ratio (2:1)
39  */
40 
41  //Define vertex data
42  points[0] = AnnVect3(-0.5, .25, 0);
43  points[1] = AnnVect3(-0.5, -.25, 0);
44  points[2] = AnnVect3(0.5, .25, 0);
45  points[3] = AnnVect3(0.5, -.25, 0);
46 
47  //Define texture coordinates
48  textCoord[0] = AnnVect2(0, 0);
49  textCoord[1] = AnnVect2(0, 1);
50  textCoord[2] = AnnVect2(1, 0);
51  textCoord[3] = AnnVect2(1, 1);
52 
53  //create the quad itself
54  displaySurface = AnnGetEngine()->getSceneManager()->createManualObject();
55  displaySurface->begin("Console", Ogre::OT_TRIANGLE_STRIP); //Strip of triangle : Define a triangle then add them by points
56 
57  //Add the four vertices. This will directly describe two Triangles
58  for(char i(0); i < 4; i++)
59  {
60  displaySurface->position(points[i]);
61  displaySurface->normal(0, 0, 1);
62  displaySurface->tangent(1, 0, 0);
63  displaySurface->textureCoord(textCoord[i]);
64  displaySurface->index(i);
65  }
66 
67  //Object complete
68  displaySurface->end();
69 
70  displaySurface->setCastShadows(false);
71 
72  //create a node child to the camera here :
73  consoleNode = AnnGetEngine()->getSceneManager()->getRootSceneNode()->createChildSceneNode();
74 
75  //attach The object
76  consoleNode->attachObject(displaySurface);
77 
78  //set the player relative position
79  consoleNode->setPosition(offset + AnnGetPlayer()->getEyesHeight() * AnnVect3::UNIT_Y);
80 
81  //Make sure the object is the last thing rendered (to be on top of everything
82  //displaySurface->setRenderQueueGroup(Ogre::uint8(-1));
83  //Set the visibility state
84  consoleNode->setVisible(visibility);
85 
86  //Create a The font
87  if(!Ogre::FontManager::getSingletonPtr()) //The FontManager isn't initialized by default
88  {
89  //Create a FontManager
90  std::cerr << "FontManager not usable yet. Initializing a new FontManager" << std::endl;
91  // ReSharper disable CppNonReclaimedResourceAcquisition
92  // Reason : Ogre will cleanup the FontManager when cleaning root.
93  OGRE_NEW Ogre::FontManager();
94  // ReSharper restore CppNonReclaimedResourceAcquisition
95  }
96 
97  //Create a manual font
98  font = Ogre::FontManager::getSingleton().create("VeraMono", AnnResourceManager::getDefaultResourceGroupName());
99 
100  //Load the VeraMono.ttf file
101  font->setType(Ogre::FontType::FT_TRUETYPE);
102  font->setSource("VeraMono.ttf");
103  font->setTrueTypeResolution(96);
104  font->setTrueTypeSize(BASE / 32); //Size of font is relative to the size of the pixel-buffer (texture)
105 
106  //Aspect ration of the console is 2:1. The actual size of texture is 2*BASE x BASE
107  //Create an map the texture to the displaySurface
108  texture = Ogre::TextureManager::getSingleton().createManual("Write Texture", AnnResourceManager::getDefaultResourceGroupName(), Ogre::TEX_TYPE_2D, 2 * BASE, BASE, Ogre::MIP_UNLIMITED, Ogre::PF_X8R8G8B8, Ogre::TU_AUTOMIPMAP | Ogre::TU_RENDERTARGET);
109 
110  auto datablock = AnnGetVRRenderer()->getRoot()->getHlmsManager()->getDatablock("Console");
111  if(auto unlitDatablock = reinterpret_cast<Ogre::HlmsUnlitDatablock*>(datablock))
112  {
113  AnnDebug() << "got unlit datablock for "
114  << "Console";
115  unlitDatablock->setTexture(Ogre::HlmsTextureManager::TEXTURE_TYPE_DIFFUSE, 0, texture);
116  }
117 
118  //Load background texture to a buffer
119  background = Ogre::TextureManager::getSingleton().load("background.png", AnnResourceManager::getDefaultResourceGroupName());
120 
121  //Initialize the text buffer.
122  //CONSOLE_BUFFER is the number of lines to keep in memory and to load on the texture.
123  //Text is drawn from the 1st line. The number of line define how main lines are visible on the console
124  for(size_t i(0); i < CONSOLE_BUFFER; i++)
125  buffer[i] = "";
126 
127  //Get the opengl ids
128  if(Ogre::Root::getSingleton().getRenderSystem()->getName()
129  == "OpenGL 3+ Rendering Subsystem")
130  {
131  background->getCustomAttribute("GLID", &backgroundID);
132  texture->getCustomAttribute("GLID", &textureID);
133  }
134 }
135 
137 {
138  rotate(begin(buffer), begin(buffer) + 1, end(buffer));
139  buffer[CONSOLE_BUFFER - 1] = str;
140 
141  //The console will be redrawn next frame
142  modified = true;
143 }
144 
145 void AnnConsole::setVisible(bool state)
146 {
147  visibility = state;
148  AnnGetEventManager()->keyboardUsedForText(visibility);
149  if(visibility)
150  AnnGetEventManager()->getTextInputer()->startListening();
151  else
152  AnnGetEventManager()->getTextInputer()->stopListening();
153 
154  consoleNode->setVisible(visibility);
155 }
156 
158 {
160 }
161 
163 {
164  //Updated
165  modified = false;
167 
168  //Get the content of the buffer into a static string
169  std::stringstream content;
170 
171  //For each line
172  for(auto i{ 0 }; i < CONSOLE_BUFFER; i++)
173  {
174  //Make the len fit the screen
175  auto logLine = buffer[i].substr(0, MAX_CONSOLE_LOG_WIDTH);
176 
177  //No newline char
178  for(auto j{ 0 }; j < logLine.size(); j++)
179  if(logLine[j] == '\n') logLine[j] = '|';
180 
181  //Append to display content
182  content << logLine << '\n';
183  }
184 
185  //horizontal separator
186  for(auto i{ 0 }; i < MAX_CONSOLE_LOG_WIDTH; ++i) content << "-";
187 
188  //Command Invite
189  content << "\n%> ";
190  auto textInputer = AnnGetEventManager()->getTextInputer();
191  auto command = textInputer->getInput();
192  cursorPos = textInputer->getCursorOffset();
193  if(command.empty())
194  {
195  cursorPos = 0;
196  textInputer->setCursorOffset(cursorPos);
197  }
198 
199  std::string strippedCommand;
200  //Display with a scrolling window
201  if(!command.empty())
202  {
203  strippedCommand = command.substr(std::max(0, int(command.size()) - (MAX_CONSOLE_LOG_WIDTH - 5)), command.size());
204  content << strippedCommand;
205  if(command[command.size() - 1] == '\r')
206  {
207  //Execute command code here
208  runInput(command);
209  AnnGetEventManager()->getTextInputer()->clearInput();
210  cursorPos = 0;
211  }
212  }
213 
214  //Append blinking cursor
215  //if (static_cast<int>(4 * AnnGetEngine()->getTimeFromStartupSeconds()) % 2) content << "_";
216  const auto textToDisplay = content.str();
217 
218  //Erase plane (draw background)
219  glCopyImageSubData(backgroundID, GL_TEXTURE_2D, 0, 0, 0, 0, textureID, GL_TEXTURE_2D, 0, 0, 0, 0, texture->getSrcWidth(), texture->getSrcHeight(), 1);
220 
221  //Write text to texture
222  WriteToTexture(textToDisplay, //Text
223  texture, //Texture
224  Ogre::Image::Box(0 + MARGIN, 0 + MARGIN, 2 * BASE - MARGIN, BASE - MARGIN), //Part of the pixel buffer to write to
225  font.get(),
226  Ogre::ColourValue::Black, //Color
227  'l',
228  true); //Alignment
229 
230  std::string cursor;
231  for(auto i = 0; i < CONSOLE_BUFFER + 1; ++i) cursor += '\n';
232  cursor += ". ";
233  for(auto i = 0; i < std::max(0, int(strippedCommand.size()) - cursorPos); ++i) cursor += ' ';
234  cursor += '_';
235 
236  WriteToTexture(cursor,
237  texture,
238  Ogre::Image::Box(0 + MARGIN, 0 + MARGIN, 2 * BASE - MARGIN, BASE - MARGIN), //Part of the pixel buffer to write to
239  font.get(),
240  Ogre::ColourValue::Blue,
241  'l',
242  true);
243 }
244 
246 {
247  for(const auto& forbiddenKeyword : forbidden)
248  if(keyword == forbiddenKeyword)
249  return true;
250  return false;
251 }
252 
253 void AnnConsole::WriteToTexture(const Ogre::String& str, Ogre::TexturePtr destTexture, Ogre::Image::Box destRectangle, Ogre::Font* font, const Ogre::ColourValue& color, char justify, bool wordwrap)
254 {
255  using namespace Ogre;
256 
257  if(destTexture->getHeight() < destRectangle.bottom)
258  destRectangle.bottom = destTexture->getHeight();
259  if(destTexture->getWidth() < destRectangle.right)
260  destRectangle.right = destTexture->getWidth();
261 
262  if(!font->isLoaded())
263  font->load();
264 
265  auto fontTexture = TexturePtr(TextureManager::getSingleton().getByName(font->getMaterial()->getTechnique(0)->getPass(0)->getTextureUnitState(0)->getTextureName()));
266 
267  auto fontBuffer = fontTexture->getBuffer();
268  auto destBuffer = destTexture->getBuffer();
269 
270  const auto destPb = destBuffer->lock(destRectangle, v1::HardwareBuffer::HBL_NORMAL);
271 
272  // The font texture textureBuffer was created write only...so we cannot read it back :o). One solution is to copy the textureBuffer instead of locking it. (Maybe there is a way to create a font texture which is not write_only ?)
273 
274  // create a textureBuffer
275  const auto nBuffSize = fontBuffer->getSizeInBytes();
276  const auto textureBuffer = static_cast<uint8*>(calloc(nBuffSize, sizeof(uint8)));
277 
278  // create pixel box using the copy of the textureBuffer
279  const PixelBox fontPb(fontBuffer->getWidth(), fontBuffer->getHeight(), fontBuffer->getDepth(), fontBuffer->getFormat(), textureBuffer);
280  fontBuffer->blitToMemory(fontPb);
281 
282  const auto fontData = static_cast<uint8*>(fontPb.data);
283  const auto destData = static_cast<uint8*>(destPb.data);
284 
285  const auto fontPixelSize = PixelUtil::getNumElemBytes(fontPb.format);
286  const auto destPixelSize = PixelUtil::getNumElemBytes(destPb.format);
287 
288  const auto fontRowPitchBytes = fontPb.rowPitch * fontPixelSize;
289  const auto destRowPitchBytes = destPb.rowPitch * destPixelSize;
290 
291  std::vector<Box> GlyphTexCoords(str.size());
292 
293  size_t charheight = 0;
294  size_t charwidth = 0;
295 
296  for(unsigned int i = 0; i < str.size(); i++)
297  {
298  if((str[i] != '\t') && (str[i] != '\n') && (str[i] != ' '))
299  {
300  auto glypheTexRect = font->getGlyphTexCoords(str[i]);
301  GlyphTexCoords[i].left = uint32_t(glypheTexRect.left * fontTexture->getSrcWidth());
302  GlyphTexCoords[i].top = uint32_t(glypheTexRect.top * fontTexture->getSrcHeight());
303  GlyphTexCoords[i].right = uint32_t(glypheTexRect.right * fontTexture->getSrcWidth());
304  GlyphTexCoords[i].bottom = uint32_t(glypheTexRect.bottom * fontTexture->getSrcHeight());
305 
306  if(GlyphTexCoords[i].getHeight() > charheight)
307  charheight = GlyphTexCoords[i].getHeight();
308  if(GlyphTexCoords[i].getWidth() > charwidth)
309  charwidth = GlyphTexCoords[i].getWidth();
310  }
311  }
312 
313  //get the size of the glyph '0'
314  const auto glypheTexRect = font->getGlyphTexCoords('0');
315  Box spaceBox;
316  spaceBox.left = uint32_t(glypheTexRect.left * fontTexture->getSrcWidth());
317  spaceBox.right = uint32_t(glypheTexRect.right * fontTexture->getSrcWidth());
318  auto spacewidth = spaceBox.getWidth();
319 
320  //if not mono-spaced
321  if(spacewidth != charwidth) spacewidth = size_t(float(spacewidth) * 0.5f);
322 
323  size_t cursorX = 0;
324  size_t cursorY = 0;
325  auto lineend = destRectangle.getWidth();
326  auto carriagreturn = true;
327  for(size_t strindex = 0; strindex < str.size(); strindex++)
328  {
329  switch(str[strindex])
330  {
331  case ' ': cursorX += spacewidth; break;
332  case '\t': cursorX += charwidth * 3; break;
333  case '\n':
334  cursorY += charheight;
335  carriagreturn = true;
336  break;
337  default:
338  {
339  //wrapping
340  if((cursorX + GlyphTexCoords[strindex].getWidth() > lineend) && !carriagreturn)
341  {
342  cursorY += charheight;
343  carriagreturn = true;
344  }
345 
346  //justify
347  if(carriagreturn)
348  {
349  auto l = strindex;
350  size_t textwidth = 0;
351  size_t wordwidth = 0;
352 
353  while((l < str.size()) && (str[l] != '\n'))
354  {
355  wordwidth = 0;
356 
357  switch(str[l])
358  {
359  case ' ':
360  wordwidth = charwidth;
361  ++l;
362  break;
363  case '\t':
364  wordwidth = charwidth * 3;
365  ++l;
366  break;
367  case '\n': l = str.size();
368  default: break;
369  }
370 
371  if(wordwrap)
372  while((l < str.size()) && (str[l] != ' ') && (str[l] != '\t') && (str[l] != '\n'))
373  {
374  wordwidth += GlyphTexCoords[l].getWidth();
375  ++l;
376  }
377  else
378  {
379  wordwidth += GlyphTexCoords[l].getWidth();
380  l++;
381  }
382 
383  if((textwidth + wordwidth) <= destRectangle.getWidth())
384  textwidth += (wordwidth);
385  else
386  break;
387  }
388 
389  if((textwidth == 0) && (wordwidth > destRectangle.getWidth()))
390  textwidth = destRectangle.getWidth();
391 
392  switch(justify)
393  {
394  case 'c':
395  cursorX = (destRectangle.getWidth() - textwidth) / 2;
396  lineend = destRectangle.getWidth() - uint32(cursorX);
397  break;
398 
399  case 'r':
400  cursorX = (destRectangle.getWidth() - textwidth);
401  lineend = destRectangle.getWidth();
402  break;
403 
404  default:
405  cursorX = 0;
406  lineend = uint32(textwidth);
407  break;
408  }
409 
410  carriagreturn = false;
411  }
412 
413  //abort - not enough space to draw
414  if((cursorY + charheight) > destRectangle.getHeight())
415  goto stop;
416 
417  //draw pixel by pixel
418  for(size_t i = 0; i < GlyphTexCoords[strindex].getHeight(); i++)
419  for(size_t j = 0; j < GlyphTexCoords[strindex].getWidth(); j++)
420  {
421  const auto alpha = float(color.a * (fontData[(i + GlyphTexCoords[strindex].top) * fontRowPitchBytes + (j + GlyphTexCoords[strindex].left) * fontPixelSize + 1] / 255.0));
422  const auto invalpha = 1.0f - alpha;
423  const auto charOffset = (i + cursorY) * destRowPitchBytes + (j + cursorX) * destPixelSize;
424  ColourValue pix;
425  PixelUtil::unpackColour(&pix, destPb.format, &destData[charOffset]);
426  pix = (pix * invalpha) + (color * alpha);
427  PixelUtil::packColour(pix, destPb.format, &destData[charOffset]);
428  }
429 
430  cursorX += GlyphTexCoords[strindex].getWidth();
431  } //default
432  } //switch
433  } //for
434 
435 stop:
436 
437  destBuffer->unlock();
438 
439  // Free the memory allocated for the textureBuffer
440  free(textureBuffer);
441 }
442 
444 {
445  const auto& command = commandHistory[historyStatus];
446  if(!command.empty())
447  {
448  AnnGetEventManager()->getTextInputer()->setInput(command);
449  return false;
450  }
451  return true;
452 }
453 
455 {
456  if(!visibility) return;
457 
458  switch(code)
459  {
460  default: break;
461  case KeyCode::up:
462  //AnnDebug() << "history command!";
463  historyStatus++;
467  historyStatus--;
468  break;
469  case KeyCode::down:
470  historyStatus--;
471  if(historyStatus <= -1)
472  {
473  historyStatus = -1;
474  break;
475  }
477  break;
478  case KeyCode::right:
479  cursorPos--;
480  if(cursorPos < 0) cursorPos = 0;
481  AnnGetEventManager()->getTextInputer()->setCursorOffset(cursorPos);
482  break;
483  case KeyCode::left:
484  cursorPos++;
485  AnnGetEventManager()->getTextInputer()->setCursorOffset(cursorPos);
486  }
487 }
488 
490 {
491  const auto targetPosition = AnnGetVRRenderer()->trackedHeadPose.position + AnnGetVRRenderer()->trackedHeadPose.orientation * offset;
492  const auto targetOrientaiton = AnnGetVRRenderer()->trackedHeadPose.orientation;
493 
494  consoleNode->setPosition(targetPosition);
495  consoleNode->setOrientation(static_cast<Ogre::Quaternion>(targetOrientaiton));
496 }
497 
499 {
501 
502  if(AnnGetEngine()->getTimeFromStartupSeconds() - lastUpdate > refreshRate)
503  modified = true;
504 
505  return modified && visibility;
506 }
507 
509 {
510  //do some cleanup on the inputed string
511  //remove the \r termination
512  input.pop_back();
513 
514  addToHistory(input);
515  historyStatus = -1;
516 
517  //Echo the command to the console
518  AnnDebug(Log::Important) << "% - " << input;
519 
520  //Prevent to start with some chaiscript symbols in global space.
521  std::string firstWord;
522  std::stringstream inputStream(input);
523  inputStream >> firstWord;
524 
525  if(isForbdiden(firstWord))
526  {
527  AnnDebug(Log::Important) << "Console input error : " << firstWord << " is a forbidden keyword";
528  return;
529  }
530 
531  if(runSpecialInput(input)) return;
532 
533  try
534  {
535  AnnGetScriptManager()->evalString(input);
536  }
537  catch(const chaiscript::exception::eval_error& eval_error)
538  {
539  AnnDebug(Log::Important) << "Console script error : " << input;
540  AnnDebug(Log::Important) << eval_error.what();
541  AnnDebug(Log::Important) << eval_error.pretty_print();
542  }
543 }
544 
546 {
547  if(input.empty()) return;
548  std::rotate(std::rbegin(commandHistory), std::rbegin(commandHistory) + 1, std::rend(commandHistory));
549  commandHistory[0] = input;
550 }
551 
553 {
554  if(input == "help")
555  {
556  bufferClear();
557  append("You asked for help :");
558  append("This debug console understand the same thing as the integrated");
559  append("scripting language.");
560  append("However, it runs on global space. To prevent breaking stuff");
561  append("you can't create global variables from that console. You have to");
562  append("reference GameObject by their name for example");
563  append("You can display this help by typing \"help\"");
564 
565  return true;
566  }
567 
568  else if(input == "status")
569  {
570  bufferClear();
571  auto currentLevel = AnnGetLevelManager()->getCurrentLevel();
572  size_t nbControllers;
573 
574  append("Running VR system: " + AnnGetVRRenderer()->getName());
575  append("LevelManager: " + std::to_string(currentLevel->getContent().size()) + " active objects");
576  append("LevelManager: " + std::to_string(currentLevel->getLights().size()) + " active light sources");
577  append("LevelManager: " + std::to_string(currentLevel->getTriggers().size()) + " physics trigger object");
578  append("HandController : " + std::to_string(nbControllers = AnnGetVRRenderer()->getHanControllerArraySize()) + " max tracked controllers");
579 
580  if(nbControllers > 0)
581  {
582  if(AnnGetVRRenderer()->getHandControllerArray()[0])
583  {
584  append("HandControllers connected");
585  append("HandController types : " + AnnGetVRRenderer()->getHandControllerArray()[0]->getTypeString());
586  }
587  else
588  {
589  append("No HandControllers active");
590  }
591  }
592  return true;
593  }
594 
595  return false;
596 }
597 
599 {
600  for(auto& line : buffer)
601  line.clear();
602 }
603 
605 {
606  font.setNull();
607 }
bool needUpdate() override
True if text has been updated on the console and the console is visible.
Definition: AnnConsole.cpp:498
static constexpr auto MARGIN
Definition: AnnConsole.hpp:34
const double refreshRate
Delay in seconds to re-refresh the console.
Definition: AnnConsole.hpp:131
Ogre::SceneNode * consoleNode
Node where the console is attached.
Definition: AnnConsole.hpp:107
void runInput(std::string &input)
Cleanup and run the user input.
Definition: AnnConsole.cpp:508
T empty(T... args)
GLuint backgroundID
OpenGL Texture IDs, to use glCopyImageSubData to clone texture quickly.
Definition: AnnConsole.hpp:119
static constexpr auto BASE
Definition: AnnConsole.hpp:33
AnnEngine * AnnGetEngine()
Get the current instance of AnnEngine.
Definition: AnnGetter.cpp:10
AnnVect3 offset
Position of the plane using the camera as reference.
Definition: AnnConsole.hpp:113
void syncConsolePosition() const
Move the console where it should.
Definition: AnnConsole.cpp:489
Ogre::FontPtr font
The font object used, should be Vera Mono in true type format from the Gnome project, included in CORE resources.
Definition: AnnConsole.hpp:122
Represent the output console that can be shown by calling AnnEngine::toggleOnScreenConsole() This cla...
void setVisible(bool visibility=true)
Set arbitrary the visibility state of the console. Visible if no arg given, hide it if visibility = f...
Definition: AnnConsole.cpp:145
void bufferClear()
Clear the text draw buffer of the console.
Definition: AnnConsole.cpp:598
T to_string(T... args)
static constexpr auto CONSOLE_HISTORY
Definition: AnnConsole.hpp:35
T endl(T... args)
Ogre::TexturePtr texture
The actual texture of the display.
Definition: AnnConsole.hpp:110
A 3D Vector.
Definition: AnnVect3.hpp:16
AnnConsole()
Construct the console. This should only be called by AnnEngine itself when the camera and ogre are op...
Definition: AnnConsole.cpp:18
void notifyNavigationKey(KeyCode::code code)
Method to be called for navigation keys.
Definition: AnnConsole.cpp:454
std::array< const char *, 2 > forbidden
Array of forbidden keyword to check.
Definition: AnnConsole.hpp:67
int historyStatus
Status of the history.
Definition: AnnConsole.hpp:137
Namespace containing the totality of Annwvyn components.
Definition: AnnGetter.cpp:8
AnnOgreVRRendererPtr AnnGetVRRenderer()
Get the VR renderer.
Definition: AnnGetter.cpp:20
bool setFromPointedHistory()
return true if pointed to an empty slot
Definition: AnnConsole.cpp:443
static const char * getDefaultResourceGroupName()
Return the default resource group name.
void addToHistory(const std::string &input)
Push the inputed text into the command history.
Definition: AnnConsole.cpp:545
Create a ostream to the Ogre logger.
Ogre::SceneManager * getSceneManager() const
Get ogre scene manager.
Definition: AnnEngine.cpp:331
void update() override
Definition: AnnConsole.cpp:162
AnnLevelManagerPtr AnnGetLevelManager()
Get the level manager.
Definition: AnnGetter.cpp:15
T pop_back(T... args)
bool runSpecialInput(const std::string &input)
Run input that are not regular script commands.
Definition: AnnConsole.cpp:552
T str(T... args)
int cursorPos
Position of the text cursor, indexed from the end of the string.
Definition: AnnConsole.hpp:140
Open an output stream to the engine log.
Definition: AnnLogger.hpp:24
double getTimeFromStartupSeconds() const
Get elapsed time from engine startup in seconds.
Definition: AnnEngine.cpp:333
T max(T... args)
bool isForbdiden(const std::string &keyword)
Return true if the given string match with any of the forbidden keyword int the array.
Definition: AnnConsole.cpp:245
bool modified
True if content of the buffer has been modified.
Definition: AnnConsole.hpp:92
Main Annwvyn Engine class Initialize the renderer and all subsystem. Provide access to all of the eng...
double lastUpdate
Timestamp in seconds since the start of the game the last console refresh was performed.
Definition: AnnConsole.hpp:128
Parent class of all Annwvyn SubSystem.
T size(T... args)
static constexpr auto CONSOLE_BUFFER
Definition: AnnConsole.hpp:31
static constexpr auto MAX_CONSOLE_LOG_WIDTH
Definition: AnnConsole.hpp:32
std::array< std::string, CONSOLE_HISTORY > commandHistory
Buffer of strings containing past run commands.
Definition: AnnConsole.hpp:134
AnnEventManagerPtr AnnGetEventManager()
Get the event manager.
Definition: AnnGetter.cpp:16
T rotate(T... args)
T substr(T... args)
std::string buffer[CONSOLE_BUFFER]
Buffer of string objects.
Definition: AnnConsole.hpp:101
Ogre::Vector2 AnnVect2
Definition: AnnTypes.h:28
bool visibility
If false, the console is not visible.
Definition: AnnConsole.hpp:125
Definition: euler.h:16
AnnPlayerBodyPtr AnnGetPlayer()
Get the player object.
Definition: AnnGetter.cpp:17
AnnScriptManagerPtr AnnGetScriptManager()
Get the script manager.
Definition: AnnGetter.cpp:21
void append(const std::string &string)
Definition: AnnConsole.cpp:136
void toggle()
Toggle the console.
Definition: AnnConsole.cpp:157
~AnnConsole()
Destructor.
Definition: AnnConsole.cpp:604
static void WriteToTexture(const Ogre::String &str, Ogre::TexturePtr destTexture, Ogre::Image::Box destRectangle, Ogre::Font *font, const Ogre::ColourValue &color, char justify='l', bool wordwrap=false)
This piece of code if from the Ogre Wiki. Write text to a texture using Ogre::FontManager to create g...
Definition: AnnConsole.cpp:253