static void dumpVariable( Stream& stream, Dictionary::Entry* entry, const char* inClass = NULL ) { // Skip variables defined in script. if( entry->type < 0 ) return; // Skip internals... don't export them. if ( entry->mUsage && ( dStrstr( entry->mUsage, "@hide" ) || dStrstr( entry->mUsage, "@internal" ) ) ) return; // Split up qualified name. Vector< String > nameComponents; String( entry->name ).split( "::", nameComponents ); if( !nameComponents.size() ) // Safety check. return; // Match filter. if( inClass ) { // Make sure first qualifier in name components is a // namespace qualifier matching the given class name. if( nameComponents.size() <= 1 || dStricmp( nameComponents.first().c_str() + 1, inClass ) != 0 ) // Skip '$'. return; } else { // Make sure, this is *not* in a class namespace. if( nameComponents.size() > 1 && Con::lookupNamespace( nameComponents.first().c_str() + 1 )->mClassRep ) return; } // Skip variables for which we can't decipher their type. ConsoleBaseType* type = ConsoleBaseType::getType( entry->type ); if( !type ) { Con::errorf( "Can't find type for variable '%s'", entry->name ); return; } // Write doc comment. stream.writeText( "/*!\r\n" ); if( !inClass ) { stream.writeText( "@var " ); stream.writeText( type->getTypeClassName() ); stream.writeText( " " ); stream.writeText( entry->name ); stream.writeText( ";\r\n" ); } dumpDoc( stream, entry->mUsage ); stream.writeText( "*/\r\n" ); // Write definition. const U32 numNameComponents = nameComponents.size(); if( !inClass && numNameComponents > 1 ) for( U32 i = 0; i < ( numNameComponents - 1 ); ++ i ) { stream.writeText( "namespace " ); stream.writeText( nameComponents[ i ] ); stream.writeText( " { " ); } if( inClass ) stream.writeText( "static " ); if( entry->mIsConstant ) stream.writeText( "const " ); stream.writeText( type->getTypeClassName() ); stream.writeText( " " ); stream.writeText( nameComponents.last() ); stream.writeText( ";" ); if( !inClass && numNameComponents > 1 ) for( U32 i = 0; i < ( numNameComponents - 1 ); ++ i ) stream.writeText( " } " ); stream.writeText( "\r\n" ); }
GuiInspectorField* GuiInspectorGroup::constructField( S32 fieldType ) { // See if we can construct a field of this type ConsoleBaseType *cbt = ConsoleBaseType::getType(fieldType); if( !cbt ) return NULL; // Alright, is it a datablock? if(cbt->isDatablock()) { // Default to GameBaseData StringTableEntry typeClassName = cbt->getTypeClassName(); if (mTarget && !dStricmp(typeClassName, "GameBaseData")) { // Try and setup the classname based on the object type char className[256]; dSprintf(className,256,"%sData",mTarget->getClassName()); // Walk the ACR list and find a matching class if any. AbstractClassRep *walk = AbstractClassRep::getClassList(); while(walk) { if(!dStricmp(walk->getClassName(), className)) break; walk = walk->getNextClass(); } // We found a valid class if (walk) typeClassName = walk->getClassName(); } GuiInspectorDatablockField *dbFieldClass = new GuiInspectorDatablockField( typeClassName ); if( dbFieldClass != NULL ) { // return our new datablock field with correct datablock type enumeration info return dbFieldClass; } } // Nope, not a datablock. So maybe it has a valid inspector field override we can use? if(!cbt->getInspectorFieldType()) // Nothing, so bail. return NULL; // Otherwise try to make it! ConsoleObject *co = create(cbt->getInspectorFieldType()); GuiInspectorField *gif = dynamic_cast<GuiInspectorField*>(co); if(!gif) { // Wasn't appropriate type, bail. delete co; return NULL; } return gif; }
bool GuiInspectorGroup::inspectGroup() { // We can't inspect a group without a target! if( !mTarget ) return false; // to prevent crazy resizing, we'll just freeze our stack for a sec.. mStack->freeze(true); bool bNoGroup = false; // Un-grouped fields are all sorted into the 'general' group if ( dStricmp( mCaption, "General" ) == 0 ) bNoGroup = true; AbstractClassRep::FieldList &fieldList = mTarget->getModifiableFieldList(); AbstractClassRep::FieldList::iterator itr; bool bGrabItems = false; bool bNewItems = false; bool bMakingArray = false; GuiStackControl *pArrayStack = NULL; GuiRolloutCtrl *pArrayRollout = NULL; // Just delete all fields and recreate them (like the dynamicGroup) // because that makes creating controls for array fields a lot easier clearFields(); for ( itr = fieldList.begin(); itr != fieldList.end(); itr++ ) { if( itr->type == AbstractClassRep::StartGroupFieldType ) { // If we're dealing with general fields, always set grabItems to true (to skip them) if( bNoGroup == true ) bGrabItems = true; else if( itr->pGroupname != NULL && dStricmp( itr->pGroupname, mCaption ) == 0 ) bGrabItems = true; continue; } else if ( itr->type == AbstractClassRep::EndGroupFieldType ) { // If we're dealing with general fields, always set grabItems to false (to grab them) if( bNoGroup == true ) bGrabItems = false; else if( itr->pGroupname != NULL && dStricmp( itr->pGroupname, mCaption ) == 0 ) bGrabItems = false; continue; } if( ( bGrabItems == true || ( bNoGroup == true && bGrabItems == false ) ) && itr->type != AbstractClassRep::DeprecatedFieldType ) { if( bNoGroup == true && bGrabItems == true ) continue; if ( itr->type == AbstractClassRep::StartArrayFieldType ) { // Starting an array... // Create a rollout for the Array, give it the array's name. GuiRolloutCtrl *arrayRollout = new GuiRolloutCtrl(); GuiControlProfile *arrayRolloutProfile = dynamic_cast<GuiControlProfile*>( Sim::findObject( "GuiInspectorRolloutProfile0" ) ); arrayRollout->setControlProfile(arrayRolloutProfile); //arrayRollout->mCaption = StringTable->insert( String::ToString( "%s (%i)", itr->pGroupname, itr->elementCount ) ); arrayRollout->mCaption = StringTable->insert( itr->pGroupname ); arrayRollout->mMargin.set( 14, 0, 0, 0 ); arrayRollout->registerObject(); GuiStackControl *arrayStack = new GuiStackControl(); arrayStack->registerObject(); arrayStack->freeze(true); arrayRollout->addObject(arrayStack); // Allocate a rollout for each element-count in the array // Give it the element count name. for ( U32 i = 0; i < itr->elementCount; i++ ) { GuiRolloutCtrl *elementRollout = new GuiRolloutCtrl(); GuiControlProfile *elementRolloutProfile = dynamic_cast<GuiControlProfile*>( Sim::findObject( "GuiInspectorRolloutProfile0" ) ); char buf[256]; dSprintf( buf, 256, " [%i]", i ); elementRollout->setControlProfile(elementRolloutProfile); elementRollout->mCaption = StringTable->insert(buf); elementRollout->mMargin.set( 14, 0, 0, 0 ); elementRollout->registerObject(); GuiStackControl *elementStack = new GuiStackControl(); elementStack->registerObject(); elementRollout->addObject(elementStack); elementRollout->instantCollapse(); arrayStack->addObject( elementRollout ); } pArrayRollout = arrayRollout; pArrayStack = arrayStack; arrayStack->freeze(false); pArrayRollout->instantCollapse(); mStack->addObject(arrayRollout); bMakingArray = true; continue; } else if ( itr->type == AbstractClassRep::EndArrayFieldType ) { bMakingArray = false; continue; } if ( bMakingArray ) { // Add a GuiInspectorField for this field, // for every element in the array... for ( U32 i = 0; i < pArrayStack->size(); i++ ) { FrameTemp<char> intToStr( 64 ); dSprintf( intToStr, 64, "%d", i ); // The array stack should have a rollout for each element // as children... GuiRolloutCtrl *pRollout = dynamic_cast<GuiRolloutCtrl*>(pArrayStack->at(i)); // And the each of those rollouts should have a stack for // fields... GuiStackControl *pStack = dynamic_cast<GuiStackControl*>(pRollout->at(0)); // And we add a new GuiInspectorField to each of those stacks... GuiInspectorField *field = constructField( itr->type ); if ( field == NULL ) field = new GuiInspectorField(); field->init( mParent, this, mTarget ); StringTableEntry caption = StringTable->insert( itr->pFieldname ); field->setInspectorField( itr, caption, intToStr ); if( field->registerObject() ) { mChildren.push_back( field ); pStack->addObject( field ); } else delete field; } continue; } // This is weird, but it should work for now. - JDD // We are going to check to see if this item is an array // if so, we're going to construct a field for each array element if( itr->elementCount > 1 ) { // Make a rollout control for this array // GuiRolloutCtrl *rollout = new GuiRolloutCtrl(); rollout->setDataField( StringTable->insert("profile"), NULL, "GuiInspectorRolloutProfile0" ); rollout->mCaption = StringTable->insert(String::ToString( "%s (%i)", itr->pFieldname, itr->elementCount)); rollout->mMargin.set( 14, 0, 0, 0 ); rollout->registerObject(); mArrayCtrls.push_back(rollout); // Put a stack control within the rollout // GuiStackControl *stack = new GuiStackControl(); stack->setDataField( StringTable->insert("profile"), NULL, "GuiInspectorStackProfile" ); stack->registerObject(); stack->freeze(true); rollout->addObject(stack); mStack->addObject(rollout); // Create each field and add it to the stack. // for (S32 nI = 0; nI < itr->elementCount; nI++) { FrameTemp<char> intToStr( 64 ); dSprintf( intToStr, 64, "%d", nI ); // Construct proper ValueName[nI] format which is "ValueName0" for index 0, etc. String fieldName = String::ToString( "%s%d", itr->pFieldname, nI ); // If the field already exists, just update it GuiInspectorField *field = findField( fieldName ); if( field != NULL ) { field->updateValue(); continue; } bNewItems = true; field = constructField( itr->type ); if ( field == NULL ) field = new GuiInspectorField(); field->init( mParent, this, mTarget ); StringTableEntry caption = StringTable->insert( String::ToString(" [%i]",nI) ); field->setInspectorField( itr, caption, intToStr ); if ( field->registerObject() ) { mChildren.push_back( field ); stack->addObject( field ); } else delete field; } stack->freeze(false); stack->updatePanes(); rollout->instantCollapse(); } else { // If the field already exists, just update it GuiInspectorField *field = findField( itr->pFieldname ); if ( field != NULL ) { field->updateValue(); continue; } bNewItems = true; field = constructField( itr->type ); if ( field == NULL ) field = new GuiInspectorField(); field->init( mParent, this, mTarget ); field->setInspectorField( itr ); if ( field->registerObject() ) { mChildren.push_back( field ); mStack->addObject( field ); } else delete field; } } } mStack->freeze(false); mStack->updatePanes(); // If we've no new items, there's no need to resize anything! if( bNewItems == false && !mChildren.empty() ) return true; sizeToContents(); setUpdate(); return true; }
bool StandardMainLoop::handleCommandLine( S32 argc, const char **argv ) { // Allow the window manager to process command line inputs; this is // done to let web plugin functionality happen in a fairly transparent way. PlatformWindowManager::get()->processCmdLineArgs(argc, argv); Process::handleCommandLine( argc, argv ); // Set up the command line args for the console scripts... Con::setIntVariable("Game::argc", argc); U32 i; for (i = 0; i < argc; i++) Con::setVariable(avar("Game::argv%d", i), argv[i]); Platform::FS::InstallFileSystems(); // install all drives for now until we have everything using the volume stuff Platform::FS::MountDefaults(); // Set our working directory. Torque::FS::SetCwd( "game:/" ); // Set our working directory. Platform::setCurrentDirectory( Platform::getMainDotCsDir() ); #ifdef TORQUE_PLAYER if(argc > 2 && dStricmp(argv[1], "-project") == 0) { char playerPath[1024]; Platform::makeFullPathName(argv[2], playerPath, sizeof(playerPath)); Platform::setCurrentDirectory(playerPath); argv += 2; argc -= 2; // Re-locate the game:/ asset mount. Torque::FS::Unmount( "game" ); Torque::FS::Mount( "game", Platform::FS::createNativeFS( playerPath ) ); } #endif // Executes an entry script file. This is "main.cs" // by default, but any file name (with no whitespace // in it) may be run if it is specified as the first // command-line parameter. The script used, default // or otherwise, is not compiled and is loaded here // directly because the resource system restricts // access to the "root" directory. #ifdef TORQUE_ENABLE_VFS Zip::ZipArchive *vfs = openEmbeddedVFSArchive(); bool useVFS = vfs != NULL; #endif Stream *mainCsStream = NULL; // The working filestream. FileStream str; const char *defaultScriptName = "main.cs"; bool useDefaultScript = true; // Check if any command-line parameters were passed (the first is just the app name). if (argc > 1) { // If so, check if the first parameter is a file to open. if ( (dStrcmp(argv[1], "") != 0 ) && (str.open(argv[1], Torque::FS::File::Read)) ) { // If it opens, we assume it is the script to run. useDefaultScript = false; #ifdef TORQUE_ENABLE_VFS useVFS = false; #endif mainCsStream = &str; } } if (useDefaultScript) { bool success = false; #ifdef TORQUE_ENABLE_VFS if(useVFS) success = (mainCsStream = vfs->openFile(defaultScriptName, Zip::ZipArchive::Read)) != NULL; else #endif success = str.open(defaultScriptName, Torque::FS::File::Read); #if defined( TORQUE_DEBUG ) && defined (TORQUE_TOOLS) && !defined( _XBOX ) if (!success) { OpenFileDialog ofd; FileDialogData &fdd = ofd.getData(); fdd.mFilters = StringTable->insert("Main Entry Script (main.cs)|main.cs|"); fdd.mTitle = StringTable->insert("Locate Game Entry Script"); // Get the user's selection if( !ofd.Execute() ) return false; // Process and update CWD so we can run the selected main.cs S32 pathLen = dStrlen( fdd.mFile ); FrameTemp<char> szPathCopy( pathLen + 1); dStrcpy( szPathCopy, fdd.mFile ); //forwardslash( szPathCopy ); const char *path = dStrrchr(szPathCopy, '/'); if(path) { U32 len = path - (const char*)szPathCopy; szPathCopy[len+1] = 0; Platform::setCurrentDirectory(szPathCopy); // Re-locate the game:/ asset mount. Torque::FS::Unmount( "game" ); Torque::FS::Mount( "game", Platform::FS::createNativeFS( ( const char* ) szPathCopy ) ); success = str.open(fdd.mFile, Torque::FS::File::Read); if(success) defaultScriptName = fdd.mFile; } } #endif if( !success ) { char msg[1024]; dSprintf(msg, sizeof(msg), "Failed to open \"%s\".", defaultScriptName); Platform::AlertOK("Error", msg); #ifdef TORQUE_ENABLE_VFS closeEmbeddedVFSArchive(); #endif return false; } #ifdef TORQUE_ENABLE_VFS if(! useVFS) #endif mainCsStream = &str; } // This should rarely happen, but lets deal with // it gracefully if it does. if ( mainCsStream == NULL ) return false; U32 size = mainCsStream->getStreamSize(); char *script = new char[size + 1]; mainCsStream->read(size, script); #ifdef TORQUE_ENABLE_VFS if(useVFS) vfs->closeFile(mainCsStream); else #endif str.close(); script[size] = 0; char buffer[1024], *ptr; Platform::makeFullPathName(useDefaultScript ? defaultScriptName : argv[1], buffer, sizeof(buffer), Platform::getCurrentDirectory()); ptr = dStrrchr(buffer, '/'); if(ptr != NULL) *ptr = 0; Platform::setMainDotCsDir(buffer); Platform::setCurrentDirectory(buffer); Con::evaluate(script, false, useDefaultScript ? defaultScriptName : argv[1]); delete[] script; #ifdef TORQUE_ENABLE_VFS closeEmbeddedVFSArchive(); #endif return true; }
void GuiTextEditCtrl::onStaticModified(const char* slotName, const char* newValue) { if(!dStricmp(slotName, "text")) setText(mText); }
/// Check if one string ends with another bool dStrEndsWith(const char* str1, const char* str2) { const char *p = str1 + dStrlen(str1) - dStrlen(str2); return ((p >= str1) && !dStricmp(p, str2)); }
bool dAtob(const char *str) { return !dStricmp(str, "true") || !dStricmp(str, "1") || (0!=dAtoi(str)); }
bool Net::stringToAddress(const char *addressString, NetAddress *address) { if(!dStrnicmp(addressString, "ipx:", 4)) // ipx support deprecated return false; if(!dStrnicmp(addressString, "ip:", 3)) addressString += 3; // eat off the ip: sockaddr_in ipAddr; char remoteAddr[256]; if(strlen(addressString) > 255) return false; dStrcpy(remoteAddr, addressString); char *portString = dStrchr(remoteAddr, ':'); if(portString) *portString++ = '\0'; if(!dStricmp(remoteAddr, "broadcast")) ipAddr.sin_addr.s_addr = htonl(INADDR_BROADCAST); else { ipAddr.sin_addr.s_addr = inet_addr(remoteAddr); if (ipAddr.sin_addr.s_addr == INADDR_NONE) // error { // On the Xbox, 'gethostbyname' does not exist so... #ifndef TORQUE_OS_XENON struct hostent *hp; if((hp = gethostbyname(remoteAddr)) == 0) return false; else memcpy(&ipAddr.sin_addr.s_addr, hp->h_addr, sizeof(in_addr)); #else // On the Xbox do XNetDnsLookup XNDNS *pxndns = NULL; HANDLE hEvent = CreateEvent(NULL, false, false, NULL); XNetDnsLookup(remoteAddr, hEvent, &pxndns); // Wait for event (passing NULL as a handle to XNetDnsLookup will NOT // cause it to behave synchronously, so do not remove the handle/wait while(pxndns->iStatus == WSAEINPROGRESS) WaitForSingleObject(hEvent, INFINITE); bool foundAddr = pxndns->iStatus == 0 && pxndns->cina > 0; if(foundAddr) { // Lets just grab the first address returned, for now memcpy(&ipAddr.sin_addr, pxndns->aina, sizeof(IN_ADDR)); } XNetDnsRelease(pxndns); CloseHandle(hEvent); // If we didn't successfully resolve the DNS lookup, bail after the // handles are released if(!foundAddr) return false; #endif } } if(portString) ipAddr.sin_port = htons(dAtoi(portString)); else ipAddr.sin_port = htons(defaultPort); ipAddr.sin_family = AF_INET; IPSocketToNetAddress(&ipAddr, address); return true; }
NetSocket Net::openConnectTo(const char *addressString) { if(!dStrnicmp(addressString, "ipx:", 4)) // ipx support deprecated return InvalidSocket; if(!dStrnicmp(addressString, "ip:", 3)) addressString += 3; // eat off the ip: char remoteAddr[256]; dStrcpy(remoteAddr, addressString); char *portString = dStrchr(remoteAddr, ':'); U16 port; if(portString) { *portString++ = 0; port = htons(dAtoi(portString)); } else port = htons(defaultPort); if(!dStricmp(remoteAddr, "broadcast")) return InvalidSocket; if(Journal::IsPlaying()) { U32 ret; Journal::Read(&ret); return NetSocket(ret); } NetSocket sock = openSocket(); setBlocking(sock, false); sockaddr_in ipAddr; dMemset(&ipAddr, 0, sizeof(ipAddr)); ipAddr.sin_addr.s_addr = inet_addr(remoteAddr); if(ipAddr.sin_addr.s_addr != INADDR_NONE) { ipAddr.sin_port = port; ipAddr.sin_family = AF_INET; if(::connect(sock, (struct sockaddr *)&ipAddr, sizeof(ipAddr)) == -1) { S32 err = getLastError(); if(err != Net::WouldBlock) { Con::errorf("Error connecting %s: %s", addressString, strerror(err)); ::closesocket(sock); sock = InvalidSocket; } } if(sock != InvalidSocket) { // add this socket to our list of polled sockets addPolledSocket(sock, ConnectionPending); } } else { // need to do an asynchronous name lookup. first, add the socket // to the polled list addPolledSocket(sock, NameLookupRequired, remoteAddr, port); // queue the lookup gNetAsync.queueLookup(remoteAddr, sock); } if(Journal::IsRecording()) Journal::Write(U32(sock)); return sock; }
//----------------------------------------------------------------------------- // GuiInspectorMountingGroup - inspectGroup override //----------------------------------------------------------------------------- bool GuiInspectorMountingGroup::inspectGroup() { // We can't inspect a group without a target! if( !mParent->getNumInspectObjects() ) return false; // to prevent crazy resizing, we'll just freeze our stack for a sec.. mStack->freeze(true); bool bNoGroup = false; // Un-grouped fields are all sorted into the 'general' group if ( dStricmp( mCaption, "General" ) == 0 ) bNoGroup = true; // Just delete all fields and recreate them (like the dynamicGroup) // because that makes creating controls for array fields a lot easier clearFields(); bool bNewItems = false; bool bMakingArray = false; GuiStackControl *pArrayStack = NULL; GuiRolloutCtrl *pArrayRollout = NULL; bool bGrabItems = false; AbstractClassRep* commonAncestorClass = findCommonAncestorClass(); AbstractClassRep::FieldList& fieldList = commonAncestorClass->mFieldList; for( AbstractClassRep::FieldList::iterator itr = fieldList.begin(); itr != fieldList.end(); ++ itr ) { AbstractClassRep::Field* field = &( *itr ); if( field->type == AbstractClassRep::StartGroupFieldType ) { // If we're dealing with general fields, always set grabItems to true (to skip them) if( bNoGroup == true ) bGrabItems = true; else if( dStricmp( field->pGroupname, mCaption ) == 0 ) bGrabItems = true; continue; } else if ( field->type == AbstractClassRep::EndGroupFieldType ) { // If we're dealing with general fields, always set grabItems to false (to grab them) if( bNoGroup == true ) bGrabItems = false; else if( dStricmp( field->pGroupname, mCaption ) == 0 ) bGrabItems = false; continue; } // Skip field if it has the HideInInspectors flag set. if( field->flag.test( AbstractClassRep::FIELD_HideInInspectors ) ) continue; if( ( bGrabItems == true || ( bNoGroup == true && bGrabItems == false ) ) && itr->type != AbstractClassRep::DeprecatedFieldType ) { if( bNoGroup == true && bGrabItems == true ) continue; // If the field already exists, just update it GuiInspectorField *fieldGui = findField( field->pFieldname ); if ( fieldGui != NULL ) { fieldGui->updateValue(); continue; } bNewItems = true; if(field->pFieldname == StringTable->insert("mountNode")) { fieldGui = new GuiInspectorNodeListField(); Entity* e = dynamic_cast<Entity*>(mParent->getInspectObject(0)); if(e) (dynamic_cast<GuiInspectorNodeListField*>(fieldGui))->setTargetEntity(e); } else { fieldGui = constructField( field->type ); if ( fieldGui == NULL ) fieldGui = new GuiInspectorField(); } fieldGui->init( mParent, this ); fieldGui->setInspectorField( field ); if( fieldGui->registerObject() ) { #ifdef DEBUG_SPEW Platform::outputDebugString( "[GuiInspectorGroup] Adding field '%s'", field->pFieldname ); #endif mChildren.push_back( fieldGui ); mStack->addObject( fieldGui ); } else { SAFE_DELETE( fieldGui ); } } } mStack->freeze(false); mStack->updatePanes(); // If we've no new items, there's no need to resize anything! if( bNewItems == false && !mChildren.empty() ) return true; sizeToContents(); setUpdate(); return true; }