#pragma once #include "Util/AsyncHttpQueue.h" #include "Util/ContentId.h" #include "Util/ProtectedString.h" #include "V8Tree/Instance.h" namespace RBX { class ContentProvider; extern const char* const sLuaSourceContainer; class LuaSourceContainer : public DescribedNonCreatable { public: enum RemoteSourceLoadState { NotAttemptedToLoad, Loaded, FailedToLoad }; static void loadLinkedScripts(shared_ptr cp, Instance* root, AsyncHttpQueue::ResultJob jobType, boost::function callback); static void loadLinkedScriptsForInstances(shared_ptr cp, Instances& instances, AsyncHttpQueue::ResultJob jobType, boost::function callback); static void blockingLoadLinkedScripts(ContentProvider* cp, Instance* root); static void blockingLoadLinkedScriptsForInstances(ContentProvider* cp, Instances& instances); static Reflection::RemoteEventDesc event_requestLock; LuaSourceContainer(); const ContentId& getScriptId() const; void setScriptId(const ContentId& contentId); const ProtectedString& getCachedRemoteSource() const; void setCachedRemoteSource(const ProtectedString& value); int getCachedRemoteSourceLoadState() const; void setCachedRemoteSourceLoadState(int value); Instance* getCurrentEditor() const; void setCurrentEditor(Instance* newEditor); virtual void fireSourceChanged() {}; rbx::remote_signal requestLock; rbx::remote_signal lockGrantedOrNot; protected: virtual void onScriptIdChanged() {} void processRemoteEvent(const Reflection::EventDescriptor& descriptor, const Reflection::EventArguments& args, const SystemAddress& source) override; private: struct LinkedScriptLoadData { rbx::atomic scriptCount; boost::function callbackWhenDone; shared_ptr context; AsyncHttpQueue::ResultJob jobType; boost::mutex scriptApplyResultClosuresMutex; std::vector > scriptApplyResultClosures; }; static void linkedSourceCountingVisitor(shared_ptr descendant, int* counter); static void linkedSourceLoadedHandler(weak_ptr weakScript, AsyncHttpQueue::RequestResult result, shared_ptr loadedSource, shared_ptr metadata); static void updateScriptInstancesUnderWriteLock(DataModel* dm, shared_ptr metadata); static void linkedSourceFetchingVisitor(shared_ptr descendant, shared_ptr cp, AsyncHttpQueue::ResultJob jobType, shared_ptr metadata); ContentId scriptId; ProtectedString cachedRemoteSource; RemoteSourceLoadState cachedRemoteSourceLoadState; weak_ptr currentEditor; }; }