void Asset::UpdateFileTimestamp() { FileSystem* fs = GetSubsystem<FileSystem>(); if (fs->FileExists(path_)) { fileTimestamp_ = fs->GetLastModifiedTime(path_); } }
bool Shader::ProcessSource(String& code, Deserializer& source) { ResourceCache* cache = GetSubsystem<ResourceCache>(); // If the source if a non-packaged file, store the timestamp File* file = dynamic_cast<File*>(&source); if (file && !file->IsPackaged()) { FileSystem* fileSystem = GetSubsystem<FileSystem>(); String fullName = cache->GetResourceFileName(file->GetName()); unsigned fileTimeStamp = fileSystem->GetLastModifiedTime(fullName); if (fileTimeStamp > timeStamp_) timeStamp_ = fileTimeStamp; } // Store resource dependencies for includes so that we know to reload if any of them changes if (source.GetName() != GetName()) cache->StoreResourceDependency(this, source.GetName()); while (!source.IsEof()) { String line = source.ReadLine(); if (line.StartsWith("#include")) { String includeFileName = GetPath(source.GetName()) + line.Substring(9).Replaced("\"", "").Trimmed(); SharedPtr<File> includeFile = cache->GetFile(includeFileName); if (!includeFile) return false; // Add the include file into the current code recursively if (!ProcessSource(code, *includeFile)) return false; } else { code += line; code += "\n"; } } // Finally insert an empty line to mark the space between files code += "\n"; return true; }
void AssetDatabase::HandleFileChanged(StringHash eventType, VariantMap& eventData) { using namespace FileChanged; const String& fullPath = eventData[P_FILENAME].GetString(); FileSystem* fs = GetSubsystem<FileSystem>(); String pathName, fileName, ext; SplitPath(fullPath, pathName, fileName, ext); // ignore changes in the Cache resource dir if (fullPath == GetCachePath() || pathName.StartsWith(GetCachePath())) return; // don't care about directories and asset file changes if (fs->DirExists(fullPath) || ext == ".asset") return; Asset* asset = GetAssetByPath(fullPath); if (!asset && fs->FileExists(fullPath)) { Scan(); return; } if (asset) { if(!fs->Exists(fullPath)) { DeleteAsset(asset); } else { if (asset->GetFileTimestamp() != fs->GetLastModifiedTime(asset->GetPath())) { asset->SetDirty(true); Scan(); } } } }
void LicenseSystem::RequestServerVerification(const String& key) { if (serverVerification_.NotNull()) { ATOMIC_LOGERROR("LicenseSystem::RequestServerLicense - request already exists"); return; } FileSystem* fileSystem = GetSubsystem<FileSystem>(); if (fileSystem->FileExists(licenseCachePath_)) { Time* time = GetSubsystem<Time>(); unsigned currentTime = time->GetTimeSinceEpoch(); unsigned fileTime = fileSystem->GetLastModifiedTime(licenseCachePath_); unsigned deltaMinutes = (currentTime - fileTime)/60; if (deltaMinutes < 1) { ATOMIC_LOGINFOF("%u minutes, using cached license", deltaMinutes); SendEvent(E_LICENSE_SUCCESS); return; } } ATOMIC_LOGINFO("LicenseSystem::RequestServerLicense - requesting verification"); key_ = key; CurlManager* cm = GetSubsystem<CurlManager>(); String post; String id = GenerateMachineID(); post.AppendWithFormat("key=%s&id=%s", key.CString(), id.CString()); serverVerification_ = cm->MakeRequest("https://store.atomicgameengine.com/licenses/license_verify.php", post); SubscribeToEvent(serverVerification_, E_CURLCOMPLETE, ATOMIC_HANDLER(LicenseSystem, HandleVerification)); }
bool ShaderVariation::LoadByteCode(const String& binaryShaderName) { ResourceCache* cache = owner_->GetSubsystem<ResourceCache>(); if (!cache->Exists(binaryShaderName)) return false; FileSystem* fileSystem = owner_->GetSubsystem<FileSystem>(); unsigned sourceTimeStamp = owner_->GetTimeStamp(); // If source code is loaded from a package, its timestamp will be zero. Else check that binary is not older // than source if (sourceTimeStamp && fileSystem->GetLastModifiedTime(cache->GetResourceFileName(binaryShaderName)) < sourceTimeStamp) return false; SharedPtr<File> file = cache->GetFile(binaryShaderName); if (!file || file->ReadFileID() != "USHD") { ATOMIC_LOGERROR(binaryShaderName + " is not a valid shader bytecode file"); return false; } /// \todo Check that shader type and model match /*unsigned short shaderType = */file->ReadUShort(); /*unsigned short shaderModel = */file->ReadUShort(); unsigned numParameters = file->ReadUInt(); for (unsigned i = 0; i < numParameters; ++i) { String name = file->ReadString(); unsigned reg = file->ReadUByte(); unsigned regCount = file->ReadUByte(); ShaderParameter parameter; parameter.type_ = type_; parameter.name_ = name; parameter.register_ = reg; parameter.regCount_ = regCount; parameters_[StringHash(name)] = parameter; } unsigned numTextureUnits = file->ReadUInt(); for (unsigned i = 0; i < numTextureUnits; ++i) { /*String unitName = */file->ReadString(); unsigned reg = file->ReadUByte(); if (reg < MAX_TEXTURE_UNITS) useTextureUnit_[reg] = true; } unsigned byteCodeSize = file->ReadUInt(); if (byteCodeSize) { byteCode_.Resize(byteCodeSize); file->Read(&byteCode_[0], byteCodeSize); if (type_ == VS) ATOMIC_LOGDEBUG("Loaded cached vertex shader " + GetFullName()); else ATOMIC_LOGDEBUG("Loaded cached pixel shader " + GetFullName()); return true; } else { ATOMIC_LOGERROR(binaryShaderName + " has zero length bytecode"); return false; } }