void ResourceEditor::SetModified(bool modified) { modified_ = modified; if (modified) { String filename = GetFileNameAndExtension(fullpath_); filename += "*"; button_->SetText(filename.CString()); } else { String filename = GetFileNameAndExtension(fullpath_); button_->SetText(filename.CString()); } }
void ResourceCache::RemovePackageFile(const String& fileName, bool releaseResources, bool forceRelease) { // Compare the name and extension only, not the path String fileNameNoPath = GetFileNameAndExtension(fileName); for (Vector<SharedPtr<PackageFile> >::Iterator i = packages_.Begin(); i != packages_.End(); ++i) { if (!GetFileNameAndExtension((*i)->GetName()).Compare(fileNameNoPath, false)) { if (releaseResources) ReleasePackageResources(*i, forceRelease); LOGINFO("Removed resource package " + (*i)->GetName()); packages_.Erase(i); return; } } }
void CSModuleWriter::WriteIncludes(String& source) { Vector<String>& includes = module_->includes_; for (unsigned i = 0; i < includes.Size(); i++) { if (includes[i].StartsWith("<")) source.AppendWithFormat("#include %s\n", includes[i].CString()); else source.AppendWithFormat("#include \"%s\"\n", includes[i].CString()); } Vector<JSBHeader*> allheaders; HashMap<StringHash, SharedPtr<JSBEnum> >::Iterator eitr = module_->enums_.Begin(); while (eitr != module_->enums_.End()) { allheaders.Push(eitr->second_->GetHeader()); eitr++; } HashMap<StringHash, SharedPtr<JSBClass> >::Iterator citr = module_->classes_.Begin(); while (citr != module_->classes_.End()) { allheaders.Push(citr->second_->GetHeader()); citr++; } Vector<JSBHeader*> included; for (unsigned i = 0; i < allheaders.Size(); i++) { JSBHeader* header = allheaders.At(i); if (included.Contains(header)) continue; String headerPath = GetPath(header->GetFilePath()); String headerfile = GetFileNameAndExtension(header->GetFilePath()); JSBind* jsbind = header->GetSubsystem<JSBind>(); headerPath.Replace(jsbind->GetSourceRootFolder() + "Source/", ""); source.AppendWithFormat("#include <%s%s>\n", headerPath.CString(), headerfile.CString()); included.Push(header); } source += ToString("\n#include \"CSPackage%s.h\"\n", module_->GetPackage()->GetName().CString()); }
void JSBModule::WriteIncludes(String& source) { Vector<JSBHeader*> allheaders; for (unsigned i = 0; i < enums_.Size(); i++) { allheaders.Push(enums_.At(i)->header_); } for (unsigned i = 0; i < classes_.Size(); i++) { allheaders.Push(classes_.At(i)->GetHeader()); } Vector<JSBHeader*> included; for (unsigned i = 0; i < allheaders.Size(); i++) { JSBHeader* header = allheaders.At(i); if (included.Contains(header)) continue; String headerPath = GetPath(header->filepath_); String headerfile = GetFileNameAndExtension(header->filepath_); headerPath.Replace(JSBind::ROOT_FOLDER + "/Source/Atomic/", "Atomic/"); source.AppendWithFormat("#include <%s%s>\n", headerPath.CString(), headerfile.CString()); included.Push(header); } for (unsigned i = 0; i < includes_.Size(); i++) { if (includes_[i].StartsWith("<")) source.AppendWithFormat("#include %s\n", includes_[i].CString()); else source.AppendWithFormat("#include \"%s\"\n", includes_[i].CString()); } }
void IssuesWidget::UpdateIssues() { AEJavascript* aejs = GetSubsystem<AEJavascript>(); const Vector<JSError>& errors = aejs->GetJSErrors(); issueList_->DeleteAllItems(); for (unsigned i = 0; i < errors.Size(); i++) { const JSError& error = errors[i]; String errorString; String filename = GetFileNameAndExtension(error.fullpath); errorString.AppendWithFormat("%s - %s - Line: %i Column: %i", filename.CString(), error.message.CString(), error.line, error.column); issueList_->AddItem(errorString.CString(), NULL, TBID(i)); } }
ResourceEditor::ResourceEditor(Context* context, const String& fullpath, UITabContainer *container): Object(context), fullpath_(fullpath), container_(container), editorTabLayout_(0), rootContentWidget_(0), button_(0), modified_(false) { String filename = GetFileNameAndExtension(fullpath_); editorTabLayout_ = new EditorTabLayout(); editorTabLayout_->SetID(TBIDC("tab")); button_ = new UIButton(context_); button_->SetText(filename.CString()); button_->SetSqueezable(true); button_->SetSkinBg("TBButton.flat"); button_->SetValue(1); editorTabLayout_->AddChild(button_->GetInternalWidget()); TBButton* closebutton = new TBButton(); editorTabLayout_->AddChild(closebutton); closebutton->SetSkinBg(TBIDC("TBWindow.close")); closebutton->SetIsFocusable(false); closebutton->SetID(TBIDC("tabclose")); editorTabLayout_->editor_ = this; editorTabLayout_->button_ = (TBButton*) button_->GetInternalWidget(); editorTabLayout_->close_ = closebutton; editorTabLayout_->container_ = (TBTabContainer*) container->GetInternalWidget(); ((TBTabContainer*)container_->GetInternalWidget())->GetTabLayout()->AddChild(editorTabLayout_); rootContentWidget_ = new UIWidget(context_); rootContentWidget_->SetGravity(UI_GRAVITY_ALL); container_->GetContentRoot()->AddChild(rootContentWidget_); SubscribeToEvent(E_FILECHANGED, HANDLER(ResourceEditor, HandleFileChanged)); }
bool RequestClose() { if (editor_->HasUnsavedModifications()) { TBMessageWindow *msg_win = new TBMessageWindow(this, TBIDC("unsaved_modifications_dialog")); TBMessageWindowSettings settings(TB_MSG_NONE, TBID(uint32(0))); settings.dimmer = true; settings.styling = true; String windowString = Atomic::ToString("%s has unsaved modifications.\nDo you wish to discard them and close?", GetFileNameAndExtension(editor_->GetFullPath()).CString()); msg_win->Show("Unsaved Modifications", windowString.CString(), &settings, 640, 360); msg_win->AddButtonLeft("dont_save", false); msg_win->AddButton("TBMessageWindow.cancel", false); msg_win->AddButton("save", true); return false; } else { editor_->Close(container_->GetNumPages()>1); return true; } }
File::File(std::string filePath){ m_hasExtension = GetFileNameAndExtension(filePath, m_name, m_extension); m_size = GetFileSize(filePath); }
void Urho3DPlayer::Setup() { FileSystem* filesystem = GetSubsystem<FileSystem>(); // Read command line from a file if no arguments given. This is primarily intended for mobile platforms. // Note that the command file name uses a hardcoded path that does not utilize the resource system // properly (including resource path prefix), as the resource system is not yet initialized at this point const String commandFileName = filesystem->GetProgramDir() + "Data/CommandLine.txt"; if (GetArguments().Empty() && filesystem->FileExists(commandFileName)) { SharedPtr<File> commandFile(new File(context_, commandFileName)); String commandLine = commandFile->ReadLine(); commandFile->Close(); ParseArguments(commandLine, false); // Reparse engine startup parameters now engineParameters_ = Engine::ParseParameters(GetArguments()); } // Check for script file name const Vector<String>& arguments = GetArguments(); String scriptFileName; if (arguments.Size() && arguments[0][0] != '-') scriptFileName_ = GetInternalPath(arguments[0]); // Show usage if not found if (scriptFileName_.Empty()) { ErrorExit("Usage: Urho3DPlayer <scriptfile> [options]\n\n" "The script file should implement the function void Start() for initializing the " "application and subscribing to all necessary events, such as the frame update.\n" #ifndef WIN32 "\nCommand line options:\n" "-x <res> Horizontal resolution\n" "-y <res> Vertical resolution\n" "-m <level> Enable hardware multisampling\n" "-v Enable vertical sync\n" "-t Enable triple buffering\n" "-w Start in windowed mode\n" "-s Enable resizing when in windowed mode\n" "-q Enable quiet mode which does not log to standard output stream\n" "-b <length> Sound buffer length in milliseconds\n" "-r <freq> Sound mixing frequency in Hz\n" "-p <paths> Resource path(s) to use, separated by semicolons\n" "-ap <paths> Autoload resource path(s) to use, seperated by semicolons\n" "-log <level> Change the log level, valid 'level' values are 'debug', 'info', 'warning', 'error'\n" "-ds <file> Dump used shader variations to a file for precaching\n" "-mq <level> Material quality level, default 2 (high)\n" "-tq <level> Texture quality level, default 2 (high)\n" "-tf <level> Texture filter mode, default 2 (trilinear)\n" "-af <level> Texture anisotropy level, default 4. Also sets anisotropic filter mode\n" "-gl2 Force OpenGL 2 use even if OpenGL 3 is available\n" "-flushgpu Flush GPU command queue each frame. Effective only on Direct3D\n" "-borderless Borderless window mode\n" "-headless Headless mode. No application window will be created\n" "-landscape Use landscape orientations (iOS only, default)\n" "-portrait Use portrait orientations (iOS only)\n" "-prepass Use light pre-pass rendering\n" "-deferred Use deferred rendering\n" "-renderpath <name> Use the named renderpath (must enter full resource name)\n" "-lqshadows Use low-quality (1-sample) shadow filtering\n" "-noshadows Disable shadow rendering\n" "-nolimit Disable frame limiter\n" "-nothreads Disable worker threads\n" "-nosound Disable sound output\n" "-noip Disable sound mixing interpolation\n" "-touch Touch emulation on desktop platform\n" #endif ); } else { // Use the script file name as the base name for the log file engineParameters_["LogName"] = filesystem->GetAppPreferencesDir("urho3d", "logs") + GetFileNameAndExtension(scriptFileName_) + ".log"; } // Construct a search path to find the resource prefix with two entries: // The first entry is an empty path which will be substituted with program/bin directory -- this entry is for binary when it is still in build tree // The second and third entries are possible relative paths from the installed program/bin directory to the asset directory -- these entries are for binary when it is in the Urho3D SDK installation location if (!engineParameters_.Contains("ResourcePrefixPaths")) engineParameters_["ResourcePrefixPaths"] = ";../share/Resources;../share/Urho3D/Resources"; }
bool ParticleEffect2D::Save(Serializer& dest) const { if (!sprite_) return false; XMLFile xmlFile(context_); XMLElement rootElem = xmlFile.CreateRoot("particleEmitterConfig"); String fileName = GetFileNameAndExtension(sprite_->GetName()); rootElem.CreateChild("texture").SetAttribute("name", fileName); WriteVector2(rootElem, "sourcePosition", Vector2::ZERO); WriteVector2(rootElem, "sourcePositionVariance", sourcePositionVariance_); WriteFloat(rootElem, "speed", speed_); WriteFloat(rootElem, "speedVariance", speedVariance_); WriteFloat(rootElem, "particleLifeSpan", particleLifeSpan_); WriteFloat(rootElem, "particleLifespanVariance", particleLifespanVariance_); WriteFloat(rootElem, "angle", angle_); WriteFloat(rootElem, "angleVariance", angleVariance_); WriteVector2(rootElem, "gravity", gravity_); WriteFloat(rootElem, "radialAcceleration", radialAcceleration_); WriteFloat(rootElem, "tangentialAcceleration", tangentialAcceleration_); WriteFloat(rootElem, "radialAccelVariance", radialAccelVariance_); WriteFloat(rootElem, "tangentialAccelVariance", tangentialAccelVariance_); WriteColor(rootElem, "startColor", startColor_); WriteColor(rootElem, "startColorVariance", startColorVariance_); WriteColor(rootElem, "finishColor", finishColor_); WriteColor(rootElem, "finishColorVariance", finishColorVariance_); WriteInt(rootElem, "maxParticles", maxParticles_); WriteFloat(rootElem, "startParticleSize", startParticleSize_); WriteFloat(rootElem, "startParticleSizeVariance", startParticleSizeVariance_); WriteFloat(rootElem, "finishParticleSize", finishParticleSize_); // Typo in pex file WriteFloat(rootElem, "FinishParticleSizeVariance", FinishParticleSizeVariance_); float duration = duration_; if (duration == M_INFINITY) duration = -1.0f; WriteFloat(rootElem, "duration", duration); WriteInt(rootElem, "emitterType", (int)emitterType_); WriteFloat(rootElem, "maxRadius", maxRadius_); WriteFloat(rootElem, "maxRadiusVariance", maxRadiusVariance_); WriteFloat(rootElem, "minRadius", minRadius_); WriteFloat(rootElem, "minRadiusVariance", minRadiusVariance_); WriteFloat(rootElem, "rotatePerSecond", rotatePerSecond_); WriteFloat(rootElem, "rotatePerSecondVariance", rotatePerSecondVariance_); WriteInt(rootElem, "blendFuncSource", srcBlendFuncs[blendMode_]); WriteInt(rootElem, "blendFuncDestination", destBlendFuncs[blendMode_]); WriteFloat(rootElem, "rotationStart", rotationStart_); WriteFloat(rootElem, "rotationStartVariance", rotationStartVariance_); WriteFloat(rootElem, "rotationEnd", rotationEnd_); WriteFloat(rootElem, "rotationEndVariance", rotationEndVariance_); return xmlFile.Save(dest); }
void Script::DumpAPI(DumpMode mode, const String& sourceTree) { // Does not use LOGRAW macro here to ensure the messages are always dumped regardless of CLOCKWORK_LOGGING compiler directive // and of Log subsystem availability // Dump event descriptions and attribute definitions in Doxygen mode. For events, this means going through the header files, // as the information is not available otherwise. /// \todo Dump events + attributes before the actual script API because the remarks (readonly / writeonly) seem to throw off // Doxygen parsing and the following page definition(s) may not be properly recognized if (mode == DOXYGEN) { Log::WriteRaw("namespace Clockwork\n{\n\n/**\n"); FileSystem* fileSystem = GetSubsystem<FileSystem>(); Vector<String> headerFileNames; String path = AddTrailingSlash(sourceTree); if (!path.Empty()) path.Append("Source/Clockwork/"); fileSystem->ScanDir(headerFileNames, path, "*.h", SCAN_FILES, true); /// \hack Rename any Events2D to 2DEvents to work with the event category creation correctly (currently PhysicsEvents2D) Vector<HeaderFile> headerFiles; for (unsigned i = 0; i < headerFileNames.Size(); ++i) { HeaderFile entry; entry.fileName = headerFileNames[i]; entry.sectionName = GetFileNameAndExtension(entry.fileName).Replaced("Events2D", "2DEvents"); if (entry.sectionName.EndsWith("Events.h")) headerFiles.Push(entry); } if (!headerFiles.Empty()) { Log::WriteRaw("\n\\page EventList Event list\n"); Sort(headerFiles.Begin(), headerFiles.End(), CompareHeaderFiles); for (unsigned i = 0; i < headerFiles.Size(); ++i) { SharedPtr<File> file(new File(context_, path + headerFiles[i].fileName, FILE_READ)); if (!file->IsOpen()) continue; const String& sectionName = headerFiles[i].sectionName; unsigned start = sectionName.Find('/') + 1; unsigned end = sectionName.Find("Events.h"); Log::WriteRaw("\n## %" + sectionName.Substring(start, end - start) + " events\n"); while (!file->IsEof()) { String line = file->ReadLine(); if (line.StartsWith("EVENT")) { Vector<String> parts = line.Split(','); if (parts.Size() == 2) Log::WriteRaw("\n### " + parts[1].Substring(0, parts[1].Length() - 1).Trimmed() + "\n"); } if (line.Contains("PARAM")) { Vector<String> parts = line.Split(','); if (parts.Size() == 2) { String paramName = parts[1].Substring(0, parts[1].Find(')')).Trimmed(); String paramType = parts[1].Substring(parts[1].Find("// ") + 3); if (!paramName.Empty() && !paramType.Empty()) Log::WriteRaw("- %" + paramName + " : " + paramType + "\n"); } } } } Log::WriteRaw("\n"); } Log::WriteRaw("\n\\page AttributeList Attribute list\n"); const HashMap<StringHash, Vector<AttributeInfo> >& attributes = context_->GetAllAttributes(); Vector<String> objectTypes; for (HashMap<StringHash, Vector<AttributeInfo> >::ConstIterator i = attributes.Begin(); i != attributes.End(); ++i) objectTypes.Push(context_->GetTypeName(i->first_)); Sort(objectTypes.Begin(), objectTypes.End()); for (unsigned i = 0; i < objectTypes.Size(); ++i) { const Vector<AttributeInfo>& attrs = attributes.Find(objectTypes[i])->second_; unsigned usableAttrs = 0; for (unsigned j = 0; j < attrs.Size(); ++j) { // Attributes that are not shown in the editor are typically internal and not usable for eg. attribute // animation if (attrs[j].mode_ & AM_NOEDIT) continue; ++usableAttrs; } if (!usableAttrs) continue; Log::WriteRaw("\n### " + objectTypes[i] + "\n"); for (unsigned j = 0; j < attrs.Size(); ++j) { if (attrs[j].mode_ & AM_NOEDIT) continue; // Prepend each word in the attribute name with % to prevent unintended links Vector<String> nameParts = attrs[j].name_.Split(' '); for (unsigned k = 0; k < nameParts.Size(); ++k) { if (nameParts[k].Length() > 1 && IsAlpha((unsigned)nameParts[k][0])) nameParts[k] = "%" + nameParts[k]; } String name; name.Join(nameParts, " "); String type = Variant::GetTypeName(attrs[j].type_); // Variant typenames are all uppercase. Convert primitive types to the proper lowercase form for the documentation if (type == "Int" || type == "Bool" || type == "Float") type[0] = (char)ToLower((unsigned)type[0]); Log::WriteRaw("- " + name + " : " + type + "\n"); } } Log::WriteRaw("\n"); } if (mode == DOXYGEN) Log::WriteRaw("\n\\page ScriptAPI Scripting API\n\n"); else if (mode == C_HEADER) Log::WriteRaw( "// Script API header intended to be 'force included' in IDE for AngelScript content assist / code completion\n\n" "#define int8 signed char\n" "#define int16 signed short\n" "#define int64 long\n" "#define uint8 unsigned char\n" "#define uint16 unsigned short\n" "#define uint64 unsigned long\n" "#define null 0\n"); unsigned types = scriptEngine_->GetObjectTypeCount(); Vector<Pair<String, unsigned> > sortedTypes; for (unsigned i = 0; i < types; ++i) { asIObjectType* type = scriptEngine_->GetObjectTypeByIndex(i); if (type) { String typeName(type->GetName()); sortedTypes.Push(MakePair(typeName, i)); } } Sort(sortedTypes.Begin(), sortedTypes.End()); if (mode == DOXYGEN) { Log::WriteRaw("\\section ScriptAPI_TableOfContents Table of contents\n" "\\ref ScriptAPI_ClassList \"Class list\"<br>\n" "\\ref ScriptAPI_Classes \"Classes\"<br>\n" "\\ref ScriptAPI_Enums \"Enumerations\"<br>\n" "\\ref ScriptAPI_GlobalFunctions \"Global functions\"<br>\n" "\\ref ScriptAPI_GlobalProperties \"Global properties\"<br>\n" "\\ref ScriptAPI_GlobalConstants \"Global constants\"<br>\n\n"); Log::WriteRaw("\\section ScriptAPI_ClassList Class list\n\n"); for (unsigned i = 0; i < sortedTypes.Size(); ++i) { asIObjectType* type = scriptEngine_->GetObjectTypeByIndex(sortedTypes[i].second_); if (type) { String typeName(type->GetName()); Log::WriteRaw("<a href=\"#Class_" + typeName + "\"><b>" + typeName + "</b></a>\n"); } } Log::WriteRaw("\n\\section ScriptAPI_Classes Classes\n"); } else if (mode == C_HEADER) Log::WriteRaw("\n// Classes\n"); for (unsigned i = 0; i < sortedTypes.Size(); ++i) { asIObjectType* type = scriptEngine_->GetObjectTypeByIndex(sortedTypes[i].second_); if (type) { String typeName(type->GetName()); Vector<String> methodDeclarations; Vector<PropertyInfo> propertyInfos; if (mode == DOXYGEN) { Log::WriteRaw("<a name=\"Class_" + typeName + "\"></a>\n"); Log::WriteRaw("\n### " + typeName + "\n"); } else if (mode == C_HEADER) { ///\todo Find a cleaner way to do this instead of hardcoding if (typeName == "Array") Log::WriteRaw("\ntemplate <class T> class " + typeName + "\n{\n"); else Log::WriteRaw("\nclass " + typeName + "\n{\n"); } unsigned methods = type->GetMethodCount(); for (unsigned j = 0; j < methods; ++j) { asIScriptFunction* method = type->GetMethodByIndex(j); String methodName(method->GetName()); String declaration(method->GetDeclaration()); // Recreate tab escape sequences declaration.Replace("\t", "\\t"); if (methodName.Contains("get_") || methodName.Contains("set_")) ExtractPropertyInfo(methodName, declaration, propertyInfos); else { // Sanitate the method name. \todo For now, skip the operators if (!declaration.Contains("::op")) { String prefix(typeName + "::"); declaration.Replace(prefix, ""); ///\todo Is there a better way to mark deprecated API bindings for AngelScript? unsigned posBegin = declaration.FindLast("const String&in = \"deprecated:"); if (posBegin != String::NPOS) { // Assume this 'mark' is added as the last parameter unsigned posEnd = declaration.Find(')', posBegin); if (posEnd != String::NPOS) { declaration.Replace(posBegin, posEnd - posBegin, ""); posBegin = declaration.Find(", ", posBegin - 2); if (posBegin != String::NPOS) declaration.Replace(posBegin, 2, ""); if (mode == DOXYGEN) declaration += " // deprecated"; else if (mode == C_HEADER) declaration = "/* deprecated */\n" + declaration; } } methodDeclarations.Push(declaration); } } } // Assume that the same property is never both an accessor property, and a direct one unsigned properties = type->GetPropertyCount(); for (unsigned j = 0; j < properties; ++j) { const char* propertyName; const char* propertyDeclaration; int typeId; type->GetProperty(j, &propertyName, &typeId); propertyDeclaration = scriptEngine_->GetTypeDeclaration(typeId); PropertyInfo newInfo; newInfo.name_ = String(propertyName); newInfo.type_ = String(propertyDeclaration); newInfo.read_ = newInfo.write_ = true; propertyInfos.Push(newInfo); } Sort(methodDeclarations.Begin(), methodDeclarations.End(), ComparePropertyStrings); Sort(propertyInfos.Begin(), propertyInfos.End(), ComparePropertyInfos); if (!methodDeclarations.Empty()) { if (mode == DOXYGEN) Log::WriteRaw("\nMethods:\n\n"); else if (mode == C_HEADER) Log::WriteRaw("// Methods:\n"); for (unsigned j = 0; j < methodDeclarations.Size(); ++j) OutputAPIRow(mode, methodDeclarations[j]); } if (!propertyInfos.Empty()) { if (mode == DOXYGEN) Log::WriteRaw("\nProperties:\n\n"); else if (mode == C_HEADER) Log::WriteRaw("\n// Properties:\n"); for (unsigned j = 0; j < propertyInfos.Size(); ++j) { String remark; String cppdoc; if (!propertyInfos[j].write_) remark = "readonly"; else if (!propertyInfos[j].read_) remark = "writeonly"; if (!remark.Empty()) { if (mode == DOXYGEN) { remark = " // " + remark; } else if (mode == C_HEADER) { cppdoc = "/* " + remark + " */\n"; remark.Clear(); } } OutputAPIRow(mode, cppdoc + propertyInfos[j].type_ + " " + propertyInfos[j].name_ + remark); } } if (mode == DOXYGEN) Log::WriteRaw("\n"); else if (mode == C_HEADER) Log::WriteRaw("};\n"); } } Vector<PropertyInfo> globalPropertyInfos; Vector<String> globalFunctions; unsigned functions = scriptEngine_->GetGlobalFunctionCount(); for (unsigned i = 0; i < functions; ++i) { asIScriptFunction* function = scriptEngine_->GetGlobalFunctionByIndex(i); String functionName(function->GetName()); String declaration(function->GetDeclaration()); // Recreate tab escape sequences declaration.Replace("\t", "\\t"); if (functionName.Contains("set_") || functionName.Contains("get_")) ExtractPropertyInfo(functionName, declaration, globalPropertyInfos); else globalFunctions.Push(declaration); } Sort(globalFunctions.Begin(), globalFunctions.End(), ComparePropertyStrings); Sort(globalPropertyInfos.Begin(), globalPropertyInfos.End(), ComparePropertyInfos); if (mode == DOXYGEN) Log::WriteRaw("\\section ScriptAPI_Enums Enumerations\n"); else if (mode == C_HEADER) Log::WriteRaw("\n// Enumerations\n"); unsigned enums = scriptEngine_->GetEnumCount(); Vector<Pair<String, unsigned> > sortedEnums; for (unsigned i = 0; i < enums; ++i) { int typeId; sortedEnums.Push(MakePair(String(scriptEngine_->GetEnumByIndex(i, &typeId)), i)); } Sort(sortedEnums.Begin(), sortedEnums.End()); for (unsigned i = 0; i < sortedEnums.Size(); ++i) { int typeId = 0; if (mode == DOXYGEN) Log::WriteRaw("\n### " + String(scriptEngine_->GetEnumByIndex(sortedEnums[i].second_, &typeId)) + "\n\n"); else if (mode == C_HEADER) Log::WriteRaw("\nenum " + String(scriptEngine_->GetEnumByIndex(sortedEnums[i].second_, &typeId)) + "\n{\n"); for (unsigned j = 0; j < (unsigned)scriptEngine_->GetEnumValueCount(typeId); ++j) { int value = 0; const char* name = scriptEngine_->GetEnumValueByIndex(typeId, j, &value); OutputAPIRow(mode, String(name), false, ","); } if (mode == DOXYGEN) Log::WriteRaw("\n"); else if (mode == C_HEADER) Log::WriteRaw("};\n"); } if (mode == DOXYGEN) Log::WriteRaw("\\section ScriptAPI_GlobalFunctions Global functions\n"); else if (mode == C_HEADER) Log::WriteRaw("\n// Global functions\n"); for (unsigned i = 0; i < globalFunctions.Size(); ++i) OutputAPIRow(mode, globalFunctions[i]); if (mode == DOXYGEN) Log::WriteRaw("\\section ScriptAPI_GlobalProperties Global properties\n"); else if (mode == C_HEADER) Log::WriteRaw("\n// Global properties\n"); for (unsigned i = 0; i < globalPropertyInfos.Size(); ++i) OutputAPIRow(mode, globalPropertyInfos[i].type_ + " " + globalPropertyInfos[i].name_, true); if (mode == DOXYGEN) Log::WriteRaw("\\section ScriptAPI_GlobalConstants Global constants\n"); else if (mode == C_HEADER) Log::WriteRaw("\n// Global constants\n"); Vector<String> globalConstants; unsigned properties = scriptEngine_->GetGlobalPropertyCount(); for (unsigned i = 0; i < properties; ++i) { const char* propertyName; const char* propertyDeclaration; int typeId; scriptEngine_->GetGlobalPropertyByIndex(i, &propertyName, 0, &typeId); propertyDeclaration = scriptEngine_->GetTypeDeclaration(typeId); String type(propertyDeclaration); globalConstants.Push(type + " " + String(propertyName)); } Sort(globalConstants.Begin(), globalConstants.End(), ComparePropertyStrings); for (unsigned i = 0; i < globalConstants.Size(); ++i) OutputAPIRow(mode, globalConstants[i], true); if (mode == DOXYGEN) Log::WriteRaw("*/\n\n}\n"); }