diff --git a/.vscode/settings.json b/.vscode/settings.json index 55d685dc..7159b11f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -71,6 +71,7 @@ "cfenv": "cpp", "typeinfo": "cpp", "valarray": "cpp", - "variant": "cpp" + "variant": "cpp", + "filesystem": "cpp" } } \ No newline at end of file diff --git a/PopEngine.Linux/Makefile b/PopEngine.Linux/Makefile index 79d35dd0..b42c8521 100644 --- a/PopEngine.Linux/Makefile +++ b/PopEngine.Linux/Makefile @@ -136,6 +136,7 @@ LIB_LINK_LIBS = \ -lm \ -lgbm \ -ldrm \ +-ludev \ LIB_OBJECTS=$(LIB_CPP_FILES:.cpp=.o) $(LIB_C_FILES:.c=.o) APP_OBJECTS=$(APP_SRC_FILES:.cpp=.o) diff --git a/UnitTest b/UnitTest index 8df3f3b7..e9249a2f 160000 --- a/UnitTest +++ b/UnitTest @@ -1 +1 @@ -Subproject commit 8df3f3b7430ce6867e7e9e98510cb163ff0aa761 +Subproject commit e9249a2f3fc6176a96c4c7dcfe67e3f89111ceac diff --git a/src/SoyLib b/src/SoyLib index 271b75af..867fc5c8 160000 --- a/src/SoyLib +++ b/src/SoyLib @@ -1 +1 @@ -Subproject commit 271b75afb89e925c8d9f667ef0c5aedfae17051d +Subproject commit 867fc5c8c91ff4b7e2c2094b33bc90a715499729 diff --git a/src/TApiCommon.cpp b/src/TApiCommon.cpp index 72e0d530..a738b14e 100644 --- a/src/TApiCommon.cpp +++ b/src/TApiCommon.cpp @@ -69,6 +69,9 @@ namespace ApiPop static void GetPlatform(Bind::TCallback& Params); static void ShellOpen(Bind::TCallback& Params); static void ShowWebPage(Bind::TCallback& Params); + static void GetExternalDrives(Bind::TCallback& Params); + static void UnMountExternalDrive(Bind::TCallback& Params); + static void GetTempDirectory(Bind::TCallback& Params); // system stuff DEFINE_BIND_FUNCTIONNAME(FileExists); @@ -92,6 +95,9 @@ namespace ApiPop DEFINE_BIND_FUNCTIONNAME(GetPlatform); DEFINE_BIND_FUNCTIONNAME(ShellOpen); DEFINE_BIND_FUNCTIONNAME(ShowWebPage); + DEFINE_BIND_FUNCTIONNAME(GetExternalDrives); + DEFINE_BIND_FUNCTIONNAME(UnMountExternalDrive); + DEFINE_BIND_FUNCTIONNAME(GetTempDirectory); // engine stuff DEFINE_BIND_FUNCTIONNAME(CompileAndRun); @@ -144,6 +150,9 @@ namespace ApiPop // TFileMonitor DEFINE_BIND_FUNCTIONNAME(Add); DEFINE_BIND_FUNCTIONNAME(WaitForChange); + + // TDeviceArray + Array> gExternalDrives; } template // ostream @@ -698,6 +707,25 @@ void ApiPop::WriteToFile(Bind::TCallback& Params) std::string Filename = Params.GetArgumentString(0); + auto IsExternalDrive = [&]() + { + for(int i = 0; i < gExternalDrives.GetSize(); i++) + { + if(Soy::StringBeginsWith(Filename, gExternalDrives[i]->mLabel, true)) + { + if(gExternalDrives[i]->mIsMounted) + return gExternalDrives[i]; + else + { + gExternalDrives[i]->MountDrive(); + return gExternalDrives[i]; + } + } + } + }; + + auto ExternalDrive = IsExternalDrive(); + // gr; work out a better idea for this if ( Soy::StringTrimLeft(Filename,"Documents/",true) || Soy::StringTrimLeft(Filename,"Documents\\",true) ) { @@ -705,6 +733,12 @@ void ApiPop::WriteToFile(Bind::TCallback& Params) //std::Debug << "Platform::GetDocumentsDirectory=" << DocsDir << std::endl; Filename = DocsDir + std::string("/") + Filename; } + // tsdk: for usb devices + else if( ExternalDrive ) + { + Soy::StringTrimLeft(Filename, ExternalDrive->mLabel,true); + Filename = ExternalDrive->mMountPath + Filename; + } else { Filename = Params.GetArgumentFilename(0); @@ -740,6 +774,55 @@ void ApiPop::WriteToFile(Bind::TCallback& Params) Soy::ArrayToFile( GetArrayBridge(Contents), Filename, Append ); } +void ApiPop::GetExternalDrives(Bind::TCallback& Params) +{ +// tsdk: TODO Remove devices from global list if they are not found by this function + auto OnDeviceFound = [&](const std::string& DevNode, const std::string& Label) + { + for( int i = 0; i < gExternalDrives.GetSize(); i++) + { + // tsdk: This is a not very unique better to use a UUID from udev + if(gExternalDrives[i]->mDevNode == DevNode) + return; + } + + auto NewDevice(std::make_shared(Label, DevNode)); + gExternalDrives.PushBack(NewDevice); + }; + + Platform::EnumExternalDrives( OnDeviceFound ); + + // os list all external Drives + Array Drives; + for( int i = 0; i < gExternalDrives.GetSize(); i++) + { + auto Object = Params.mContext.CreateObjectInstance( Params.mLocalContext ); + Object.SetString("Label", gExternalDrives[i]->mLabel); + + Drives.PushBack(Object); + } + + Params.Return( GetArrayBridge( Drives ) ); +} + +void ApiPop::UnMountExternalDrive(Bind::TCallback& Params) +{ + std::string DeviceName = Params.GetArgumentString(0); + + for(int i = 0; i < gExternalDrives.GetSize(); i++) + { + if(gExternalDrives[i]->mLabel == DeviceName) + { + // Do I need to do anything else to here? + gExternalDrives[i].reset(); + } + } +} + +void ApiPop::GetTempDirectory(Bind::TCallback& Params) +{ + Params.Return( Platform::GetTempDirectory() ); +} void ApiPop::GetFilenames(Bind::TCallback& Params) { @@ -822,6 +905,9 @@ void ApiPop::Bind(Bind::TContext& Context) Context.BindGlobalFunction(GetPlatform, Namespace); Context.BindGlobalFunction(ShellOpen, Namespace); Context.BindGlobalFunction(ShowWebPage, Namespace); + Context.BindGlobalFunction(GetExternalDrives, Namespace ); + Context.BindGlobalFunction(UnMountExternalDrive, Namespace ); + Context.BindGlobalFunction(GetTempDirectory, Namespace ); } TImageWrapper::~TImageWrapper() @@ -2063,3 +2149,22 @@ void ApiPop::TShellExecuteWrapper::OnStdOut(const std::string& Output) } FlushPendingOutput(); } + +ApiPop::TExternalDrive::TExternalDrive(const std::string& Label, const std::string& DevNode) +{ + mLabel = Label; + mDevNode = DevNode; +} + +ApiPop::TExternalDrive::~TExternalDrive() +{ + if(mIsMounted) + Platform::UnMountDrive(mLabel); +} + +void ApiPop::TExternalDrive::MountDrive() +{ + Platform::MountDrive(mDevNode, mLabel); + mMountPath = std::string("/media/") + mLabel; + mIsMounted = true; +} \ No newline at end of file diff --git a/src/TApiCommon.h b/src/TApiCommon.h index da13db1f..3312f48e 100644 --- a/src/TApiCommon.h +++ b/src/TApiCommon.h @@ -39,8 +39,9 @@ namespace ApiPop class TFileMonitorWrapper; class TShellExecuteWrapper; - + class TExternalDrive; class TAsyncLoop; + DECLARE_BIND_TYPENAME(AsyncLoop); DECLARE_BIND_TYPENAME(Image); DECLARE_BIND_TYPENAME(FileMonitor); @@ -227,3 +228,18 @@ class ApiPop::TShellExecuteWrapper : public Bind::TObjectWrapper mPendingOutput; // note: no filter between stderr and stdout atm }; +class ApiPop::TExternalDrive +{ +public: + TExternalDrive(const std::string& Label, const std::string& DevNode); + ~TExternalDrive(); + +public: + std::string mLabel; + std::string mDevNode; + + bool mIsMounted = false; + std::string mMountPath; + + void MountDrive(); +}; \ No newline at end of file