/* Copyright 2003-2005 ROBLOX Corporation, All Rights Reserved */ #include "stdafx.h" #include "V8DataModel/GuiBuilder.h" #include "V8DataModel/Commands.h" #include "V8DataModel/GameBasicSettings.h" #include "V8DataModel/DataModel.h" #include "V8DataModel/Workspace.h" #include "V8DataModel/SafeChat.h" #include "V8DataModel/ContentProvider.h" #include "V8DataModel/GameBasicSettings.h" #include "V8DataModel/PhysicsSettings.h" #include "V8Tree/Verb.h" #include "Network/Players.h" #include "Network/../../NetworkSettings.h" #include "Util/Color.h" #include "Util/FileSystem.h" #include "Util/profiling.h" #include "Gui/GUI.h" #include "Gui/EquationDisplay.h" #include "Gui/ChatOutput.h" #include "Gui/ChatWidget.h" #include "Humanoid/Humanoid.h" #include #include #include "Script/ScriptContext.h" #include "V8DataModel/Frame.h" #include "V8DataModel/TextLabel.h" #include "V8DataModel/ScreenGui.h" #include "V8DataModel/ImageLabel.h" #include "V8DataModel/ImageButton.h" #include "V8DataModel/PlayerGui.h" #include "SimpleJSON.h" #include "v8datamodel/Stats.h" FASTFLAGVARIABLE(DebugDisplayFPS, false) FASTFLAGVARIABLE(LuaBasedBubbleChat, false) using namespace G3D; namespace RBX { static GuiBuilder::Display gDebugDisplay = GuiBuilder::DISPLAY_NONE; static boost::filesystem::path GetCustomStatsFilename() { return RBX::FileSystem::getUserDirectory(false, RBX::DirExe, "ClientSettings") / "StatDisplaySettings.json"; } class CustomStatsGuiJSON : public SimpleJSON { public: CustomStatsGuiJSON(GuiBuilder* guiBuilder); virtual bool DefaultHandler(const std::string& valueName, const std::string& valueData); void WriteFile(); private: CustomStatsGuiJSON() {}; GuiBuilder* mGuiBuilder; }; CustomStatsGuiJSON::CustomStatsGuiJSON(GuiBuilder* guiBuilder) : mGuiBuilder(guiBuilder) { // this space intentionally left blank } bool CustomStatsGuiJSON::DefaultHandler(const std::string& valueName, const std::string& valueData) { shared_ptr item = Creatable::create(valueName + " : ", valueData); GuiBuilder::Data data; data.stat = valueData; data.item = item; mGuiBuilder->customStatsCont.insert(make_pair(valueName, data)); return true; } void CustomStatsGuiJSON::WriteFile() { std::ofstream localConfigFile(GetCustomStatsFilename().native().c_str()); if(localConfigFile.is_open()) { std::stringstream localConfigBuffer; localConfigFile.write("{\n", 2); for (GuiBuilder::CustomStatsContainer::iterator itr = mGuiBuilder->customStatsCont.begin(); itr != mGuiBuilder->customStatsCont.end(); ++itr) { std::string output = "\t\"" + itr->first + "\": \"" + itr->second.stat + "\",\n"; localConfigFile.write(output.c_str(), output.length()); } localConfigFile.write("}", 1); } } GuiBuilder::Display GuiBuilder::getDebugDisplay() { return gDebugDisplay; } void GuiBuilder::setDebugDisplay(Display display) { gDebugDisplay = display; } Verb* GuiBuilder::getWhitelistVerb(const std::string& name) { RBXASSERT(workspace); Verb* answer = workspace->getWhitelistVerb(name); return answer; } void GuiBuilder::buildSimpleStatsOutput(shared_ptr instance, std::string* output) { if (Stats::Item* item = instance->fastDynamicCast()) { std::string itemName = item->getName(); if (itemName.size()<15) { for (size_t i=0; i<15-itemName.size(); i++) { itemName+=" "; } } (*output) += RBX::format("\n%s: %.2f", itemName.c_str(), item->getValue()); } } void GuiBuilder::buildNetworkStatsOutput(shared_ptr instance, std::string* output) { if (Stats::Item* item = instance->fastDynamicCast()) { std::string itemName = item->getName(); if (itemName.size()<15) { for (size_t i=0; i<15-itemName.size(); i++) { itemName+=" "; } } float numPacket = item->getValue(); float avgSize = item->findFirstChildByName("Size")->fastDynamicCast()->getValue(); float kBps = numPacket * avgSize / 1000.f; (*output) += RBX::format("\n%s: %.2f, %.2fB, %.2f", itemName.c_str(), kBps, avgSize, numPacket); } } void GuiBuilder::toggleGeneralStats() { FASTLOG(FLog::Verbs, "Gui:Stats"); GuiRoot* guiRoot = dataModel->getGuiRoot(); TopMenuBar* statsMenu = Instance::fastDynamicCast(guiRoot->findFirstChildByName("StatsHud1")); if (statsMenu!=NULL) statsMenu->setVisible(!statsMenu->isVisible()); statsMenu = Instance::fastDynamicCast(guiRoot->findFirstChildByName("StatsHud2")); if (statsMenu!=NULL) statsMenu->setVisible(!statsMenu->isVisible()); } void GuiBuilder::toggleRenderStats() { FASTLOG(FLog::Verbs, "Gui:RenderStats"); GuiRoot* guiRoot = dataModel->getGuiRoot(); TopMenuBar* statsMenu = Instance::fastDynamicCast(guiRoot->findFirstChildByName("RenderStats")); if (statsMenu!=NULL) { statsMenu->setVisible(!statsMenu->isVisible()); if (FFlag::DebugDisplayFPS) { TopMenuBar* fpsMenu = Instance::fastDynamicCast(guiRoot->findFirstChildByName("FPS")); if (fpsMenu!=NULL) fpsMenu->setVisible(!statsMenu->isVisible()); } } } void GuiBuilder::toggleNetworkStats() { FASTLOG(FLog::Verbs, "Gui:NetworkStats"); GuiRoot* guiRoot = dataModel->getGuiRoot(); TopMenuBar* statsMenu = Instance::fastDynamicCast(guiRoot->findFirstChildByName("NetworkStats")); if (statsMenu!=NULL) statsMenu->setVisible(!statsMenu->isVisible()); statsMenu = Instance::fastDynamicCast(guiRoot->findFirstChildByName("NetworkStats2")); if (statsMenu!=NULL) { statsMenu->setVisible(!statsMenu->isVisible()); dataModel->setNetworkStatsWindowsOn(statsMenu->isVisible()); if (statsMenu->isVisible()) { oldTrackDataTypesValue = NetworkSettings::singleton().trackDataTypes; oldTrackPhysicsDetailsValue = NetworkSettings::singleton().trackPhysicsDetails; NetworkSettings::singleton().trackDataTypes = true; NetworkSettings::singleton().trackPhysicsDetails = true; } else { NetworkSettings::singleton().trackDataTypes = oldTrackDataTypesValue; NetworkSettings::singleton().trackPhysicsDetails = oldTrackPhysicsDetailsValue; } } } void GuiBuilder::togglePhysicsStats() { FASTLOG(FLog::Verbs, "Gui:PhysicsStats"); GuiRoot* guiRoot = dataModel->getGuiRoot(); TopMenuBar* statsMenu = Instance::fastDynamicCast(guiRoot->findFirstChildByName("PhysicsStats")); if (statsMenu!=NULL) statsMenu->setVisible(!statsMenu->isVisible()); statsMenu = Instance::fastDynamicCast(guiRoot->findFirstChildByName("PhysicsStats2")); if (statsMenu!=NULL) { statsMenu->setVisible(!statsMenu->isVisible()); RBX::Profiling::setEnabled(statsMenu->isVisible()); } } void GuiBuilder::toggleSummaryStats() { FASTLOG(FLog::Verbs, "Gui:SummaryStats"); GuiRoot* guiRoot = dataModel->getGuiRoot(); TopMenuBar* statsMenu = Instance::fastDynamicCast(guiRoot->findFirstChildByName("SummaryStats")); if (statsMenu) statsMenu->setVisible(!statsMenu->isVisible()); } void GuiBuilder::toggleCustomStats() { FASTLOG(FLog::Verbs, "Gui:CustomStats"); GuiRoot* guiRoot = dataModel->getGuiRoot(); TopMenuBar* statsMenu = Instance::fastDynamicCast(guiRoot->findFirstChildByName("CustomStats")); if (statsMenu) statsMenu->setVisible(!statsMenu->isVisible()); } ///////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////// // // TOP LEVEL - BUILD THE GUI // void GuiBuilder::buildGui( Workspace* _workspace, bool buildInGameGui) { Vector2 size; workspace = _workspace; dataModel->getGuiRoot()->addGuiItem(buildStatsHud1()); dataModel->getGuiRoot()->addGuiItem(buildStatsHud2()); dataModel->getGuiRoot()->addGuiItem(buildRenderStats()); dataModel->getGuiRoot()->addGuiItem(buildNetworkStats()); dataModel->getGuiRoot()->addGuiItem(buildNetworkStats2(true)); dataModel->getGuiRoot()->addGuiItem(buildPhysicsStats()); dataModel->getGuiRoot()->addGuiItem(buildPhysicsStats2()); dataModel->getGuiRoot()->addGuiItem(buildFPS()); dataModel->getGuiRoot()->addGuiItem(buildSummaryStats()); dataModel->getGuiRoot()->addGuiItem(buildCustomStats()); if (gDebugDisplay == DISPLAY_FPS) { TopMenuBar* fps = Instance::fastDynamicCast(dataModel->getGuiRoot()->findFirstChildByName("FPS")); RBXASSERT(fps != NULL); if (fps) { fps->setVisible(true); } } if (gDebugDisplay == DISPLAY_PHYSICS || gDebugDisplay == DISPLAY_PHYSICS_AND_OWNER) { TopMenuBar* physicsStats = Instance::fastDynamicCast(dataModel->getGuiRoot()->findFirstChildByName("PhysicsStats")); RBXASSERT(physicsStats != NULL); if (physicsStats) { physicsStats->setVisible(true); } TopMenuBar* physicsStats2 = Instance::fastDynamicCast(dataModel->getGuiRoot()->findFirstChildByName("PhysicsStats2")); RBXASSERT(physicsStats2 != NULL); if (physicsStats2) { physicsStats2->setVisible(true); RBX::Profiling::setEnabled(physicsStats2->isVisible()); } } if (gDebugDisplay == DISPLAY_PHYSICS_AND_OWNER) { RBX::PhysicsSettings &ps = RBX::PhysicsSettings::singleton(); ps.setShowEPhysicsOwners(!ps.getShowEPhysicsOwners()); } if (gDebugDisplay == DISPLAY_SUMMARY) { TopMenuBar* summaryStats = Instance::fastDynamicCast(dataModel->getGuiRoot()->findFirstChildByName("SummaryStats")); RBXASSERT(summaryStats != NULL); if (summaryStats) { summaryStats->setVisible(true); } } if (gDebugDisplay == DISPLAY_RENDER) { TopMenuBar* renderStats = Instance::fastDynamicCast(dataModel->getGuiRoot()->findFirstChildByName("RenderStats")); RBXASSERT(renderStats != NULL); if (renderStats) { renderStats->setVisible(true); } } if(buildInGameGui) { if (shared_ptr topMenuBar = buildChatHud()) { dataModel->getGuiRoot()->addGuiItem(topMenuBar); } dataModel->getGuiRoot()->addGuiItem(buildRightPalette()); buildLuaGui(); } } void GuiBuilder::Initialize(DataModel* _dataModel) { dataModel = _dataModel; } // lua gui into CoreGuiService void GuiBuilder::buildLuaGui() { //////////////////////////////////// TOP LEVEL LUA GUI //////////////////////////////////////// shared_ptr controls = Creatable::create(); controls->setName("ControlFrame"); controls->setBackgroundTransparency(1); controls->setSize(UDim2(1,0,1,0)); controls->setRobloxLocked(true); shared_ptr bottomLeftControl = Creatable::create(); bottomLeftControl->setSize(UDim2(0,130,0,46)); bottomLeftControl->setPosition(UDim2(0,0,1,-46)); bottomLeftControl->setBackgroundTransparency(1); bottomLeftControl->setName("BottomLeftControl"); bottomLeftControl->setRobloxLocked(true); shared_ptr bottomRightControl = Creatable::create(); bottomRightControl->setSize(UDim2(0,180,0,41)); bottomRightControl->setPosition(UDim2(1,-180,1,-41)); bottomRightControl->setBackgroundTransparency(1); bottomRightControl->setName("BottomRightControl"); bottomRightControl->setRobloxLocked(true); shared_ptr topLeftControl = Creatable::create(); topLeftControl->setSize(UDim2(0.05f,0,0.05f,0)); topLeftControl->setBackgroundTransparency(1); topLeftControl->setName("TopLeftControl"); Instance::propRobloxLocked.set(topLeftControl.get(),true); //////////////////////// COREGUI SETUP ////////////////////////////////////// // Add gui into CoreGuiService shared_ptr coreGuiService = shared_from(dataModel->find()); bottomLeftControl->setParent(controls.get()); bottomRightControl->setParent(controls.get()); topLeftControl->setParent(controls.get()); coreGuiService->addChild(controls.get()); } void GuiBuilder::updateGui() { TopMenuBar* summaryStats = Instance::fastDynamicCast(dataModel->getGuiRoot()->findFirstChildByName("SummaryStats")); if (summaryStats && summaryStats->isVisible()) { updateSummaryStats(summaryStats); } } void GuiBuilder::addCustomStat(const std::string& name, const std::string& value) { CustomStatsContainer::iterator itr = customStatsCont.find(name); if (itr == customStatsCont.end()) { TopMenuBar* customStats = Instance::fastDynamicCast(dataModel->getGuiRoot()->findFirstChildByName("CustomStats")); if (customStats) { shared_ptr item = Creatable::create(name + " : ", value); Data data; data.stat = value; data.item = item; customStatsCont.insert(make_pair(name, data)); customStats->addGuiItem(item); item->setFontSize(12); item->setFontColor(G3D::Color3::purple()); item->setBorderColor(G3D::Color4::clear()); item->setGuiSize(Vector2(440, 22)); } } } void GuiBuilder::removeCustomStat(const std::string& name) { CustomStatsContainer::iterator itr = customStatsCont.find(name); if (itr != customStatsCont.end()) { TopMenuBar* customStats = Instance::fastDynamicCast(dataModel->getGuiRoot()->findFirstChildByName("CustomStats")); if (customStats) { shared_ptr item = itr->second.item; item->setParent(NULL); item->setVisible(false); customStatsCont.erase(itr); } } } void GuiBuilder::saveCustomStats() { CustomStatsGuiJSON json(this); json.WriteFile(); } shared_ptr GuiBuilder::buildRightPalette() { Layout layout; layout.layoutStyle = Layout::VERTICAL; layout.xLocation = Rect::RIGHT; layout.yLocation = Rect::BOTTOM; shared_ptr rightPalette = Creatable::create(layout); rightPalette->setName("RightPalette"); return rightPalette; } shared_ptr GuiBuilder::buildChatHud() { if (!FFlag::LuaBasedBubbleChat) { Layout layout; layout.layoutStyle = Layout::VERTICAL; layout.xLocation = Rect::LEFT; layout.yLocation = Rect::TOP; layout.offset.x = 15; layout.offset.y = 100; shared_ptr chatHud = Creatable::create(layout); chatHud->setName("ChatHud"); chatHud->addGuiItem( Creatable::create()); return chatHud; } return shared_ptr(); } void GuiBuilder::removeSafeChatMenu() { if(safeChatMenu) safeChatMenu->setParent(NULL); } void GuiBuilder::addSafeChatMenu() { if(safeChatMenu && dataModel) safeChatMenu->setParent(dataModel->getGuiRoot()); } void GuiBuilder::nextNetworkStats() { int counter = (int)networkStatsCounter; counter++; networkStatsCounter = (NetworkStats)counter; if (networkStatsCounter >= NETWORKSTATS_COUNT) { networkStatsCounter = NETWORKSTATS_FIRST; } GuiItem* item = Instance::fastDynamicCast(dataModel->getGuiRoot()->findFirstChildByName("NetworkStats2")); if (item) { item->setParent(NULL); } dataModel->getGuiRoot()->addGuiItem(buildNetworkStats2(false)); } void GuiBuilder::buildChatMenu(ChatOption *cur, std::string code, shared_ptr parentWidget) { // depth-first recursive construction of the templated chat menu tree for(unsigned int i = 0; i < cur->children.size(); i++) { // Distinguish between regular nodes and the ROOT chat option node, which is first // and for which we don't create an option. ChatOption *child = cur->children[i]; std::ostringstream strstream; strstream << code << ' ' << i; std::string myCode = strstream.str(); shared_ptr menu = Creatable::create(child->text, myCode); parentWidget->addGuiItem(menu); buildChatMenu(child, myCode , menu); } } shared_ptr GuiBuilder::buildChatMenu() { Layout layout; layout.layoutStyle = Layout::VERTICAL; layout.xLocation = Rect::LEFT; layout.yLocation = Rect::TOP; layout.offset.x = 15; layout.offset.y = 130; shared_ptr chatMenuPanel = Creatable::create(layout); chatMenuPanel->setName("ChatMenuPanel"); shared_ptr button = Creatable::create("Chat", GuiDrawImage::NORMAL | GuiDrawImage::DOWN | GuiDrawImage::DISABLE | GuiDrawImage::HOVER); chatMenuPanel->addGuiItem(button); ChatOption *cur = SafeChat::singleton().getChatRoot(); std::string code = ""; buildChatMenu(cur, code, button); return chatMenuPanel; } shared_ptr GuiBuilder::buildStatsHud1() { Layout layout; layout.layoutStyle = Layout::VERTICAL; layout.xLocation = Rect::LEFT; layout.yLocation = Rect::BOTTOM; layout.offset.x = 50; layout.offset.y = 40; layout.backdropColor = GuiItem::translucentBackdrop(); shared_ptr hudArray = Creatable::create(layout); hudArray->setName("StatsHud1"); hudArray->addGuiItem( Creatable::create("" , "----- World ----")); hudArray->addGuiItem( Creatable::create("Instances : ", "numInstances")); hudArray->addGuiItem( Creatable::create("Physics Mode : ", "physicsMode")); hudArray->addGuiItem( Creatable::create("Primitives : ", "numPrimitives")); hudArray->addGuiItem( Creatable::create("Moving Prims : ", "numMovingPrimitives")); hudArray->addGuiItem( Creatable::create("Joints : ", "numJoints")); hudArray->addGuiItem( Creatable::create("Contacts : ", "numContacts")); hudArray->addGuiItem( Creatable::create("Tree : ", "maxTreeDepth")); hudArray->addGuiItem( Creatable::create("" , "----- Timing -----")); hudArray->addGuiItem( Creatable::create("Physics : ", "Physics")); hudArray->addGuiItem( Creatable::create("Mouse Move : ", "MouseMove")); hudArray->addGuiItem( Creatable::create("Render : ", "Render")); hudArray->addGuiItem( Creatable::create("Delta bw render : ", "Delta Between Renders")); hudArray->addGuiItem( Creatable::create("Total Render : ", "Total Render")); hudArray->addGuiItem( Creatable::create("Render Nom : ", "Render Nominal FPS")); hudArray->addGuiItem( Creatable::create("" , "----- Graphics ----")); hudArray->addGuiItem( Creatable::create("Graphic Mode : ", "Graphics Mode")); hudArray->addGuiItem( Creatable::create("Video Memory : ", "Video Memory")); hudArray->addGuiItem( Creatable::create("Anti-Aliasing : ", "Anti-Aliasing")); hudArray->addGuiItem( Creatable::create("Frame Id : ", "drawId")); hudArray->addGuiItem( Creatable::create("World Id : ", "worldId")); hudArray->addGuiItem( Creatable::create("" , "----- Throttles ----")); hudArray->addGuiItem( Creatable::create("EnviroSpeed % : ", "environmentSpeed")); hudArray->addGuiItem( Creatable::create("FRM : ", "FRM")); hudArray->addGuiItem( Creatable::create("FRM Target : ", "FRM Target")); hudArray->addGuiItem( Creatable::create("FRM Visible : ", "FRM Visible")); hudArray->addGuiItem( Creatable::create("FRM Quality : ", "FRM Quality")); hudArray->addGuiItem( Creatable::create("" , "----- Network ----")); hudArray->addGuiItem( Creatable::create("RequestQueue : ", "RequestQueueSize")); for (size_t i = 0; i < hudArray->numChildren(); ++i) { shared_ptr item = shared_from_dynamic_cast(hudArray->getChild(i)); RBXASSERT(item); item->setFontSize(12); item->setFontColor(G3D::Color3::purple()); item->setBorderColor(G3D::Color4::clear()); item->setGuiSize(Vector2(310, 22)); } hudArray->setVisible(false); return hudArray; } shared_ptr GuiBuilder::buildRenderStats() { Layout layout; layout.layoutStyle = Layout::VERTICAL; layout.xLocation = Rect::LEFT; layout.yLocation = Rect::BOTTOM; layout.offset.x = 50; layout.offset.y = 40; layout.backdropColor = GuiItem::translucentBackdrop(); shared_ptr hudArray = Creatable::create(layout); hudArray->setName("RenderStats"); hudArray->addGuiItem( Creatable::create("" , "----- Graphics ----")); hudArray->addGuiItem( Creatable::create("Physics : ", "Physics")); hudArray->addGuiItem( Creatable::create("Heartbeat : ", "Heartbeat")); hudArray->addGuiItem( Creatable::create("Network send : ", "Network Send")); hudArray->addGuiItem( Creatable::create("Network receive : ", "Network Receive")); hudArray->addGuiItem( Creatable::create("Video Memory : ", "Video Memory")); hudArray->addGuiItem( Creatable::create("Resolution: ", "RenderStatsResolution")); hudArray->addGuiItem( Creatable::create("" , "----- Performance -----")); hudArray->addGuiItem( Creatable::create("FRM Config: ", "RenderStatsFRMConfig")); hudArray->addGuiItem( Creatable::create("FRM Blocks: ", "RenderStatsFRMBlocks")); hudArray->addGuiItem( Creatable::create("FRM Adjust: ", "RenderStatsFRMAdjust")); hudArray->addGuiItem( Creatable::create("FRM Target Time: ", "RenderStatsFRMTargetTime")); hudArray->addGuiItem( Creatable::create("FRM Distance: ", "RenderStatsFRMDistance")); hudArray->addGuiItem( Creatable::create("Framerate Variance: ", "FRM Variance")); hudArray->addGuiItem( Creatable::create("" , "----- Timing -----")); hudArray->addGuiItem( Creatable::create("Scheduler Render : ", "Render")); hudArray->addGuiItem( Creatable::create("CPU: ", "RenderStatsTimeTotal")); hudArray->addGuiItem( Creatable::create("GPU: ", "RenderStatsGPU")); hudArray->addGuiItem( Creatable::create("Delta: ", "RenderStatsDelta")); hudArray->addGuiItem( Creatable::create("Draw (total): ", "RenderStatsPassTotal")); hudArray->addGuiItem( Creatable::create("Draw (scene): ", "RenderStatsPassScene")); hudArray->addGuiItem( Creatable::create("Draw (shadow): ", "RenderStatsPassShadow")); hudArray->addGuiItem( Creatable::create("Draw (UI): ", "RenderStatsPassUI")); hudArray->addGuiItem( Creatable::create("Draw (3D Adorns): ", "RenderStatsPass3dAdorns")); hudArray->addGuiItem( Creatable::create("Light grid: ", "RenderStatsLightGrid")); hudArray->addGuiItem( Creatable::create("Geometry Gen: ", "RenderStatsGeometryGen")); hudArray->addGuiItem( Creatable::create("Clusters: ", "RenderStatsClusters")); hudArray->addGuiItem( Creatable::create("Textures: ", "RenderStatsTM")); hudArray->addGuiItem( Creatable::create("TC: ", "RenderStatsTC")); for (size_t i = 0; i < hudArray->numChildren(); ++i) { shared_ptr item = shared_from_dynamic_cast(hudArray->getChild(i)); RBXASSERT(item); item->setFontSize(12); item->setFontColor(G3D::Color3::purple()); item->setBorderColor(G3D::Color4::clear()); item->setGuiSize(Vector2(440, 22)); } hudArray->setVisible(false); return hudArray; } shared_ptr GuiBuilder::buildNetworkStats() { Layout layout; layout.layoutStyle = Layout::VERTICAL; layout.xLocation = Rect::LEFT; layout.yLocation = Rect::BOTTOM; layout.offset.x = 50; layout.offset.y = 40; layout.backdropColor = GuiItem::translucentBackdrop(); shared_ptr hudArray = Creatable::create(layout); hudArray->setName("NetworkStats"); hudArray->addGuiItem( Creatable::create("" , "----- HTTP ----")); hudArray->addGuiItem( Creatable::create("Avg Time In Queue: " , "HttpTimeInQueue")); hudArray->addGuiItem( Creatable::create("Avg Process Time: " , "HttpProcessTime")); hudArray->addGuiItem( Creatable::create("Request Queue Size: " , "RequestQueueSize")); hudArray->addGuiItem( Creatable::create("# slow requests: " , "HttpSlowReq")); hudArray->addGuiItem( Creatable::create("" , "----- Replicator ----")); hudArray->addGuiItem( Creatable::create("" , "General (MTU Size, Ping) :")); hudArray->addGuiItem( Creatable::create(" " , "GeneralStats")); hudArray->addGuiItem( Creatable::create("" , "----- Incoming ----")); hudArray->addGuiItem( Creatable::create("" , "Overall (KB/s, Pkt/s, Queue) :")); hudArray->addGuiItem( Creatable::create(" " , "IncomingStats")); hudArray->addGuiItem( Creatable::create("" , "In Data (KB/s, Pkt/s, Avg Size) :")); hudArray->addGuiItem( Creatable::create(" " , "InData")); hudArray->addGuiItem( Creatable::create("" , "In Physics (KB/s, Pkt/s, Avg Size, Avg Lag) :")); hudArray->addGuiItem( Creatable::create(" " , "InPhysics")); hudArray->addGuiItem( Creatable::create("" , "In Touches (KB/s, Pkt/s, Avg Size) :")); hudArray->addGuiItem( Creatable::create(" " , "InTouches")); hudArray->addGuiItem( Creatable::create("" , "In Clusters (KB/s, Pkt/s, Avg Size) :")); hudArray->addGuiItem( Creatable::create(" " , "InClusters")); hudArray->addGuiItem( Creatable::create("" , "----- Outgoing ----")); hudArray->addGuiItem( Creatable::create( "Overall (KB/s) :" , "OutgoingStats")); hudArray->addGuiItem( Creatable::create("" , "Out Data (KB/s, Pkt/s, Avg Size, Throttle) :")); hudArray->addGuiItem( Creatable::create(" " , "OutData")); hudArray->addGuiItem( Creatable::create("" , "Out Physics (KB/s, Pkt/s, Avg Size, Throttle) :")); hudArray->addGuiItem( Creatable::create(" " , "OutPhysics")); hudArray->addGuiItem( Creatable::create("" , "Out Touches (KB/s, Pkt/s, Avg Size, #Waiting) :")); hudArray->addGuiItem( Creatable::create(" " , "OutTouches")); hudArray->addGuiItem( Creatable::create("" , "Out Clusters (KB/s, Pkt/s, Avg Size) :")); hudArray->addGuiItem( Creatable::create(" " , "OutClusters")); for (size_t i = 0; i < hudArray->numChildren(); ++i) { shared_ptr item = shared_from_dynamic_cast(hudArray->getChild(i)); RBXASSERT(item); item->setFontSize(12); item->setFontColor(G3D::Color3::purple()); item->setBorderColor(G3D::Color4::clear()); item->setGuiSize(Vector2(420, 22)); } hudArray->setVisible(false); return hudArray; } shared_ptr GuiBuilder::buildFPS() { Layout layout; layout.layoutStyle = Layout::VERTICAL; layout.xLocation = Rect::LEFT; layout.yLocation = Rect::TOP; layout.offset.x = 50; layout.offset.y = 40; layout.backdropColor = GuiItem::translucentBackdrop(); shared_ptr hudArray = Creatable::create(layout); hudArray->setName("FPS"); hudArray->addGuiItem( Creatable::create("FPS : ", "Render")); for (size_t i = 0; i < hudArray->numChildren(); ++i) { shared_ptr item = shared_from_dynamic_cast(hudArray->getChild(i)); RBXASSERT(item); item->setFontSize(24); item->setFontColor(G3D::Color3::purple()); item->setBorderColor(G3D::Color4::clear()); item->setGuiSize(Vector2(400, 22)); } hudArray->setVisible(FFlag::DebugDisplayFPS); return hudArray; } shared_ptr GuiBuilder::buildNetworkStats2(bool init) { if (init) { networkStatsCounter = NETWORKSTATS_INVALID; } Layout layout; layout.layoutStyle = Layout::VERTICAL; layout.xLocation = Rect::RIGHT; layout.yLocation = Rect::BOTTOM; layout.offset.x = 50; layout.offset.y = 40; layout.backdropColor = GuiItem::translucentBackdrop(); shared_ptr hudArray = Creatable::create(layout); hudArray->setName("NetworkStats2"); switch (networkStatsCounter) { case NETWORKSTATS_RAKNET: hudArray->addGuiItem( Creatable::create("" , "----- Raknet ----")); hudArray->addGuiItem( Creatable::create("ping : ", "RakNetPing")); hudArray->addGuiItem( Creatable::create("msgTotalBytesPushed/s : ", "messageDataBytesSentPerSec")); hudArray->addGuiItem( Creatable::create("msgTotalBytesSent/s : ", "messageTotalBytesSentPerSec")); hudArray->addGuiItem( Creatable::create("msgDataBytesResent/s : ", "messageDataBytesResentPerSec")); hudArray->addGuiItem( Creatable::create("msgBytesRecv/s : ", "messagesBytesReceivedPerSec")); hudArray->addGuiItem( Creatable::create("msgBytesRecvAndIgnored/s : ", "messagesBytesReceivedAndIgnoredPerSec")); hudArray->addGuiItem( Creatable::create("bytesSent/s : ", "bytesSentPerSec")); hudArray->addGuiItem( Creatable::create("bytesReceived/s : ", "bytesReceivedPerSec")); hudArray->addGuiItem( Creatable::create("outBandwidthLimitBytes/s : ", "outgoingBandwidthLimitBytesPerSecond")); hudArray->addGuiItem( Creatable::create("limitedByOutBandwidthLimit : ", "isLimitedByOutgoingBandwidthLimit")); hudArray->addGuiItem( Creatable::create("congestionCtrlLimitBytes/s : ", "congestionControlLimitBytesPerSecond")); hudArray->addGuiItem( Creatable::create("limitedByCongestionControl : ", "isLimitedByCongestionControl")); hudArray->addGuiItem( Creatable::create("messagesInResendQueue : ", "messagesInResendQueue")); hudArray->addGuiItem( Creatable::create("bytesInResendQueue : ", "bytesInResendQueue")); hudArray->addGuiItem( Creatable::create("packetlossLastSecond : ", "packetlossLastSecond")); break; case NETWORKSTATS_PHYSICS: hudArray->addGuiItem( Creatable::create("" , "----- In Physics ----")); hudArray->addGuiItem( Creatable::create("" , "Class) Type (KB/s, Avg Size, Count/s)")); hudArray->addGuiItem( Creatable::create("" , "")); hudArray->addGuiItem( Creatable::create("" , "")); hudArray->addGuiItem( Creatable::create("" , "InPhysicsDetails")); hudArray->addGuiItem( Creatable::create("" , "")); hudArray->addGuiItem( Creatable::create("" , "")); hudArray->addGuiItem( Creatable::create("" , "")); hudArray->addGuiItem( Creatable::create("" , "----- Out Physics ----")); hudArray->addGuiItem( Creatable::create("" , "Class) Type (KB/s, Avg Size, Count/s)")); hudArray->addGuiItem( Creatable::create("" , "")); hudArray->addGuiItem( Creatable::create("" , "")); hudArray->addGuiItem( Creatable::create("" , "OutPhysicsDetails")); hudArray->addGuiItem( Creatable::create("" , "")); hudArray->addGuiItem( Creatable::create("" , "")); hudArray->addGuiItem( Creatable::create("" , "")); hudArray->addGuiItem( Creatable::create("", "(PBM Enabled)")); break; case NETWORKSTATS_DATATYPE: hudArray->addGuiItem( Creatable::create("" , "----- In Data ----")); hudArray->addGuiItem( Creatable::create("" , "Details (KB/s, Avg Size, Count/s)")); hudArray->addGuiItem( Creatable::create("" , "")); hudArray->addGuiItem( Creatable::create("" , "")); hudArray->addGuiItem( Creatable::create("" , "")); hudArray->addGuiItem( Creatable::create("" , "")); hudArray->addGuiItem( Creatable::create("" , "InDataDetails")); hudArray->addGuiItem( Creatable::create("" , "")); hudArray->addGuiItem( Creatable::create("" , "")); hudArray->addGuiItem( Creatable::create("" , "")); hudArray->addGuiItem( Creatable::create("" , "")); hudArray->addGuiItem( Creatable::create("" , "")); hudArray->addGuiItem( Creatable::create("" , "----- Out Data ----")); hudArray->addGuiItem( Creatable::create("" , "Details (KB/s, Avg Size, Count/s)")); hudArray->addGuiItem( Creatable::create("" , "")); hudArray->addGuiItem( Creatable::create("" , "")); hudArray->addGuiItem( Creatable::create("" , "")); hudArray->addGuiItem( Creatable::create("" , "")); hudArray->addGuiItem( Creatable::create("" , "OutDataDetails")); hudArray->addGuiItem( Creatable::create("" , "")); hudArray->addGuiItem( Creatable::create("" , "")); hudArray->addGuiItem( Creatable::create("" , "")); hudArray->addGuiItem( Creatable::create("" , "")); hudArray->addGuiItem( Creatable::create("" , "")); break; case NETWORKSTATS_STREAMING: hudArray->addGuiItem( Creatable::create("" , "----- Streaming ----")); hudArray->addGuiItem( Creatable::create("Free Memory:" , "FreeMemory")); hudArray->addGuiItem( Creatable::create("Memory Level:" , "MemoryLevel")); hudArray->addGuiItem( Creatable::create("" , "")); hudArray->addGuiItem( Creatable::create("" , "")); hudArray->addGuiItem( Creatable::create("" , "ReceivedStreamData")); hudArray->addGuiItem( Creatable::create("" , "")); hudArray->addGuiItem( Creatable::create("" , "")); hudArray->addGuiItem( Creatable::create("" , "")); hudArray->addGuiItem( Creatable::create("" , "")); hudArray->addGuiItem( Creatable::create("" , "")); default: break; } for (size_t i = 0; i < hudArray->numChildren(); ++i) { shared_ptr item = shared_from_dynamic_cast(hudArray->getChild(i)); RBXASSERT(item); item->setFontSize(12); item->setFontColor(G3D::Color3::purple()); item->setBorderColor(G3D::Color4::clear()); item->setGuiSize(Vector2(280, 22)); } if (init) { hudArray->setVisible(false); } return hudArray; } shared_ptr GuiBuilder::buildStatsHud2() { Layout layout; layout.layoutStyle = Layout::VERTICAL; layout.xLocation = Rect::RIGHT; layout.yLocation = Rect::BOTTOM; layout.offset.x = 50; layout.offset.y = 40; layout.backdropColor = GuiItem::translucentBackdrop(); shared_ptr hudArray = Creatable::create(layout); hudArray->setName("StatsHud2"); hudArray->addGuiItem( Creatable::create("" , "----- Contacts ----")); hudArray->addGuiItem( Creatable::create("CtctStageCtcts: ", "numContactsInCollisionStage")); hudArray->addGuiItem( Creatable::create("SteppingCtcts : ", "numSteppingContacts")); hudArray->addGuiItem( Creatable::create("TouchingCtcts : ", "numTouchingContacts")); hudArray->addGuiItem( Creatable::create("% Pair Hit : ", "contactPairHitRatio")); hudArray->addGuiItem( Creatable::create("% Feature Hit : ", "contactFeatureHitRatio")); hudArray->addGuiItem( Creatable::create("# link(p) : ", "numLinkCalls")); hudArray->addGuiItem( Creatable::create("sH Nodes Out : ", "numHashNodes")); hudArray->addGuiItem( Creatable::create("sH Max Bucket : ", "maxBucketSize")); hudArray->addGuiItem( Creatable::create("" , "----- Kernel ----")); hudArray->addGuiItem( Creatable::create("Solver Iteratn: ", "solverIterations")); // This is for fun / deception - we don't use matrices! hudArray->addGuiItem( Creatable::create("Matrix Size : ", "matrixSize")); // This is for fun / deception - we don't use matrices! hudArray->addGuiItem( Creatable::create("Bodies : ", "numBodies")); hudArray->addGuiItem( Creatable::create("MaxBodies : ", "maxBodies")); hudArray->addGuiItem( Creatable::create("Leaves : ", "numLeafBodies")); hudArray->addGuiItem( Creatable::create("Constraints : ", "numConstraints")); hudArray->addGuiItem( Creatable::create("Points : ", "numPoints")); hudArray->addGuiItem( Creatable::create("% Active CC's : ", "percentConnectorsActive")); hudArray->addGuiItem( Creatable::create("Energy B : ", "energyBody")); hudArray->addGuiItem( Creatable::create("Energy C : ", "energyConnector")); hudArray->addGuiItem( Creatable::create("Energy T : ", "energyTotal")); for (size_t i = 0; i < hudArray->numChildren(); ++i) { shared_ptr item = shared_from_dynamic_cast(hudArray->getChild(i)); RBXASSERT(item); item->setFontSize(12); item->setFontColor(G3D::Color3::purple()); item->setBorderColor(G3D::Color4::clear()); item->setGuiSize(Vector2(260, 22)); } hudArray->setVisible(false); return hudArray; } shared_ptr GuiBuilder::buildPhysicsStats() { Layout layout; layout.layoutStyle = Layout::VERTICAL; layout.xLocation = Rect::LEFT; layout.yLocation = Rect::TOP; layout.offset.x = 50; layout.offset.y = 40; layout.backdropColor = GuiItem::translucentBackdrop(); shared_ptr hudArray = Creatable::create(layout); hudArray->setName("PhysicsStats"); hudArray->addGuiItem( Creatable::create("" , "----- FPS ----")); hudArray->addGuiItem( Creatable::create("Physics : ", "Physics")); hudArray->addGuiItem( Creatable::create("PhysicsReal : ", "PhysicsReal")); hudArray->addGuiItem( Creatable::create("Render : ", "Render")); hudArray->addGuiItem( Creatable::create("Heartbeat : ", "Heartbeat")); hudArray->addGuiItem( Creatable::create("Network send : ", "Network Send")); hudArray->addGuiItem( Creatable::create("Network recv : ", "Network Receive")); hudArray->addGuiItem( Creatable::create("Rx data pkts : ", "Received Data Packets")); hudArray->addGuiItem( Creatable::create("Rx phys pkts : ", "Received Physics Packets")); hudArray->addGuiItem( Creatable::create("" , "----- World ----")); hudArray->addGuiItem( Creatable::create("Player Radius : ", "Player Radius")); hudArray->addGuiItem( Creatable::create("Parts : ", "numPrimitives")); hudArray->addGuiItem( Creatable::create("Moving parts : ", "numMovingPrimitives")); hudArray->addGuiItem( Creatable::create("Joints : ", "numJoints")); hudArray->addGuiItem( Creatable::create("Contacts : ", "numContactsAll")); hudArray->addGuiItem( Creatable::create("% Pair Hit : ", "contactPairHitRatio")); hudArray->addGuiItem( Creatable::create("% Feature Hit : ", "contactFeatureHitRatio")); hudArray->addGuiItem( Creatable::create("sH Nodes : ", "numHashNodes")); hudArray->addGuiItem( Creatable::create("" , "----- Kernel ----")); hudArray->addGuiItem( Creatable::create("PGS Solver On : ", "pGSSolverActive")); hudArray->addGuiItem( Creatable::create("Bodies : ", "numBodiesAll")); hudArray->addGuiItem( Creatable::create("Connectors : ", "numConnectorsAll")); hudArray->addGuiItem( Creatable::create("Energy T : ", "energyTotal")); hudArray->addGuiItem( Creatable::create("Iterations : ", "numIterations")); for (size_t i = 0; i < hudArray->numChildren(); ++i) { shared_ptr item = shared_from_dynamic_cast(hudArray->getChild(i)); RBXASSERT(item); item->setFontSize(12); item->setFontColor(G3D::Color3::purple()); item->setBorderColor(G3D::Color4::clear()); item->setGuiSize(Vector2(440, 22)); } hudArray->setVisible(false); return hudArray; } void GuiBuilder::updatePerformanceBasedStat(shared_ptr item, float value, float greenCutoff, float yellowCutoff, float orangeCutoff, bool isBottleneck) { if (value >= greenCutoff) { item->setFontColor(G3D::Color3::green()); } else if (value >= yellowCutoff) { item->setFontColor(G3D::Color3::yellow()); } else if (value >= orangeCutoff) { item->setFontColor(G3D::Color3::orange()); } else { item->setFontColor(G3D::Color3::red()); } if (!isBottleneck) { item->setFontSize(12); } else { item->setFontSize(18); } item->setBorderColor(G3D::Color4::clear()); item->setGuiSize(Vector2(440, 22)); } // this function is called while we have a read lock on the DataModel but modifies it // Things that need to be addressed to stop this: // modifying the colour property of the text // modifying the font size property of the text // modifying the visibility of the text void GuiBuilder::updateSummaryStats(RBX::TopMenuBar* hudArray) { // parameters for adjusting the displayed stats const float startSlowRendering = 15.f; const float endSlowRendering = 20.f; const float startSlowPhysics = 15.f; const float endSlowPhysics = 20.f; const float startSlowNetworkCPU = 25.f; const float endSlowNetworkCPU = 20.f; const float startSlowNetworkPhysics = 15.f; const float endSlowNetworkPhysics = 17.f; const float totalGreenFPS = 28.f; const float totalYellowFPS = 20.f; const float totalOrangeFPS = 10.f; const float physicsGreenFPS = 28.f; const float physicsYellowFPS = 20.f; const float physicsOrangeFPS = 10.f; const float renderGreenFPS = 28.f; const float renderYellowFPS = 20.f; const float renderOrangeFPS = 10.f; const float networkGreenCPU = 15.f; const float networkYellowCPU = 20.f; const float networkOrangeCPU = 25.f; const float networkGreenPhysicsPacketsReceived = 19.f; const float networkYellowPhysicsPacketsReceived = 16.f; const float networkOrangePhysicsPacketsReceived = 12.f; enum { DefaultStat_Total, DefaultStat_Physics, DefaultStat_Render, DefaultStat_Network, DefaultStat_Count, RenderStat_Start = DefaultStat_Count, RenderStat_End = RenderStat_Start + 13, PhysicsStat_Start = RenderStat_End, PhysicsStat_End = PhysicsStat_Start + 8, NetworkStat_Start = PhysicsStat_End, NetworkStat_End = NetworkStat_Start + 11 }; RBXASSERT(NetworkStat_End == hudArray->numChildren()); float totalFps = dataModel->getMetricValue("Effective FPS"); float renderFps = dataModel->getMetricValue("Render FPS"); float physicsFps = dataModel->getMetricValue("Physics FPS"); float networkReceivePercentage = dataModel->getMetricValue("Network Receive CPU"); float physicsPacketsReceived = dataModel->getMetricValue("Received Physics Packets"); static bool slowRendering = false; static bool slowPhysics = false; static bool slowNetworking = false; bool isNetworkGame; bool isRenderingBottleneck = false, isPhysicsBottleneck = false, isNetworkingBottleneck = false; if (totalFps < 30.f) { float frameTime = dataModel->getMetricValue("Frame Time"); float renderTime = dataModel->getMetricValue("Render Time"); float physicsTime = dataModel->getMetricValue("Physics Time"); float networkTime = dataModel->getMetricValue("Network Receive Time"); if (renderTime > physicsTime && renderTime > networkTime && renderTime > frameTime * 0.4f) { isRenderingBottleneck = true; } else if (physicsTime > renderTime && physicsTime > networkTime && physicsTime > frameTime * 0.4f) { isPhysicsBottleneck = true; } else { // if networking is taking longer than rendering or physics assume it is the bottleneck if ((networkTime > physicsTime && networkTime > renderTime) || networkReceivePercentage > 0.5f) { isNetworkingBottleneck = true; } } } slowRendering = renderFps < startSlowRendering || (slowRendering && renderFps < endSlowRendering); slowPhysics = physicsFps < startSlowPhysics || (slowPhysics && physicsFps < endSlowPhysics); // We ignore networking unless we're playing a networked game // networking checks to see if we spend too much time processing incoming packets or // receive physics packets slower than expected isNetworkGame = networkReceivePercentage > 0.f || physicsPacketsReceived > 0.f; slowNetworking = isNetworkGame && (networkReceivePercentage > startSlowNetworkCPU || physicsPacketsReceived < startSlowNetworkPhysics || (slowNetworking && (networkReceivePercentage > endSlowNetworkCPU || physicsPacketsReceived < endSlowNetworkPhysics))); updatePerformanceBasedStat(shared_from_dynamic_cast(hudArray->getChild(DefaultStat_Total)), totalFps, totalGreenFPS, totalYellowFPS, totalOrangeFPS, false); updatePerformanceBasedStat(shared_from_dynamic_cast(hudArray->getChild(DefaultStat_Physics)), physicsFps, physicsGreenFPS, physicsYellowFPS, physicsOrangeFPS, isPhysicsBottleneck); updatePerformanceBasedStat(shared_from_dynamic_cast(hudArray->getChild(DefaultStat_Render)), renderFps, renderGreenFPS, renderYellowFPS, renderOrangeFPS, isRenderingBottleneck); shared_ptr item = shared_from_dynamic_cast(hudArray->getChild(DefaultStat_Network)); if ((networkReceivePercentage < networkGreenCPU && physicsPacketsReceived >= networkGreenPhysicsPacketsReceived) || !isNetworkGame) { item->setFontColor(G3D::Color3::green()); } else if (networkReceivePercentage < networkYellowCPU && physicsPacketsReceived >= networkYellowPhysicsPacketsReceived) { item->setFontColor(G3D::Color3::yellow()); } else if (networkReceivePercentage < networkOrangeCPU && physicsPacketsReceived >= networkOrangePhysicsPacketsReceived) { item->setFontColor(G3D::Color3::orange()); } else { item->setFontColor(G3D::Color3::red()); } if (!isNetworkingBottleneck) { item->setFontSize(12); } else { item->setFontSize(18); } item->setBorderColor(G3D::Color4::clear()); item->setGuiSize(Vector2(440, 22)); // hide all of the bottleneck specific stats for (size_t i = DefaultStat_Count; i < hudArray->numChildren(); ++i) { shared_ptr item = shared_from_dynamic_cast(hudArray->getChild(i)); RBXASSERT(item); item->setVisible(false); } if (slowRendering) { for (size_t i = RenderStat_Start; i < RenderStat_End; ++i) { shared_ptr item = shared_from_dynamic_cast(hudArray->getChild(i)); RBXASSERT(item); item->setVisible(true); } } if (slowPhysics) { for (size_t i = PhysicsStat_Start; i < PhysicsStat_End; ++i) { shared_ptr item = shared_from_dynamic_cast(hudArray->getChild(i)); RBXASSERT(item); item->setVisible(true); } } if (slowNetworking) { for (size_t i = NetworkStat_Start; i < NetworkStat_End; ++i) { shared_ptr item = shared_from_dynamic_cast(hudArray->getChild(i)); RBXASSERT(item); item->setVisible(true); } } } shared_ptr GuiBuilder::buildSummaryStats() { Layout layout; layout.layoutStyle = Layout::VERTICAL; layout.xLocation = Rect::LEFT; layout.yLocation = Rect::TOP; layout.offset.x = 50; layout.offset.y = 40; layout.backdropColor = GuiItem::translucentBackdrop(); shared_ptr hudArray = Creatable::create(layout); hudArray->setName("SummaryStats"); hudArray->addGuiItem(Creatable::create("FPS : ", "Effective FPS")); hudArray->addGuiItem(Creatable::create("Physics : ", "Physics")); hudArray->addGuiItem(Creatable::create("Render : ", "Render")); hudArray->addGuiItem( Creatable::create("Network receive : ", "Network Receive")); hudArray->addGuiItem( Creatable::create("", "----- Rendering -----")); hudArray->addGuiItem( Creatable::create("Video Memory : ", "Video Memory")); hudArray->addGuiItem( Creatable::create("FRM Auto Quality: ", "Auto Quality")); hudArray->addGuiItem( Creatable::create("FRM Quality : ", "FRM Quality")); hudArray->addGuiItem( Creatable::create("FRM Visible : ", "FRM Visible")); hudArray->addGuiItem( Creatable::create("Particles : ", "Particles")); hudArray->addGuiItem( Creatable::create("Scheduler Render : ", "Render")); hudArray->addGuiItem( Creatable::create("Present time : ", "Present Time")); hudArray->addGuiItem( Creatable::create("Draw (total): ", "RenderStatsPassTotal")); hudArray->addGuiItem( Creatable::create("Draw (scene): ", "RenderStatsPassScene")); hudArray->addGuiItem( Creatable::create("Draw (shadow): ", "RenderStatsPassShadow")); hudArray->addGuiItem( Creatable::create("Draw (UI): ", "RenderStatsPassUI")); hudArray->addGuiItem( Creatable::create("Draw (3D Adorns): ", "RenderStatsPass3dAdorns")); hudArray->addGuiItem( Creatable::create("", "----- Physics -----")); hudArray->addGuiItem( Creatable::create("Parts : ", "numPrimitives")); hudArray->addGuiItem( Creatable::create("Moving parts : ", "numMovingPrimitives")); hudArray->addGuiItem( Creatable::create("Joints : ", "numJoints")); hudArray->addGuiItem( Creatable::create("Contacts : ", "numContacts")); hudArray->addGuiItem( Creatable::create("EnviroSpeed % : ", "environmentSpeed")); hudArray->addGuiItem( Creatable::create("Energy T : ", "energyTotal")); hudArray->addGuiItem( Creatable::create("TouchingCtcts : ", "numTouchingContacts")); hudArray->addGuiItem( Creatable::create("", "----- Network -----")); hudArray->addGuiItem( Creatable::create("Data Ping : ", "Data Ping")); hudArray->addGuiItem( Creatable::create("Send KBytesPerSec : ", "Send kBps")); hudArray->addGuiItem( Creatable::create("Receive KBytesPerSec : ", "Receive kBps")); hudArray->addGuiItem( Creatable::create("Incoming Packet Queue : ", "Packet Queue")); hudArray->addGuiItem( Creatable::create("Received Data Packets : ", "Received Data Packets")); hudArray->addGuiItem( Creatable::create("Received Physics Packets : ", "Received Physics Packets")); hudArray->addGuiItem( Creatable::create("Received Cluster Packets : ", "Received Cluster Packets")); hudArray->addGuiItem( Creatable::create("messagesInResendQueue : ", "messagesInResendQueue")); hudArray->addGuiItem( Creatable::create("Sent Data Packets : ", "Sent Data Packets")); hudArray->addGuiItem( Creatable::create("Sent Physics Packets : ", "Sent Physics Packets")); for (size_t i = 0; i < hudArray->numChildren(); ++i) { shared_ptr item = shared_from_dynamic_cast(hudArray->getChild(i)); RBXASSERT(item); item->setFontSize(12); item->setFontColor(G3D::Color3::purple()); item->setBorderColor(G3D::Color4::clear()); item->setGuiSize(Vector2(440, 22)); } hudArray->setVisible(false); return hudArray; } shared_ptr GuiBuilder::buildCustomStats() { Layout layout; layout.layoutStyle = Layout::VERTICAL; layout.xLocation = Rect::LEFT; layout.yLocation = Rect::TOP; layout.offset.x = 50; layout.offset.y = 40; layout.backdropColor = GuiItem::translucentBackdrop(); shared_ptr hudArray = Creatable::create(layout); hudArray->setName("CustomStats"); hudArray->addGuiItem( Creatable::create("", "----- Custom Stats -----")); // load custom stats JSON file CustomStatsGuiJSON json(this); std::string localSettingsData; std::ifstream localConfigFile(GetCustomStatsFilename().native().c_str()); if(localConfigFile.is_open()) { std::stringstream localConfigBuffer; localConfigBuffer << localConfigFile.rdbuf(); localSettingsData = localConfigBuffer.str(); if(localSettingsData.length() > 0) { json.ReadFromStream(localSettingsData.c_str()); } } for (CustomStatsContainer::iterator itr = customStatsCont.begin(); itr != customStatsCont.end(); ++itr) { hudArray->addGuiItem( Creatable::create(itr->first + " : ", itr->second.stat)); } for (size_t i = 0; i < hudArray->numChildren(); ++i) { shared_ptr item = shared_from_dynamic_cast(hudArray->getChild(i)); RBXASSERT(item); item->setFontSize(12); item->setFontColor(G3D::Color3::purple()); item->setBorderColor(G3D::Color4::clear()); item->setGuiSize(Vector2(440, 22)); } hudArray->setVisible(false); return hudArray; } shared_ptr GuiBuilder::buildPhysicsStats2() { Layout layout; layout.layoutStyle = Layout::VERTICAL; layout.xLocation = Rect::RIGHT; layout.yLocation = Rect::BOTTOM; layout.offset.x = 5; layout.offset.y = 220; layout.backdropColor = GuiItem::translucentBackdrop(); shared_ptr hudArray = Creatable::create(layout); hudArray->setName("PhysicsStats2"); hudArray->addGuiItem( Creatable::create("" , "----- Physics Profiling ----")); hudArray->addGuiItem( Creatable::create("" , "World Step -")); hudArray->addGuiItem( Creatable::create(" Break Time: ", "Break Time")); hudArray->addGuiItem( Creatable::create(" Assembler Time: ", "Assembler Time")); hudArray->addGuiItem( Creatable::create(" Filter Time: ", "Filter Time")); hudArray->addGuiItem( Creatable::create(" UI Step: ", "UI Step")); hudArray->addGuiItem( Creatable::create(" Broadphase: ", "Broadphase")); hudArray->addGuiItem( Creatable::create(" Collision: ", "Collision")); hudArray->addGuiItem( Creatable::create(" Joint Sleep: ", "Joint Sleep")); hudArray->addGuiItem( Creatable::create(" Wake: ", "Wake")); hudArray->addGuiItem( Creatable::create(" Sleep: ", "Sleep")); hudArray->addGuiItem( Creatable::create(" Joint Update: ", "Joint Update")); hudArray->addGuiItem( Creatable::create(" Bodies: ", "Kernel Bodies")); hudArray->addGuiItem( Creatable::create(" Connectors: ", "Kernel Connectors")); for (size_t i = 0; i < hudArray->numChildren(); ++i) { shared_ptr item = shared_from_dynamic_cast(hudArray->getChild(i)); RBXASSERT(item); item->setFontSize(12); item->setFontColor(G3D::Color3::purple()); item->setBorderColor(G3D::Color4::clear()); item->setGuiSize(Vector2(260, 22)); } hudArray->setVisible(false); return hudArray; } } // namespace