postEffectVis.cpp
Engine/source/postFx/postEffectVis.cpp
Public Variables
_PfxVisclear ("@brief Close all visualization windows.\n\n" "@tsexample\n" "PfxVis::clear();" "@endtsexample\n\n", "PfxVis", "void clear();")
_PfxVishide ("@brief Hide all visualization windows (they are not destroyed).\n\n" "@tsexample\n" "PfxVis::hide();" "@endtsexample\n\n", "PfxVis", "void hide();")
_PfxVisonWindowClosed ("@brief Callback when a visualization window is closed.\n\n" "@param ctrl Name of the GUI control being closed\n" "@tsexample\n" "PfxVis::onWindowClosed( VisWindow )\n" "@endtsexample\n\n", "PfxVis", "void onWindowClosed(GuiWindowCtrl *ctrl);")
_PfxVisopen ("@brief Open visualization windows for all input and target textures.\n\n" "@param effect Name of the PostEffect to open\n" "@param clear True to close all visualization windows before opening the effect\n\n" "@tsexample\n" "// Multiple PostEffects can be visualized at the same time\n" "PfxVis::open( PostEffect )\n" "@endtsexample\n\n", "PfxVis", "void open(PostEffect effect, bool clear);")
_PfxVisshow ("@brief Show all visualization windows.\n\n" "@tsexample\n" "PfxVis::show();" "@endtsexample\n\n", "PfxVis", "void show();")
Public Functions
ConsoleDoc("@class <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">PfxVis\n</a>" "@brief <a href="/coding/class/classsingleton/">Singleton</a> class that exposes ConsoleStaticFunctions <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> debug visualizing <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">PostEffects.\n\n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "// Script <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">interface...\n</a>" "PfxVis::open( <a href="/coding/class/classposteffect/">PostEffect</a> ) // Multiple PostEffects can be visualized at the same <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">time\n</a>" "PfxVis::clear() // Clear all visualizer <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">windows\n</a>" "PfxVis::hide() // Hide all windows (are not destroyed)\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "PfxVis::show()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GFX\n</a>" )
DefineEngineStaticMethod(PfxVis , clear , void , () , "@hide" )
DefineEngineStaticMethod(PfxVis , hide , void , () , "@hide" )
DefineEngineStaticMethod(PfxVis , onWindowClosed , void , (GuiWindowCtrl *ctrl) , "@hide" )
DefineEngineStaticMethod(PfxVis , open , void , (PostEffect *pfx, bool clear) , (false) , "( PostEffect, [bool clear = false] )" "@hide" )
DefineEngineStaticMethod(PfxVis , show , void , () , "@hide" )
Detailed Description
Public Variables
ConsoleDocFragment _PfxVisclear ("@brief Close all visualization windows.\n\n" "@tsexample\n" "PfxVis::clear();" "@endtsexample\n\n", "PfxVis", "void clear();")
ConsoleDocFragment _PfxVishide ("@brief Hide all visualization windows (they are not destroyed).\n\n" "@tsexample\n" "PfxVis::hide();" "@endtsexample\n\n", "PfxVis", "void hide();")
ConsoleDocFragment _PfxVisonWindowClosed ("@brief Callback when a visualization window is closed.\n\n" "@param ctrl Name of the GUI control being closed\n" "@tsexample\n" "PfxVis::onWindowClosed( VisWindow )\n" "@endtsexample\n\n", "PfxVis", "void onWindowClosed(GuiWindowCtrl *ctrl);")
ConsoleDocFragment _PfxVisopen ("@brief Open visualization windows for all input and target textures.\n\n" "@param effect Name of the PostEffect to open\n" "@param clear True to close all visualization windows before opening the effect\n\n" "@tsexample\n" "// Multiple PostEffects can be visualized at the same time\n" "PfxVis::open( PostEffect )\n" "@endtsexample\n\n", "PfxVis", "void open(PostEffect effect, bool clear);")
ConsoleDocFragment _PfxVisshow ("@brief Show all visualization windows.\n\n" "@tsexample\n" "PfxVis::show();" "@endtsexample\n\n", "PfxVis", "void show();")
MODULE_END
MODULE_INIT
MODULE_SHUTDOWN
Public Functions
ConsoleDoc("@class <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">PfxVis\n</a>" "@brief <a href="/coding/class/classsingleton/">Singleton</a> class that exposes ConsoleStaticFunctions <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> debug visualizing <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">PostEffects.\n\n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "// Script <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">interface...\n</a>" "PfxVis::open( <a href="/coding/class/classposteffect/">PostEffect</a> ) // Multiple PostEffects can be visualized at the same <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">time\n</a>" "PfxVis::clear() // Clear all visualizer <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">windows\n</a>" "PfxVis::hide() // Hide all windows (are not destroyed)\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "PfxVis::show()\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">GFX\n</a>" )
DefineEngineStaticMethod(PfxVis , clear , void , () , "@hide" )
DefineEngineStaticMethod(PfxVis , hide , void , () , "@hide" )
DefineEngineStaticMethod(PfxVis , onWindowClosed , void , (GuiWindowCtrl *ctrl) , "@hide" )
DefineEngineStaticMethod(PfxVis , open , void , (PostEffect *pfx, bool clear) , (false) , "( PostEffect, [bool clear = false] )" "@hide" )
DefineEngineStaticMethod(PfxVis , show , void , () , "@hide" )
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#include "platform/platform.h" 25#include "postFx/postEffectVis.h" 26#include "gui/containers/guiWindowCtrl.h" 27#include "gui/controls/guiBitmapCtrl.h" 28#include "gui/core/guiCanvas.h" 29#include "postFx/postEffectManager.h" 30#include "core/module.h" 31 32ConsoleDoc( 33 "@class PfxVis\n" 34 "@brief Singleton class that exposes ConsoleStaticFunctions for debug visualizing PostEffects.\n\n" 35 "@tsexample\n" 36 "// Script interface...\n" 37 "PfxVis::open( PostEffect ) // Multiple PostEffects can be visualized at the same time\n" 38 "PfxVis::clear() // Clear all visualizer windows\n" 39 "PfxVis::hide() // Hide all windows (are not destroyed)\n" 40 "PfxVis::show()\n" 41 "@endtsexample\n\n" 42 "@ingroup GFX\n" 43); 44 45IMPLEMENT_STATIC_CLASS(PfxVis, , "") 46 47MODULE_BEGIN( PostEffectVis ) 48 49 MODULE_INIT 50 { 51 ManagedSingleton< PostEffectVis >::createSingleton(); 52 } 53 54 MODULE_SHUTDOWN 55 { 56 ManagedSingleton< PostEffectVis >::deleteSingleton(); 57 } 58 59MODULE_END; 60 61 62PostEffectVis::PostEffectVis() 63 : mContent( NULL ) 64{ 65} 66 67PostEffectVis::~PostEffectVis() 68{ 69} 70 71void PostEffectVis::open( PostEffect *pfx ) 72{ 73 GuiControl *content = _getContentControl(); 74 75 // If we already have this PostEffect added 76 // remove it first so we can recreate its controls. 77 VisVector::iterator itr = mWindows.begin(); 78 for ( ; itr != mWindows.end(); itr++ ) 79 { 80 if ( itr->pfx == pfx ) 81 { 82 for ( U32 i = 0; i < TexCount; i++ ) 83 { 84 // Deleting the GuiWindowCtrl will automatically also delete 85 // any child controls we have allocated. 86 if ( itr->window[i] ) 87 itr->window[i]->deleteObject(); 88 } 89 90 mWindows.erase_fast( itr ); 91 break; 92 } 93 } 94 95 // Allocate VisWindow struct. 96 mWindows.increment(); 97 VisWindow &window = mWindows.last(); 98 window.pfx = pfx; 99 100 for ( U32 i = 0; i < TexCount; i++ ) 101 { 102 // Only allocate window/bitmaps for input textures that are actually used. 103 if ( i > Target ) 104 { 105 if ( pfx->mTexFilename[i-1].isEmpty() ) 106 { 107 window.window[i] = NULL; 108 window.bmp[i] = NULL; 109 continue; 110 } 111 } 112 113 // Allocate GuiWindowCtrl 114 GuiWindowCtrl *winCtrl = new GuiWindowCtrl(); 115 winCtrl->setPosition( Point2I( 50, 50 ) + Point2I( 15, 15 ) * i ); 116 winCtrl->setExtent( 347, 209 ); 117 winCtrl->setMinExtent( Point2I( 150, 100 ) ); 118 winCtrl->setMobility( true, true, true, true, false, false ); 119 winCtrl->setCanResize( true, true ); 120 winCtrl->setDataField( StringTable->insert( "closeCommand" ), NULL, "PfxVis::onWindowClosed( $ThisControl );" ); 121 winCtrl->registerObject(); 122 123 window.window[i] = winCtrl; 124 125 _setDefaultCaption( window, i ); 126 127 // Allocate background GuiBitmapCtrl 128 GuiBitmapCtrl *bmpCtrl = new GuiBitmapCtrl(); 129 bmpCtrl->setPosition( 3, 23 ); 130 bmpCtrl->setSizing( GuiControl::horizResizeWidth, GuiControl::vertResizeHeight ); 131 bmpCtrl->setExtent( 341, 181 ); 132 bmpCtrl->setDataField( StringTable->insert( "wrap" ), NULL, "1" ); 133 bmpCtrl->setBitmap( "tools/gui/images/transp_grid" ); 134 bmpCtrl->registerObject(); 135 winCtrl->addObject( bmpCtrl ); 136 137 // Allocate GuiBitmapCtrl 138 bmpCtrl = new GuiBitmapCtrl(); 139 bmpCtrl->setPosition( 3, 23 ); 140 bmpCtrl->setSizing( GuiControl::horizResizeWidth, GuiControl::vertResizeHeight ); 141 bmpCtrl->setExtent( 341, 181 ); 142 bmpCtrl->registerObject(); 143 winCtrl->addObject( bmpCtrl ); 144 145 window.bmp[i] = bmpCtrl; 146 147 content->addObject( winCtrl ); 148 } 149 150 // Make sure we visible. 151 setVisible( true ); 152} 153 154void PostEffectVis::setVisible( bool visible ) 155{ 156 GuiCanvas *canvas = NULL; 157 if ( !Sim::findObject( "Canvas", canvas ) ) 158 { 159 Con::errorf( "PostEffectVis::setVisible, Canvas was not found." ); 160 return; 161 } 162 163 GuiControl *content = _getContentControl(); 164 165 if ( visible && !content->isAwake() ) 166 canvas->pushDialogControl( content, 100 ); 167 168 if ( !visible && content->isAwake() ) 169 canvas->popDialogControl( content ); 170} 171 172void PostEffectVis::clear() 173{ 174 GuiControl *content = _getContentControl(); 175 176 content->clear(); 177 mWindows.clear(); 178} 179 180void PostEffectVis::onStartOfFrame() 181{ 182 if ( mWindows.empty() ) 183 return; 184 if ( !_getContentControl()->isAwake() ) 185 return; 186 187 // Restore vis windows to a default state. 188 // This ensures to users that open PostEffects that are not 189 // actively being processed are obvious. 190 191 VisVector::iterator itr = mWindows.begin(); 192 for ( ; itr != mWindows.end(); itr++ ) 193 { 194 for ( U32 i = 0; i < TexCount; i++ ) 195 { 196 if ( !itr->bmp[i] || itr->pfx->getRenderTime() == PFXTexGenOnDemand ) 197 continue; 198 199 itr->bmp[i]->setBitmap( NULL ); 200 _setDefaultCaption( *itr, i ); 201 } 202 } 203} 204 205void PostEffectVis::onPFXProcessed( PostEffect *pfx ) 206{ 207 // If we have no windows we can early out before even testing 208 // isAwake so we avoid creating the content control unnecessarily. 209 if ( mWindows.empty() ) 210 return; 211 212 if ( !_getContentControl()->isAwake() ) 213 return; 214 215 VisVector::iterator itr = mWindows.begin(); 216 for ( ; itr != mWindows.end(); itr++ ) 217 { 218 if ( itr->pfx == pfx ) 219 { 220 GuiBitmapCtrl *pBmpCtrl = NULL; 221 GuiWindowCtrl *pWinCtrl = NULL; 222 223 if ( itr->bmp[Target] != NULL ) 224 { 225 pBmpCtrl = itr->bmp[Target]; 226 pWinCtrl = itr->window[Target]; 227 228 GFXTextureObject *tex; 229 230 if ( pfx->mTargetTex ) 231 tex = pfx->mTargetTex; 232 else 233 tex = PFXMGR->getBackBufferTex(); 234 235 pBmpCtrl->setBitmapHandle( tex ); 236 237 char caption[256]; 238 char name[256]; 239 240 if ( pfx->getName() == NULL || dStrlen( pfx->getName() ) == 0 ) 241 dSprintf( name, 256, "(none)" ); 242 else 243 dSprintf( name, 256, "%s", pfx->getName() ); 244 245 246 if ( tex ) 247 dSprintf( caption, 256, "%s[%i] target - %s [ %ix%i ]", name, pfx->getId(), pfx->mTargetName.c_str(), tex->getWidth(), tex->getHeight() ); 248 else 249 dSprintf( caption, 256, "%s[%i] target", name, pfx->getId() ); 250 251 252 pWinCtrl->setDataField( StringTable->insert("text"), NULL, caption ); 253 } 254 255 for ( U32 i = Input1; i < TexCount; i++ ) 256 { 257 if ( itr->bmp[i] == NULL ) 258 continue; 259 260 pBmpCtrl = itr->bmp[i]; 261 pWinCtrl = itr->window[i]; 262 263 GFXTextureObject *tex = pfx->mActiveTextures[i-1]; 264 265 pBmpCtrl->setBitmapHandle( tex ); 266 267 char caption[256]; 268 char name[256]; 269 270 if ( pfx->getName() == NULL || dStrlen( pfx->getName() ) == 0 ) 271 dSprintf( name, 256, "(none)" ); 272 else 273 dSprintf( name, 256, "%s", pfx->getName() ); 274 275 276 if ( tex ) 277 dSprintf( caption, 256, "%s[%i] input%i - %s [ %ix%i ]", name, pfx->getId(), i-1, pfx->mTexFilename[i-1].c_str(), tex->getWidth(), tex->getHeight() ); 278 else 279 dSprintf( caption, 256, "%s[%i] input%i - %s", name, pfx->getId(), i-1, pfx->mTexFilename[i-1].c_str() ); 280 281 pWinCtrl->setDataField( StringTable->insert("text"), NULL, caption ); 282 } 283 } 284 } 285} 286 287void PostEffectVis::onWindowClosed( GuiWindowCtrl *ctrl ) 288{ 289 VisVector::iterator itr = mWindows.begin(); 290 291 for ( ; itr != mWindows.end(); itr++ ) 292 { 293 for ( U32 i = 0; i < TexCount; i++ ) 294 { 295 if ( itr->window[i] == ctrl ) 296 { 297 itr->window[i] = NULL; 298 itr->bmp[i] = NULL; 299 ctrl->setVisible( false ); 300 301 // Avoid deleting immediately since this happens in response to a 302 // script callback. 303 Con::evaluate( "%i.schedule( 1, \"delete\" );" ); 304 305 return; 306 } 307 } 308 } 309 310 Con::errorf( "PostEffectVis::onWindowClosed, passed window (%s) [%i] was found.", StringTable->insert( ctrl->getName() ), ctrl->getId() ); 311} 312 313GuiControl* PostEffectVis::_getContentControl() 314{ 315 if ( mContent == NULL ) 316 { 317 GuiCanvas *canvas = NULL; 318 if ( !Sim::findObject( "Canvas", canvas ) ) 319 { 320 AssertFatal( false, "PostEffectVis::_getContentControl, Canvas not found." ); 321 return NULL; 322 } 323 324 mContent = new GuiControl(); 325 mContent->setPosition( 0, 0 ); 326 mContent->setExtent( 1024, 768 ); 327 mContent->setDataField( StringTable->insert( "noCursor" ), NULL, "1" ); 328 mContent->setDataField( StringTable->insert( "profile" ), NULL, "GuiModelessDialogProfile" ); 329 mContent->registerObject( "PfxVisContent" ); 330 331 canvas->pushDialogControl( mContent, 100 ); 332 } 333 334 return mContent; 335} 336 337void PostEffectVis::_setDefaultCaption( VisWindow &vis, U32 texIndex ) 338{ 339 PostEffect *pfx = vis.pfx; 340 GuiWindowCtrl *winCtrl = vis.window[texIndex]; 341 342 if ( texIndex == Target ) 343 { 344 char caption[256]; 345 char name[256]; 346 347 if ( pfx->getName() == NULL || dStrlen( pfx->getName() ) == 0 ) 348 dSprintf( name, 256, "(none)" ); 349 else 350 dSprintf( name, 256, "%s", pfx->getName() ); 351 352 dSprintf( caption, 256, "%s[%i] target [NOT ENABLED]", name, pfx->getId() ); 353 354 winCtrl->setDataField( StringTable->insert("text"), NULL, caption ); 355 } 356 else 357 { 358 char caption[256]; 359 char name[256]; 360 361 if ( pfx->getName() == NULL || dStrlen( pfx->getName() ) == 0 ) 362 dSprintf( name, 256, "(none)" ); 363 else 364 dSprintf( name, 256, "%s", pfx->getName() ); 365 366 dSprintf( caption, 256, "%s[%i] input%i - %s [NOT ENABLED]", name, pfx->getId(), texIndex-1, pfx->mTexFilename[texIndex-1].c_str() ); 367 368 winCtrl->setDataField( StringTable->insert("text"), NULL, caption ); 369 } 370} 371 372static ConsoleDocFragment _PfxVisclear( 373 "@brief Close all visualization windows.\n\n" 374 "@tsexample\n" 375 "PfxVis::clear();" 376 "@endtsexample\n\n", 377 "PfxVis", 378 "void clear();" ); 379 380 381DefineEngineStaticMethod( PfxVis, clear, void, (),, 382 "@hide") 383{ 384 PFXVIS->clear(); 385} 386 387static ConsoleDocFragment _PfxVisopen( 388 "@brief Open visualization windows for all input and target textures.\n\n" 389 "@param effect Name of the PostEffect to open\n" 390 "@param clear True to close all visualization windows before opening the effect\n\n" 391 "@tsexample\n" 392 "// Multiple PostEffects can be visualized at the same time\n" 393 "PfxVis::open( PostEffect )\n" 394 "@endtsexample\n\n", 395 "PfxVis", 396 "void open(PostEffect effect, bool clear);" ); 397 398DefineEngineStaticMethod( PfxVis, open, void, (PostEffect* pfx, bool clear), (false), "( PostEffect, [bool clear = false] )" 399 "@hide") 400{ 401 if ( clear ) 402 PFXVIS->clear(); 403 404 if ( !pfx ) 405 { 406 Con::errorf( "PfxVis::add, argument was not a PostEffect"); 407 return; 408 } 409 410 PFXVIS->open( pfx ); 411} 412 413static ConsoleDocFragment _PfxVishide( 414 "@brief Hide all visualization windows (they are not destroyed).\n\n" 415 "@tsexample\n" 416 "PfxVis::hide();" 417 "@endtsexample\n\n", 418 "PfxVis", 419 "void hide();" ); 420 421DefineEngineStaticMethod( PfxVis, hide, void, (),, 422 "@hide") 423{ 424 PFXVIS->setVisible( false ); 425} 426 427static ConsoleDocFragment _PfxVisshow( 428 "@brief Show all visualization windows.\n\n" 429 "@tsexample\n" 430 "PfxVis::show();" 431 "@endtsexample\n\n", 432 "PfxVis", 433 "void show();" ); 434 435DefineEngineStaticMethod( PfxVis, show, void, (),, 436 "@hide") 437{ 438 PFXVIS->setVisible( true ); 439} 440 441static ConsoleDocFragment _PfxVisonWindowClosed( 442 "@brief Callback when a visualization window is closed.\n\n" 443 "@param ctrl Name of the GUI control being closed\n" 444 "@tsexample\n" 445 "PfxVis::onWindowClosed( VisWindow )\n" 446 "@endtsexample\n\n", 447 "PfxVis", 448 "void onWindowClosed(GuiWindowCtrl *ctrl);" ); 449 450DefineEngineStaticMethod( PfxVis, onWindowClosed, void, (GuiWindowCtrl* ctrl),, 451 "@hide") 452{ 453 if ( !ctrl ) 454 { 455 Con::errorf( "PfxVis::onWindowClosed, argument was not a GuiWindowCtrl"); 456 return; 457 } 458 459 PFXVIS->onWindowClosed( ctrl ); 460} 461