Example #1
0
void PixInsightX11Installer::CopyFiles( const String& targetDir, const String& sourceDir )
{
   if ( !targetDir.BeginsWith( '/' ) )
      throw Error( "CopyFiles(): Relative target directory." );
   if ( !sourceDir.BeginsWith( '/' ) )
      throw Error( "CopyFiles(): Relative source directory." );
   if ( targetDir.EndsWith( '/' ) || sourceDir.EndsWith( '/' ) )
      throw Error( "CopyFiles(): Incorrectly terminated directories." );
   if ( !File::DirectoryExists( targetDir ) )
      throw Error( "CopyFiles(): Nonexistent target directory." );
   if ( !File::DirectoryExists( sourceDir ) )
      throw Error( "CopyFiles(): Nonexistent source directory." );

   StringList sourceItems = SearchDirectory( sourceDir );

   size_type sourceDirLen = sourceDir.Length();
   for ( StringList::const_iterator i = sourceItems.Begin(); i != sourceItems.End(); ++i )
   {
      String relSourcePath = *i;
      relSourcePath.DeleteLeft( sourceDirLen );

      String targetPath = targetDir + relSourcePath;
      if ( targetPath.EndsWith( '/' ) )
      {
         /*
          * Create a subdirectory
          */
         targetPath.Delete( targetPath.UpperBound() );
         if ( !File::DirectoryExists( targetPath ) )
         {
            File::CreateDirectory( targetPath );
            String sourcePath = *i;
            sourcePath.Delete( sourcePath.UpperBound() );
            File::CopyTimesAndPermissions( targetPath, sourcePath );
         }
      }
      else
      {
         /*
          * Copy a file
          */
         /*
          * ### N.B. We don't have to create subdirectories here becase they
          * have been reported by SearchDirectory(), and we are creating them
          * before copying files. SearchDirectory() promises that all
          * subdirectories are reported before their contained files.
          */
         /*
         String targetSubdir = File::ExtractDirectory( targetPath );
         if ( targetSubdir.EndsWith( '/' ) )
            targetSubdir.Delete( targetSubdir.UpperBound() );
         if ( !File::DirectoryExists( targetSubdir ) )
            File::CreateDirectory( targetSubdir );
         */
         File::CopyFile( targetPath, *i );
      }
   }
}
bool ResourceOps::CheckCreate2DLevel(const String& resourcePath, const String& resourceName, bool reportError)
{

    Editor* editor = GetSubsystem<Editor>();
    Project* project = editor->GetProject();

    String fullpath = resourcePath + resourceName;
    if (!resourceName.EndsWith(".tmx"))
        fullpath += ".tmx";

    FileSystem* fs = GetSubsystem<FileSystem>();

    if (fs->FileExists(fullpath))
    {
        if (reportError)
        {
            String errorMsg;
            errorMsg.AppendWithFormat("The level:\n\n%s\n\nalready exists", fullpath.CString());
            editor->PostModalError("Create 2D Level Error", errorMsg);
        }

        return false;
    }

    return true;

}
Example #3
0
void PixInsightX11Installer::DirectorySearch_Recursive( StringList& foundItems, const String& dirPath, const String& baseDir )
{
   if ( dirPath.Has( ".." ) )
      throw Error( "SearchDirectory(): Attempt to redirect outside the base directory." );
   if ( !dirPath.BeginsWith( baseDir ) )
      throw Error( "SearchDirectory(): Attempt to redirect outside the base directory." );
   if ( !File::DirectoryExists( dirPath ) )
      throw Error( "SearchDirectory(): Attempt to search a nonexistent directory." );

   String currentDir = dirPath;
   if ( !currentDir.EndsWith( '/' ) )
      currentDir += '/';

   StringList directories;
   FindFileInfo info;
   for ( File::Find f( currentDir + "*" ); f.NextItem( info ); )
      if ( info.IsDirectory() )
      {
         if ( info.name != "." && info.name != ".." )
         {
            directories.Add( info.name );
            foundItems.Add( currentDir + info.name + '/' );
         }
      }
      else
         foundItems.Add( currentDir + info.name );

   for ( StringList::const_iterator i = directories.Begin(); i != directories.End(); ++i )
      DirectorySearch_Recursive( foundItems, currentDir + *i, baseDir );
}
Example #4
0
   String 
   FileUtilities::Combine(const String &path1, const String &path2)
   {
      String firstHalf = path1;
      String secondHalf = path2;

      if (firstHalf.EndsWith(_T("\\")) || firstHalf.EndsWith(_T("/")))
         firstHalf = firstHalf.Mid(0, firstHalf.GetLength() -1);

      if (secondHalf.StartsWith(_T("\\")) || secondHalf.StartsWith(_T("/")))
         secondHalf = secondHalf.Mid(1);

      String result = firstHalf + "\\" + secondHalf;

      return result;
   }
Example #5
0
void PixInsightX11Installer::RemoveDirectory_Recursive( const String& dirPath, const String& baseDir )
{
   if ( dirPath.Has( ".." ) )
      throw Error( "RemoveDirectory(): Attempt to climb up the filesystem." );
   if ( !dirPath.BeginsWith( baseDir ) )
      throw Error( "RemoveDirectory(): Attempt to redirect outside the base directory." );
   if ( !File::DirectoryExists( dirPath ) )
      throw Error( "RemoveDirectory(): Attempt to remove a nonexistent directory." );

   String currentDir = dirPath;
   if ( !currentDir.EndsWith( '/' ) )
      currentDir += '/';

   FindFileInfo info;
   for ( File::Find f( currentDir + "*" ); f.NextItem( info ); )
   {
      String itemPath = currentDir + info.name;
      if ( info.IsDirectory() )
      {
         if ( info.name != "." && info.name != ".." )
         {
            RemoveDirectory_Recursive( itemPath, baseDir );
            File::RemoveDirectory( itemPath );
         }
      }
      else
      {
         File::Remove( itemPath );
      }
   }
}
Example #6
0
String PixInsightX11Installer::Unquoted( const String& s )
{
   String r = s;
   if ( s.BeginsWith( '\"' ) )
      if ( s.EndsWith( '\"' ) )
      {
         r.DeleteRight( r.UpperBound() );
         r.DeleteLeft( 1 );
      }
   if ( s.BeginsWith( '\'' ) )
      if ( s.EndsWith( '\'' ) )
      {
         r.DeleteRight( r.UpperBound() );
         r.DeleteLeft( 1 );
      }
   return r;
}
Example #7
0
StringList PixInsightX11Installer::SearchDirectory( const String& dirPath )
{
   if ( !dirPath.BeginsWith( '/' ) )
      throw Error( "SearchDirectory(): Relative search directory." );
   if ( dirPath.EndsWith( '/' ) )
      throw Error( "SearchDirectory(): Incorrectly terminated directory." );

   StringList foundItems;
   DirectorySearch_Recursive( foundItems, dirPath, dirPath );
   return foundItems;
}
void BuildBase::ScanResourceDirectory(const String& resourceDir)
{
    Vector<String> fileNames;
    FileSystem* fileSystem = GetSubsystem<FileSystem>();
    fileSystem->ScanDir(fileNames, resourceDir, "*.*", SCAN_FILES, true);

    for (unsigned i = 0; i < fileNames.Size(); i++)
    {
        const String& filename = fileNames[i];

        for (unsigned j = 0; j < resourceEntries_.Size(); j++)
        {
            const BuildResourceEntry* entry = resourceEntries_[j];

            if (entry->packagePath_ == filename)
            {
                BuildWarn(ToString("Resource Path: %s already exists", filename.CString()));
                continue;
            }
        }

        // TODO: Add additional filters
        if (GetExtension(filename) == ".psd")
            continue;

        BuildResourceEntry* newEntry = new BuildResourceEntry;

// BEGIN LICENSE MANAGEMENT
        if (GetExtension(filename) == ".mdl")
        {
            containsMDL_ = true;
        }
// END LICENSE MANAGEMENT

        newEntry->absolutePath_ = resourceDir + filename;
        newEntry->resourceDir_ = resourceDir;

        if (resourceDir.EndsWith("/Cache/"))
            newEntry->packagePath_ = "Cache/" + filename;
        else
            newEntry->packagePath_ = filename;

        resourceEntries_.Push(newEntry);

        //LOGINFOF("Adding resource: %s : %s", newEntry->absolutePath_.CString(), newEntry->packagePath_.CString());
    }
}
bool ResourceOps::CheckCreateScript(const String& resourcePath, const String& resourceName, bool reportError)
{

    Editor* editor = GetSubsystem<Editor>();
    Project* project = editor->GetProject();

    String fullpath = resourcePath + resourceName;
    if (!resourceName.EndsWith(".js"))
        fullpath += ".js";

    FileSystem* fs = GetSubsystem<FileSystem>();

    if (fs->FileExists(fullpath))
    {
        if (reportError)
        {
            String errorMsg;
            errorMsg.AppendWithFormat("The script:\n\n%s\n\nalready exists", fullpath.CString());
            editor->PostModalError("Create Script Error", errorMsg);
        }

        return false;
    }

    if (!project->IsScriptsDirOrFile(resourcePath))
    {
        if (reportError)
        {
            String errorMsg;
            errorMsg.AppendWithFormat("Scripts must reside in or in a subfolder of the Scripts folder");
            editor->PostModalError("Create Script Error", errorMsg);
        }

        return false;
    }

    return true;

}
Example #10
0
void ResourceOps::HandleCreate2DLevel(const String& resourcePath, const String& resourceName,
                                        bool navigateToResource, bool reportError)
{
    Editor* editor = GetSubsystem<Editor>();

    if (!CheckCreate2DLevel(resourcePath, resourceName, reportError))
        return;

    ResourceCache* cache = GetSubsystem<ResourceCache>();

    SharedPtr<File> srcFile = cache->GetFile("ClockworkEditor/templates/template_empty.tmx");
    if (srcFile.Null() || !srcFile->IsOpen())
    {
        editor->PostModalError("Create Script Error", "Could not open module template");
        return;
    }

    String fullpath = resourcePath + resourceName;
    if (!resourceName.EndsWith(".tmx"))
        fullpath += ".tmx";

    if (!CopyFile(srcFile, fullpath))
    {
        String errorMsg;
        errorMsg.AppendWithFormat("Error copying template:\n\n%s\n\nto:\n\n%s",
                                  "ClockworkEditor/template_empty.tmx", fullpath.CString());
        editor->PostModalError("Create 2D Level Error", errorMsg);
        return;
    }

    if (navigateToResource)
    {
        //ResourceFrame* rframe = GetSubsystem<MainFrame>()->GetResourceFrame();
        //rframe->EditResource(fullpath);
    }

    GetSubsystem<MainFrame>()->GetProjectFrame()->Refresh();

}
Example #11
0
bool JSVM::ExecuteScript(const String& scriptPath)
{
    String path = scriptPath;
    if (!path.StartsWith("Scripts/"))
        path = "Scripts/" + path;

    if (!path.EndsWith(".js"))
        path += ".js";

    SharedPtr<File> file (GetSubsystem<ResourceCache>()->GetFile(path));

    if (file.Null())
    {
        return false;
    }

    String source;

    file->ReadText(source);
    source.Append('\n');

    duk_push_string(ctx_, file->GetFullPath().CString());
    if (duk_eval_raw(ctx_, source.CString(), 0,
                     DUK_COMPILE_EVAL | DUK_COMPILE_SAFE | DUK_COMPILE_NOSOURCE | DUK_COMPILE_STRLEN) != 0)
    {
        if (duk_is_object(ctx_, -1))
            SendJSErrorEvent(path);

        duk_pop(ctx_);
        return false;
    }

    duk_pop(ctx_);

    return true;
}
Example #12
0
void PropertyWindow::SetProperty()
{
	if(property->GetOption().second!=-1 && textField->GetText().length() > 0)
	{
		String value = textField->GetText();
		try {
			switch(properties[property->GetOption().second].Type)
			{
				case StructProperty::Integer:
				case StructProperty::ParticleType:
				{
					int v;
					if(value.length() > 2 && value.BeginsWith("0x"))
					{
						//0xC0FFEE
						v = value.Substr(2).ToNumber<unsigned int>(Format::Hex());
					}
					else if(value.length() > 1 && value.BeginsWith("#"))
					{
						//#C0FFEE
						v = value.Substr(1).ToNumber<unsigned int>(Format::Hex());
					}
					else
					{
						int type;
						if ((type = sim->GetParticleType(value.ToUtf8())) != -1)
						{
							v = type;

#ifdef DEBUG
							std::cout << "Got type from particle name" << std::endl;
#endif
						}
						else
						{
							v = value.ToNumber<int>();
						}
					}

					if (properties[property->GetOption().second].Name == "type" && (v < 0 || v >= PT_NUM || !sim->elements[v].Enabled))
					{
						new ErrorMessage("Could not set property", "Invalid particle type");
						return;
					}

#ifdef DEBUG
					std::cout << "Got int value " << v << std::endl;
#endif

					tool->propValue.Integer = v;
					break;
				}
				case StructProperty::UInteger:
				{
					unsigned int v;
					if(value.length() > 2 && value.BeginsWith("0x"))
					{
						//0xC0FFEE
						v = value.Substr(2).ToNumber<unsigned int>(Format::Hex());
					}
					else if(value.length() > 1 && value.BeginsWith("#"))
					{
						//#C0FFEE
						v = value.Substr(1).ToNumber<unsigned int>(Format::Hex());
					}
					else
					{
						v = value.ToNumber<unsigned int>();
					}
#ifdef DEBUG
					std::cout << "Got uint value " << v << std::endl;
#endif
					tool->propValue.UInteger = v;
					break;
				}
				case StructProperty::Float:
				{
					if (value.EndsWith("C"))
					{
						float v = value.SubstrFromEnd(1).ToNumber<float>();
						tool->propValue.Float = v + 273.15;
					}
					else if(value.EndsWith("F"))
					{
						float v = value.SubstrFromEnd(1).ToNumber<float>();
						tool->propValue.Float = (v-32.0f)*5/9+273.15f;
					}
					else
					{
						tool->propValue.Float = value.ToNumber<float>();
					}
#ifdef DEBUG
					std::cout << "Got float value " << tool->propValue.Float << std::endl;
#endif
				}
					break;
				default:
					new ErrorMessage("Could not set property", "Invalid property");
					return;
			}
			tool->propOffset = properties[property->GetOption().second].Offset;
			tool->propType = properties[property->GetOption().second].Type;
		} catch (const std::exception& ex) {
			new ErrorMessage("Could not set property", "Invalid value provided");
			return;
		}
		Client::Ref().SetPref("Prop.Type", property->GetOption().second);
		Client::Ref().SetPrefUnicode("Prop.Value", textField->GetText());
	}
}
	bool PluginManager::Mount(const String& pluginPath, bool appendExtension)
	{
		if (!Initialize())
		{
			NazaraError("Failed to initialize PluginManager");
			return false;
		}

		String path = pluginPath;
		if (appendExtension && !path.EndsWith(NAZARA_DYNLIB_EXTENSION))
			path += NAZARA_DYNLIB_EXTENSION;

		bool exists = false;
		if (!File::IsAbsolute(path))
		{
			for (const String& dir : s_directories)
			{
				String testPath;
				testPath.Reserve(dir.GetSize() + path.GetSize() + 10);

				testPath = dir;
				testPath += NAZARA_DIRECTORY_SEPARATOR;
				testPath += path;

				if (File::Exists(testPath))
				{
					path = testPath;
					exists = true;
					break;
				}
			}
		}
		else if (File::Exists(path))
			exists = true;

		if (!exists)
		{
			NazaraError("Failed to find plugin file");
			return false;
		}

		std::unique_ptr<DynLib> library(new DynLib);
		if (!library->Load(path))
		{
			NazaraError("Failed to load plugin");
			return false;
		}

		PluginLoad func = reinterpret_cast<PluginLoad>(library->GetSymbol("PluginLoad"));
		if (!func)
		{
			NazaraError("Failed to get symbol PluginLoad");
			return false;
		}

		if (!func())
		{
			NazaraError("Plugin failed to load");
			return false;
		}

		s_plugins[pluginPath] = library.release();

		return true;
	}
/* This function takes a file name and normalizes
 * all the directory names included in the path by
 * removing spaces and dots at the end. It also
 * shortens each directory and the file name to a
 * maximum of 248 or 96 characters.
 */
String BonkEnc::Utilities::NormalizeFileName(const String &fileName)
{
	Int	 maxLength = 248;

	/* Set smaller maximum path component length on old systems.
	 */
#ifdef __WIN32__
	OSVERSIONINFOA	 vInfo;

	vInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);

	GetVersionExA(&vInfo);

	if (vInfo.dwPlatformId != VER_PLATFORM_WIN32_NT) maxLength = 96;
#endif

	String	 rFileName = fileName;
	String	 dir = fileName;
	String	 tmpDir;
	Int	 lastBS = 0;

	for (Int i = 0; i < dir.Length(); i++)
	{
		if (dir[i] == '\\' || dir[i] == '/')
		{
			String	 tmpDir2 = tmpDir;

			/* Shorten to at most maxLength characters.
			 */
			if (tmpDir.Length() - lastBS > maxLength)
			{
				tmpDir2 = String().CopyN(tmpDir, lastBS + maxLength);

				i -= (tmpDir.Length() - lastBS - maxLength);
			}

			/* Replace trailing dots and spaces.
			 */
			while (tmpDir2.EndsWith(".") || tmpDir2.EndsWith(" ")) { tmpDir2[tmpDir2.Length() - 1] = 0; i--; }

			if (tmpDir2 != tmpDir)
			{
				rFileName.Replace(tmpDir, tmpDir2);

				tmpDir = tmpDir2;
				dir = rFileName;
			}

			lastBS = i;
		}

		tmpDir[i] = dir[i];
	}

	/* Shorten file name to maxLength characters.
	 */
	if (rFileName.Length() - lastBS > maxLength) rFileName = String().CopyN(rFileName, lastBS + maxLength);

	/* Replace trailing spaces.
	 */
	while (rFileName.EndsWith(" ")) { rFileName[rFileName.Length() - 1] = 0; }

	return rFileName;
}
BonkEnc::InputFilter *BonkEnc::Utilities::CreateInputFilter(const String &iFile, Track *trackInfo)
{
	Array<String>	 extensions;
	Array<Int>	 indexes;

	String		 file = iFile.ToLower();

	for (Int i = 0; i < DLLInterfaces::winamp_in_plugins.Length(); i++)
	{
		Int	 n = 1;
		Int	 k = 0;
		String	 extension;

		for (Int j = 0; true; j++)
		{
			if (!(n & 1))
			{
				if (DLLInterfaces::winamp_in_modules.GetNth(i)->FileExtensions[j] == 0) n++;
			}
			else
			{
				extension[k++] = DLLInterfaces::winamp_in_modules.GetNth(i)->FileExtensions[j];

				if (DLLInterfaces::winamp_in_modules.GetNth(i)->FileExtensions[j] == 0)
				{
					String	 extension2 = extension;
					Int	 o = 0;		

					for (Int m = 0; m <= extension2.Length(); m++)
					{
						if (extension2[m] == ';' || extension2[m] == 0)
						{
							extension[m - o] = 0;

							extensions.Add(extension);
							indexes.Add(i);

							o = m + 1;
						}
						else
						{
							extension[m - o] = tolower(extension2[m]);
						}
					}

					k = 0;
					n++;
					extension = "";
				}
			}

			if (DLLInterfaces::winamp_in_modules.GetNth(i)->FileExtensions[j] == 0 && DLLInterfaces::winamp_in_modules.GetNth(i)->FileExtensions[j + 1] == 0) break;
		}
	}

	Int	 found = -1;

	for (Int j = 0; j < extensions.Length(); j++)
	{
		if (file.EndsWith(extensions.GetNth(j)))
		{
			found = j;

			break;
		}
	}

	InputFilter	*filter_in = NIL;

	if ((file.StartsWith("/cda") || file.EndsWith(".cda")) && BonkEnc::currentConfig->enable_cdrip && BonkEnc::currentConfig->cdrip_numdrives >= 1)
	{
		filter_in = new FilterInCDRip(BonkEnc::currentConfig, trackInfo);
	}
	else if ((file.EndsWith(".mp1") || file.EndsWith(".mp2") || file.EndsWith(".mp3")) && BonkEnc::currentConfig->enable_mad)
	{
		filter_in = new FilterInMAD(BonkEnc::currentConfig, trackInfo);
	}
	else if ((file.EndsWith(".mp4") || file.EndsWith(".m4a") || file.EndsWith(".m4b")) && BonkEnc::currentConfig->enable_mp4 && BonkEnc::currentConfig->enable_faad2)
	{
		filter_in = new FilterInMP4(BonkEnc::currentConfig, trackInfo);
	}
	else if (file.EndsWith(".ogg") && BonkEnc::currentConfig->enable_vorbis)
	{
		filter_in = new FilterInVORBIS(BonkEnc::currentConfig, trackInfo);
	}
	else if (file.EndsWith(".aac") && BonkEnc::currentConfig->enable_faad2)
	{
		filter_in = new FilterInFAAD2(BonkEnc::currentConfig, trackInfo);
	}
	else if (file.EndsWith(".bonk") && BonkEnc::currentConfig->enable_bonk)
	{
		filter_in = new FilterInBONK(BonkEnc::currentConfig, trackInfo);
	}
	else if (file.EndsWith(".flac") && BonkEnc::currentConfig->enable_flac)
	{
		filter_in = new FilterInFLAC(BonkEnc::currentConfig, trackInfo);
	}
	else if (file.EndsWith(".wma") && BonkEnc::currentConfig->enable_wma)
	{
		filter_in = new FilterInWMA(BonkEnc::currentConfig, trackInfo);
	}
	else if (found != -1)
	{
		filter_in = new FilterInWinamp(BonkEnc::currentConfig, trackInfo, DLLInterfaces::winamp_in_modules.GetNth(indexes.GetNth(found)));
	}
	else
	{
		InStream	*f_in = new InStream(STREAM_FILE, file, IS_READONLY);
		Int		 magic = f_in->InputNumber(4);

		delete f_in;

		switch (magic)
		{
			case 1297239878:
				filter_in = new FilterInAIFF(BonkEnc::currentConfig, trackInfo);
				break;
			case 1684960046:
				filter_in = new FilterInAU(BonkEnc::currentConfig, trackInfo);
				break;
			case 1634038339:
				filter_in = new FilterInVOC(BonkEnc::currentConfig, trackInfo);
				break;
			case 1179011410:
				filter_in = new FilterInWAVE(BonkEnc::currentConfig, trackInfo);
				break;
		}
	}

	return filter_in;
}
Example #16
0
int JSVM::GetRealLineNumber(const String& fileName, const int lineNumber) {

    int realLineNumber = lineNumber;

    String mapPath = fileName;

    if (!mapPath.EndsWith(".js.map"))
        mapPath += ".js.map";

    if (mapPath.EndsWith(".js")) {
        return realLineNumber;
    }

    ResourceCache* cache = GetSubsystem<ResourceCache>();

    String path;
    const Vector<String>& searchPaths = GetModuleSearchPaths();
    for (unsigned i = 0; i < searchPaths.Size(); i++)
    {
        String checkPath = searchPaths[i] + mapPath;

        if (cache->Exists(checkPath))
        {
            path = checkPath;
            break;
        }

    }

    if (!path.Length())
        return realLineNumber;


    SharedPtr<File> mapFile(GetSubsystem<ResourceCache>()->GetFile(path));

    //if there's no source map file, maybe you use a pure js, so give an error, or maybe forgot to generate source-maps :(
    if (mapFile.Null())
    {
        return realLineNumber;
    }

    String map;
    mapFile->ReadText(map);
    int top = duk_get_top(ctx_);
    duk_get_global_string(ctx_, "require");
    duk_push_string(ctx_, "AtomicEditor/JavaScript/Lib/jsutils");
    if (duk_pcall(ctx_, 1))
    {
        printf("Error: %s\n", duk_safe_to_string(ctx_, -1));
        duk_set_top(ctx_, top);
        return false;
    }

    duk_get_prop_string(ctx_, -1, "getRealLineNumber");
    duk_push_string(ctx_, map.CString());
    duk_push_int(ctx_, lineNumber);
    bool ok = true;
    if (duk_pcall(ctx_, 2))
    {
        ok = false;
        printf("Error: %s\n", duk_safe_to_string(ctx_, -1));
    }
    else
    {
        realLineNumber = duk_to_int(ctx_, -1);
    }
    duk_set_top(ctx_, top);

    return realLineNumber;
}
Example #17
0
void ScriptInstance::GetScriptAttributes()
{
    asIScriptEngine* engine = GetSubsystem<Script>()->GetScriptEngine();
    attributeInfos_ = *context_->GetAttributes(GetTypeStatic());

    unsigned numProperties = scriptObject_->GetPropertyCount();
    for (unsigned i = 0; i < numProperties; ++i)
    {
        const char* name;
        int typeId;
        bool isPrivate, isHandle;

        scriptObject_->GetObjectType()->GetProperty(i, &name, &typeId, &isPrivate);

        // Hide private variables or ones that begin with an underscore
        if (isPrivate || name[0] == '_')
            continue;

        String typeName = engine->GetTypeDeclaration(typeId);
        isHandle = typeName.EndsWith("@");
        if (isHandle)
            typeName = typeName.Substring(0, typeName.Length() - 1);

        AttributeInfo info;
        info.mode_ = AM_FILE;
        info.name_ = name;
        info.ptr_ = scriptObject_->GetAddressOfProperty(i);

        if (!isHandle)
        {
            switch (typeId)
            {
            case asTYPEID_BOOL:
                info.type_ = VAR_BOOL;
                break;

            case asTYPEID_INT32:
            case asTYPEID_UINT32:
                info.type_ = VAR_INT;
                break;

            case asTYPEID_FLOAT:
                info.type_ = VAR_FLOAT;
                break;

            default:
                info.type_ = Variant::GetTypeFromName(typeName);
                break;
            }
        }
        else
        {
            // For a handle type, check if it's an Object subclass with a registered factory
            StringHash typeHash(typeName);
            const HashMap<StringHash, SharedPtr<ObjectFactory> >& factories = context_->GetObjectFactories();
            HashMap<StringHash, SharedPtr<ObjectFactory> >::ConstIterator j = factories.Find(typeHash);
            if (j != factories.End())
            {
                // Check base class type. Node & Component are supported as ID attributes, Resource as a resource reference
                StringHash baseType = j->second_->GetBaseType();
                if (baseType == Node::GetTypeStatic())
                {
                    info.mode_ |= AM_NODEID;
                    info.type_ = VAR_INT;
                }
                else if (baseType == Component::GetTypeStatic())
                {
                    info.mode_ |= AM_COMPONENTID;
                    info.type_ = VAR_INT;
                }
                else if (baseType == Resource::GetTypeStatic())
                {
                    info.type_ = VAR_RESOURCEREF;
                    info.defaultValue_ = ResourceRef(typeHash);
                }
            }
        }

        if (info.type_ != VAR_NONE)
            attributeInfos_.Push(info);
    }
}