/* * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or * its licensors. * * For complete copyright and license terms please see the LICENSE at the root of this * distribution (the "License"). All use of this software is governed by the License, * or, if provided, by the license below or the license accompanying this file. Do not * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ // Original file Copyright Crytek GMBH or its affiliates, used under license. #pragma once #include "Strings.h" #include "Pointers.h" #include "ExplorerDataProvider.h" #include "EntryList.h" #include #include #include #include namespace CharacterTool { class ExplorerFileList; using std::vector; using std::unique_ptr; struct System; struct ActionContext; struct LoaderContext { System* system; ExplorerFileList* rigList; LoaderContext() : rigList() , system() {} }; struct IEntryLoader : _i_reference_target_t { virtual ~IEntryLoader() {} virtual bool Load(EntryBase* entry, const char* filename, LoaderContext* context) = 0; virtual bool Save(EntryBase* entry, const char* filename, LoaderContext* context, string& errorString) = 0; }; struct IEntryDependencyExtractor : _i_reference_target_t { virtual ~IEntryDependencyExtractor() {} virtual void Extract(vector* paths, const EntryBase* entry) = 0; }; struct JSONLoader : IEntryLoader { bool Load(EntryBase* entry, const char* filename, LoaderContext* context) override; bool Save(EntryBase* entry, const char* filename, LoaderContext* context, string& errorString) override; }; template struct SelfLoader : IEntryLoader { bool Load(EntryBase* entry, const char* filename, LoaderContext* context) override { return ((SEntry*)entry)->content.Load(); } bool Save(EntryBase* entry, const char* filename, LoaderContext* context, string& errorString) override { return ((SEntry*)entry)->content.Save(); } }; struct ScanLoadedFile; enum FormatUsage { FORMAT_LOAD = 1 << 0, FORMAT_SAVE = 1 << 1, FORMAT_LIST = 1 << 2, FORMAT_MAIN = 1 << 3 }; struct EntryFormat { string extension; string path; int usage; _smart_ptr loader; string MakeFilename(const char* entryPath) const; EntryFormat() : usage() { } }; typedef vector EntryFormats; struct EntryType { EntryListBase* entryList; int subtree; int explorerEntryType; bool fileListenerRegistered; _smart_ptr dependencyExtractor; EntryFormats formats; EntryType() : subtree(0) , explorerEntryType(0) , fileListenerRegistered(false) {} EntryType& AddFormat(const char* extension, IEntryLoader* loader, int usage = FORMAT_LIST | FORMAT_LOAD | FORMAT_SAVE) { EntryFormat format; format.extension = extension; format.usage = usage; format.loader.reset(loader); formats.push_back(format); return *this; } EntryType& AddFile(const char* path) { EntryFormat format; format.path = path; format.usage = FORMAT_LIST | FORMAT_LOAD | FORMAT_SAVE; formats.push_back(format); return *this; } }; class ExplorerFileList : public IExplorerEntryProvider , public IFileChangeListener , public AzFramework::LegacyAssetEventBus::MultiHandler { Q_OBJECT public: ExplorerFileList() : m_loaderContext(0) , m_explorer(0) , m_explorerColumnPak(-1) { } ~ExplorerFileList(); template EntryType& AddEntryType(int subtree, int explorerEntryType, IEntryDependencyExtractor* extractor = 0) { return AddEntryType(new CEntryList(), subtree, explorerEntryType, extractor); } template SEntry* AddSingleFile(const char* path, const char* label, int subtree, int explorerEntryType, IEntryLoader* loader) { EntryType* f = AddSingleFileEntryType(new CEntryList, path, label, subtree, explorerEntryType, loader); return ((CEntryList*)f->entryList)->AddEntry(0, path, label, false); } void SetLoaderContext(LoaderContext* loaderContext) { m_loaderContext = loaderContext; } void SetExplorer(Explorer* explorer); void SetAssetWatchType(AZ::Crc32 type); ExplorerEntryId AddEntry(const char* filename, bool resetIfExists); void AddAndSaveEntry(const char* filename, const AZStd::shared_ptr& actionOutput, AZ::SaveCompleteCallback onSaveComplete); EntryBase* GetEntryBaseByPath(const char* path); EntryBase* GetEntryBaseById(unsigned int id); template SEntry* GetEntryByPath(const char* path) { return static_cast*>(GetEntryBaseByPath(path)); } template SEntry* GetEntryById(unsigned int id) { return static_cast*>(GetEntryBaseById(id)); } void Populate(); // IExplorerDataProvider: int GetEntryCount(int subtree) const override; unsigned int GetEntryIdByIndex(int subtree, int index) const override; bool GetEntrySerializer(Serialization::SStruct* out, unsigned int id) const override; void UpdateEntry(ExplorerEntry* entry) override; void RevertEntry(unsigned int id) override; string GetSaveFilename(unsigned int id) override; void SaveEntry(const AZStd::shared_ptr& output, unsigned int id, AZ::SaveCompleteCallback onSaveComplete) override; void DeleteEntry(const AZStd::shared_ptr& output, const char * entryFullPath, const char * entryFileName) override; void SaveAll(const AZStd::shared_ptr& output, AZ::SaveCompleteCallback onSaveComplete) override; int GetEntryType(int subtreeIndex) const override; void CheckIfModified(unsigned int id, const char* reason, bool continuousChange) override; void GetEntryActions(vector* actions, unsigned int id, Explorer* explorer) override; bool HasBackgroundLoading() const override; bool LoadOrGetChangedEntry(unsigned int id) override; const char* CanonicalExtension() const override; void GetDependencies(vector* paths, unsigned int id) override; bool IsRunningAsyncSaveOperation() override; // ^^^ void OnFileChange(const char* filename, EChangeType eType) override; void OnFileChanged(AZStd::string assetPath) override; void DeleteEntries(ActionContext& x); public slots: void OnBackgroundFileLoaded(const ScanLoadedFile&); void OnBackgroundLoadingFinished(int subtree); signals: void SignalEntryDeleted(const char* path); private: string GetSaveFileExtension(const char* entryPath) const; void ActionSaveAs(ActionContext& x); void ActionDelete(ActionContext& x); string GetCanonicalPath(const char* path) const; bool CanBeSaved(const char* path) const; EntryBase* GetEntry(EntryId id, const EntryType** format = 0) const; EntryType* GetEntryTypeByExtension(const char* ext); const EntryType* GetEntryTypeByExtension(const char* ext) const; EntryType* GetEntryTypeByPath(const char* singleFile); const EntryType* GetEntryTypeByPath(const char* singleFile) const; EntryType* GetEntryTypeByExplorerEntryType(int explorerEntryType); EntryType& AddEntryType(EntryListBase* list, int subtree, int explorerEntryType, IEntryDependencyExtractor* extractor); EntryType* AddSingleFileEntryType(EntryListBase* list, const char* path, const char* label, int subtree, int explorerEntryType, IEntryLoader* loader); static int GetEntryFilesPakState(const EntryType& format, const char* filename); void UpdateEntryPakState(const ExplorerEntryId& id, int pakState); vector m_entryTypes; LoaderContext* m_loaderContext; Explorer* m_explorer; int m_explorerColumnPak; bool m_isRunningSaveAll = false; AZStd::shared_ptr m_saveRunner; }; }