cleanupFinish
This commit is contained in:
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"BuildId": "23058290",
|
||||
"Modules":
|
||||
{
|
||||
"EasyXMLParser": "UnrealEditor-EasyXMLParser.dll"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
[FilterPlugin]
|
||||
; This section lists additional files which will be packaged along with your plugin. Paths should be listed relative to the root plugin directory, and
|
||||
; may include "...", "*", and "?" wildcards to match directories, files, and individual characters respectively.
|
||||
;
|
||||
; Examples:
|
||||
; /README.txt
|
||||
; /Extras/...
|
||||
; /Binaries/ThirdParty/*.dll
|
||||
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"FileVersion": 3,
|
||||
"Version": 1,
|
||||
"VersionName": "1.0.1",
|
||||
"FriendlyName": "EasyXMLParser",
|
||||
"Description": "Parse xml easily",
|
||||
"Category": "Programming",
|
||||
"CreatedBy": "ayumax",
|
||||
"CreatedByURL": "https://github.com/ayumax",
|
||||
"DocsURL": "https://github.com/ayumax/EasyXMLParserSample",
|
||||
"MarketplaceURL": "com.epicgames.launcher://ue/marketplace/content/af98110080a4411a8eaf3b8e931b8655",
|
||||
"SupportURL": "",
|
||||
"CanContainContent": false,
|
||||
"IsBetaVersion": false,
|
||||
"Installed": true,
|
||||
"Modules": [
|
||||
{
|
||||
"Name": "EasyXMLParser",
|
||||
"Type": "Runtime",
|
||||
"LoadingPhase": "Default",
|
||||
"WhitelistPlatforms": [
|
||||
"Android",
|
||||
"Win64",
|
||||
"Mac",
|
||||
"IOS"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1.7 KiB |
@@ -0,0 +1,53 @@
|
||||
// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
using UnrealBuildTool;
|
||||
|
||||
public class EasyXMLParser : ModuleRules
|
||||
{
|
||||
public EasyXMLParser(ReadOnlyTargetRules Target) : base(Target)
|
||||
{
|
||||
PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
|
||||
|
||||
PublicIncludePaths.AddRange(
|
||||
new string[] {
|
||||
// ... add public include paths required here ...
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
PrivateIncludePaths.AddRange(
|
||||
new string[] {
|
||||
// ... add other private include paths required here ...
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
PublicDependencyModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
"Core",
|
||||
// ... add other public dependencies that you statically link with here ...
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
PrivateDependencyModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
"CoreUObject",
|
||||
"Engine",
|
||||
"Slate",
|
||||
"SlateCore",
|
||||
"XmlParser"
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
DynamicallyLoadedModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
// ... add any modules that your module loads dynamically here ...
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
// Copyright 2019 ayumax. All Rights Reserved.
|
||||
#include "EasyXMLAsyncLoadFromFile.h"
|
||||
#include "Engine/World.h"
|
||||
#include "TimerManager.h"
|
||||
#include "Async/Async.h"
|
||||
#include "Utils/CustomXMLParser.h"
|
||||
#include "EasyXMLParseManager.h"
|
||||
|
||||
UEasyXMLAsyncLoadFromFile::UEasyXMLAsyncLoadFromFile(const FObjectInitializer& ObjectInitializer)
|
||||
:Super(ObjectInitializer)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
UEasyXMLAsyncLoadFromFile* UEasyXMLAsyncLoadFromFile::AsyncLoadFromFile(UObject* WorldContextObject, const FString& FilePath, bool IsAblolute)
|
||||
{
|
||||
auto Action = NewObject<UEasyXMLAsyncLoadFromFile>();
|
||||
Action->RegisterWithGameInstance(WorldContextObject);
|
||||
Action->_XMLFile = FilePath;
|
||||
Action->_IsAblolute = IsAblolute;
|
||||
|
||||
return Action;
|
||||
}
|
||||
|
||||
void UEasyXMLAsyncLoadFromFile::Activate()
|
||||
{
|
||||
AsyncTask(ENamedThreads::AnyBackgroundThreadNormalTask, [this]()
|
||||
{
|
||||
auto manager = NewObject<UEasyXMLParseManager>();
|
||||
FString _errorMessage;
|
||||
EEasyXMLParserErrorCode _isSuccessed;
|
||||
auto rootElement = manager->LoadFromFile(_XMLFile, _IsAblolute, _isSuccessed, _errorMessage);
|
||||
|
||||
if (_isSuccessed == EEasyXMLParserErrorCode::Successed)
|
||||
{
|
||||
AsyncTask(ENamedThreads::GameThread, [this, rootElement]()
|
||||
{
|
||||
Successed.Broadcast(rootElement, TEXT(""));
|
||||
SetReadyToDestroy();
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
AsyncTask(ENamedThreads::GameThread, [this, _errorMessage]()
|
||||
{
|
||||
Failed.Broadcast(nullptr, _errorMessage);
|
||||
SetReadyToDestroy();
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
// Copyright 2019 ayumax. All Rights Reserved.
|
||||
#include "EasyXMLAsyncLoadFromString.h"
|
||||
#include "Engine/World.h"
|
||||
#include "TimerManager.h"
|
||||
#include "Async/Async.h"
|
||||
#include "Utils/CustomXMLParser.h"
|
||||
|
||||
UEasyXMLAsyncLoadFromString::UEasyXMLAsyncLoadFromString(const FObjectInitializer& ObjectInitializer)
|
||||
:Super(ObjectInitializer)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
UEasyXMLAsyncLoadFromString* UEasyXMLAsyncLoadFromString::AsyncLoadFromString(UObject* WorldContextObject, const FString& XMLString)
|
||||
{
|
||||
auto Action = NewObject<UEasyXMLAsyncLoadFromString>();
|
||||
Action->RegisterWithGameInstance(WorldContextObject);
|
||||
Action->_XMLString = XMLString;
|
||||
|
||||
return Action;
|
||||
}
|
||||
|
||||
void UEasyXMLAsyncLoadFromString::Activate()
|
||||
{
|
||||
AsyncTask(ENamedThreads::AnyBackgroundThreadNormalTask, [this]()
|
||||
{
|
||||
CustomXMLParser parser;
|
||||
FString _errorMessage;
|
||||
|
||||
auto rootElement = parser.Parse(_XMLString, _errorMessage);
|
||||
|
||||
if (rootElement != nullptr)
|
||||
{
|
||||
AsyncTask(ENamedThreads::GameThread, [this, rootElement]()
|
||||
{
|
||||
Successed.Broadcast(rootElement, TEXT(""));
|
||||
SetReadyToDestroy();
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
AsyncTask(ENamedThreads::GameThread, [this, _errorMessage]()
|
||||
{
|
||||
Failed.Broadcast(nullptr, _errorMessage);
|
||||
SetReadyToDestroy();
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
// Copyright 2019 ayumax. All Rights Reserved.
|
||||
#include "EasyXMLAttribute.h"
|
||||
#include "EasyXMLElement.h"
|
||||
|
||||
UEasyXMLAttribute* UEasyXMLAttribute::CreateAttribute(UEasyXMLElement* ParentObject, FString _Name, FString _Value)
|
||||
{
|
||||
auto newAttribute = NewObject<UEasyXMLAttribute>(ParentObject == nullptr ? (UObject*)GetTransientPackage() : ParentObject);
|
||||
newAttribute->Parent = ParentObject;
|
||||
newAttribute->Name = _Name;
|
||||
newAttribute->Value = _Value.TrimStartAndEnd();
|
||||
|
||||
return newAttribute;
|
||||
}
|
||||
@@ -0,0 +1,223 @@
|
||||
// Copyright 2019 ayumax. All Rights Reserved.
|
||||
#include "EasyXMLElement.h"
|
||||
#include "EasyXMLAttribute.h"
|
||||
#include "Internationalization/Regex.h"
|
||||
|
||||
UEasyXMLElement* UEasyXMLElement::CreateElement(UEasyXMLObject* ParentObject, FString Tag, FString Content, int32 _LineNumber)
|
||||
{
|
||||
auto newElement = NewObject<UEasyXMLElement>(ParentObject == nullptr ? (UObject*)GetTransientPackage() : ParentObject);
|
||||
newElement->Parent = ParentObject;
|
||||
newElement->Name = Tag;
|
||||
newElement->Value = Content.TrimStartAndEnd();
|
||||
newElement->LineNumber = _LineNumber;
|
||||
|
||||
return newElement;
|
||||
}
|
||||
|
||||
|
||||
int32 UEasyXMLElement::ReadInt(const FString& AccessString, int32 DefaultValue)
|
||||
{
|
||||
auto foundElement = ReadEasyXMLObject(AccessString);
|
||||
if (!foundElement) return DefaultValue;
|
||||
|
||||
return foundElement->GetIntValue(DefaultValue);
|
||||
}
|
||||
|
||||
|
||||
float UEasyXMLElement::ReadFloat(const FString& AccessString, float DefaultValue)
|
||||
{
|
||||
auto foundElement = ReadEasyXMLObject(AccessString);
|
||||
if (!foundElement) return DefaultValue;
|
||||
|
||||
return foundElement->GetFloatValue(DefaultValue);
|
||||
}
|
||||
|
||||
FString UEasyXMLElement::ReadString(const FString& AccessString, const FString& DefaultValue)
|
||||
{
|
||||
auto foundElement = ReadEasyXMLObject(AccessString);
|
||||
if (!foundElement) return DefaultValue;
|
||||
|
||||
return foundElement->GetStringValue(DefaultValue);
|
||||
}
|
||||
|
||||
bool UEasyXMLElement::ReadBool(const FString& AccessString, bool DefaultValue)
|
||||
{
|
||||
auto foundElement = ReadEasyXMLObject(AccessString);
|
||||
if (!foundElement) return DefaultValue;
|
||||
|
||||
return foundElement->GetBoolValue(DefaultValue);
|
||||
}
|
||||
|
||||
UEasyXMLElement* UEasyXMLElement::ReadElement(const FString& AccessString, EEasyXMLParserFound& Result)
|
||||
{
|
||||
auto filterArray = ReadElements(AccessString, Result);
|
||||
|
||||
return filterArray.Num() > 0 ? filterArray[0] : nullptr;
|
||||
}
|
||||
|
||||
TArray<UEasyXMLElement*> UEasyXMLElement::ReadElements(const FString& AccessString, EEasyXMLParserFound& Result)
|
||||
{
|
||||
TArray<UEasyXMLElement*> foundElements;
|
||||
|
||||
TArray<FString> Accessers;
|
||||
AccessString.ParseIntoArray(Accessers, TEXT("."), true);
|
||||
|
||||
Result = EEasyXMLParserFound::NotFound;
|
||||
|
||||
auto parentNode = this;
|
||||
|
||||
for (int i = 0; i < Accessers.Num(); ++i)
|
||||
{
|
||||
auto accesseName = Accessers[i];
|
||||
|
||||
if (accesseName.IsEmpty()) return foundElements;
|
||||
|
||||
if (accesseName[0] == TEXT('@'))
|
||||
{
|
||||
return foundElements;
|
||||
}
|
||||
|
||||
FString elementName;
|
||||
int32 arrayIndex = 0;
|
||||
bool IsArrayAccess = IsAccessAsArray(accesseName, elementName, arrayIndex);
|
||||
|
||||
auto filterNodes = parentNode->GetElementsByTagName(elementName);
|
||||
|
||||
if (i == (Accessers.Num() - 1))
|
||||
{
|
||||
if (IsArrayAccess)
|
||||
{
|
||||
if (filterNodes.Num() > arrayIndex)
|
||||
{
|
||||
foundElements.Emplace(filterNodes[arrayIndex]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
foundElements = filterNodes;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (filterNodes.Num() > arrayIndex)
|
||||
{
|
||||
parentNode = filterNodes[arrayIndex];
|
||||
}
|
||||
|
||||
if (!parentNode) return foundElements;
|
||||
}
|
||||
}
|
||||
|
||||
Result = EEasyXMLParserFound::Found;
|
||||
|
||||
return foundElements;
|
||||
}
|
||||
|
||||
UEasyXMLObject* UEasyXMLElement::ReadEasyXMLObject(const FString& AccessString)
|
||||
{
|
||||
TArray<FString> Accessers;
|
||||
AccessString.ParseIntoArray(Accessers, TEXT("."), true);
|
||||
|
||||
auto parentNode = this;
|
||||
|
||||
for (auto accesseName : Accessers)
|
||||
{
|
||||
if (!parentNode) return nullptr;
|
||||
if (accesseName.IsEmpty()) return nullptr;
|
||||
|
||||
if (accesseName[0] == TEXT('@'))
|
||||
{
|
||||
EEasyXMLParserFound retFound;
|
||||
return parentNode->GetAttribute(accesseName.Mid(1), retFound);
|
||||
}
|
||||
|
||||
FString elementName;
|
||||
int32 arrayIndex = 0;
|
||||
IsAccessAsArray(accesseName, elementName, arrayIndex);
|
||||
|
||||
auto filterNodes = parentNode->GetElementsByTagName(elementName);
|
||||
if (filterNodes.Num() > arrayIndex)
|
||||
{
|
||||
parentNode = filterNodes[arrayIndex];
|
||||
}
|
||||
else
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return parentNode;
|
||||
}
|
||||
|
||||
TArray<UEasyXMLElement*> UEasyXMLElement::GetElementsByTagName(const FString& TagName)
|
||||
{
|
||||
TArray<UEasyXMLElement*> foundElements = Children.FilterByPredicate(
|
||||
[TagName](UEasyXMLElement* child)
|
||||
{
|
||||
return child->Name.Equals(TagName, ESearchCase::IgnoreCase);
|
||||
});
|
||||
|
||||
return foundElements;
|
||||
}
|
||||
|
||||
UEasyXMLAttribute* UEasyXMLElement::GetAttribute(const FString& AtrributeName, EEasyXMLParserFound& Result)
|
||||
{
|
||||
if (Attributes.Contains(AtrributeName))
|
||||
{
|
||||
Result = EEasyXMLParserFound::Found;
|
||||
return Attributes[AtrributeName];
|
||||
}
|
||||
|
||||
Result = EEasyXMLParserFound::NotFound;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool UEasyXMLElement::IsAccessAsArray(const FString& AccessName, FString& ElementName, int32& ArrayIndex)
|
||||
{
|
||||
const FRegexPattern pattern = FRegexPattern(FString(TEXT("(.*)\\[([0-9]+)\\]$")));
|
||||
FRegexMatcher matcher(pattern, AccessName);
|
||||
|
||||
while (matcher.FindNext())
|
||||
{
|
||||
ElementName = matcher.GetCaptureGroup(1);
|
||||
|
||||
FString numStr = matcher.GetCaptureGroup(2);
|
||||
if (numStr.IsNumeric())
|
||||
{
|
||||
ArrayIndex = (FCString::Atoi(*numStr));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
ElementName = AccessName;
|
||||
ArrayIndex = 0;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool UEasyXMLElement::IsContainAttributeKeys(const TArray<FString>& Keys, TArray<FString>& FoundAttributeKeys)
|
||||
{
|
||||
TArray<FString> attributeKeys;
|
||||
Attributes.GetKeys(attributeKeys);
|
||||
|
||||
for (auto key : Keys)
|
||||
{
|
||||
bool found = false;
|
||||
for (auto attributeKey : attributeKeys)
|
||||
{
|
||||
if (key.Equals(attributeKey, ESearchCase::IgnoreCase))
|
||||
{
|
||||
found = true;
|
||||
FoundAttributeKeys.Emplace(attributeKey);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!found) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
// Copyright 2019 ayumax. All Rights Reserved.
|
||||
|
||||
#include "EasyXMLObject.h"
|
||||
#include "Utils/CustomXMLParser.h"
|
||||
|
||||
int32 UEasyXMLObject::GetIntValue(int32 DefaultValue)
|
||||
{
|
||||
if (Value.IsEmpty()) return DefaultValue;
|
||||
|
||||
int32 _index = 0;
|
||||
|
||||
if (Value.IsNumeric() && !Value.FindChar(TEXT('.'), _index))
|
||||
{
|
||||
return FCString::Atoi(*Value);
|
||||
}
|
||||
|
||||
return DefaultValue;
|
||||
}
|
||||
|
||||
float UEasyXMLObject::GetFloatValue(float DefaultValue)
|
||||
{
|
||||
if (Value.IsEmpty()) return DefaultValue;
|
||||
|
||||
auto isSuccess = Value.IsNumeric();
|
||||
return isSuccess ? FCString::Atof(*Value) : DefaultValue;
|
||||
}
|
||||
|
||||
FString UEasyXMLObject::GetStringValue(FString DefaultValue)
|
||||
{
|
||||
if (Value.IsEmpty()) return DefaultValue;
|
||||
|
||||
return Value;
|
||||
}
|
||||
|
||||
bool UEasyXMLObject::GetBoolValue(bool DefaultValue)
|
||||
{
|
||||
if (Value.IsEmpty()) return DefaultValue;
|
||||
|
||||
if (Value.Equals(TEXT("true"), ESearchCase::IgnoreCase))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (Value.Equals(TEXT("false"), ESearchCase::IgnoreCase))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return DefaultValue;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
// Copyright 2019 ayumax. All Rights Reserved.
|
||||
|
||||
#include "EasyXMLParseManager.h"
|
||||
#include "Misc/Paths.h"
|
||||
#include "Misc/FileHelper.h"
|
||||
#include "EasyXMLElement.h"
|
||||
#include "Utils/CustomXMLParser.h"
|
||||
|
||||
|
||||
UEasyXMLElement* UEasyXMLParseManager::LoadFromString(const FString& XMLString, EEasyXMLParserErrorCode& Result, FString& ErrorMessage)
|
||||
{
|
||||
CustomXMLParser parser;
|
||||
FString _errorMessage;
|
||||
|
||||
auto rootElement = parser.Parse(XMLString, _errorMessage);
|
||||
Result = rootElement != nullptr ? EEasyXMLParserErrorCode::Successed : EEasyXMLParserErrorCode::Failed;
|
||||
ErrorMessage = _errorMessage;
|
||||
|
||||
return rootElement;
|
||||
}
|
||||
|
||||
UEasyXMLElement* UEasyXMLParseManager::LoadFromFile(const FString& FilePath, bool IsAblolute, EEasyXMLParserErrorCode& Result, FString& ErrorMessage)
|
||||
{
|
||||
auto readPath = FilePath;
|
||||
if (!IsAblolute)
|
||||
{
|
||||
readPath = FPaths::Combine(FPaths::ProjectContentDir(), FilePath);
|
||||
}
|
||||
|
||||
if (!FPaths::FileExists(readPath)) return nullptr;
|
||||
|
||||
FString xmlString;
|
||||
|
||||
FFileHelper::LoadFileToString(xmlString, *readPath);
|
||||
|
||||
return LoadFromString(xmlString, Result, ErrorMessage);
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#include "EasyXMLParser.h"
|
||||
|
||||
#define LOCTEXT_NAMESPACE "FEasyXMLParserModule"
|
||||
|
||||
void FEasyXMLParserModule::StartupModule()
|
||||
{
|
||||
// This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module
|
||||
}
|
||||
|
||||
void FEasyXMLParserModule::ShutdownModule()
|
||||
{
|
||||
// This function may be called during shutdown to clean up your module. For modules that support dynamic reloading,
|
||||
// we call this function before unloading the module.
|
||||
}
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
|
||||
IMPLEMENT_MODULE(FEasyXMLParserModule, EasyXMLParser)
|
||||
@@ -0,0 +1,270 @@
|
||||
// Copyright 2019 ayumax. All Rights Reserved.
|
||||
#include "Misc/AutomationTest.h"
|
||||
#include "EasyXMLParseManager.h"
|
||||
|
||||
IMPLEMENT_SIMPLE_AUTOMATION_TEST(FNodeAccessTest, "EasyXMLParser.NodeAccessTest", EAutomationTestFlags::ApplicationContextMask | EAutomationTestFlags::SmokeFilter)
|
||||
|
||||
bool FNodeAccessTest::RunTest(const FString& Parameters)
|
||||
{
|
||||
{
|
||||
FString xmlString = TEXT("<root>\r")
|
||||
TEXT("<!-- comment desu -->\r")
|
||||
TEXT("<abc attr1=\"10\" attr2=\"false\">\r")
|
||||
TEXT("123\r")
|
||||
TEXT("</abc>\r")
|
||||
TEXT("<abc/>\r")
|
||||
TEXT("<abc>40</abc>\r")
|
||||
TEXT("<abc>ZZZZ</abc>\r")
|
||||
TEXT("<bbb>\r")
|
||||
TEXT("bbbChild\r")
|
||||
TEXT("</bbb>\r")
|
||||
TEXT("</root>");
|
||||
|
||||
EEasyXMLParserErrorCode result;
|
||||
FString errorMessage;
|
||||
auto rootNode = UEasyXMLParseManager::LoadFromString(xmlString, result, errorMessage);
|
||||
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("root.abc")), TEXT("123"));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("root.abc[0]")), TEXT("123"));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("root.abc[1]")), TEXT(""));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("root.abc[2]")), TEXT("40"));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("root.abc[3]")), TEXT("ZZZZ"));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("root.bbb")), TEXT("bbbChild"));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("root.abc[0].@attr1")), TEXT("10"));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("root.abc[0].@attr2")), TEXT("false"));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
IMPLEMENT_SIMPLE_AUTOMATION_TEST(FNodeAccessTest2, "EasyXMLParser.NodeAccessTest2", EAutomationTestFlags::ApplicationContextMask | EAutomationTestFlags::SmokeFilter)
|
||||
|
||||
bool FNodeAccessTest2::RunTest(const FString& Parameters)
|
||||
{
|
||||
FString XMLSource =
|
||||
TEXT("<PurchaseOrder PurchaseOrderNumber=\"99503\" OrderDate=\"1999-10-20\">\r")
|
||||
TEXT("<Address Type=\"Shipping\">\r")
|
||||
TEXT("<Name>Ellen Adams</Name>\r")
|
||||
TEXT("<Street>123 Maple Street</Street>\r")
|
||||
TEXT("<City>Mill Valley</City>\r")
|
||||
TEXT("<State>CA</State>\r")
|
||||
TEXT("<Zip>10999</Zip>\r")
|
||||
TEXT("<Country>USA</Country>\r")
|
||||
TEXT("</Address>\r")
|
||||
TEXT("<Address Type=\"Billing\">\r")
|
||||
TEXT("<Name>Tai Yee</Name>\r")
|
||||
TEXT("<Street>8 Oak Avenue</Street>\r")
|
||||
TEXT("<City>Old Town</City>\r")
|
||||
TEXT("<State>PA</State>\r")
|
||||
TEXT("<Zip>95819</Zip>\r")
|
||||
TEXT("<Country>USA</Country>\r")
|
||||
TEXT("</Address>\r")
|
||||
TEXT("<DeliveryNotes>Please leave packages in shed by driveway.</DeliveryNotes>\r")
|
||||
TEXT("<Items>\r")
|
||||
TEXT("<Item PartNumber=\"872-AA\">\r")
|
||||
TEXT("<ProductName>Lawnmower</ProductName>\r")
|
||||
TEXT("<Quantity>1</Quantity>\r")
|
||||
TEXT("<USPrice>148.95</USPrice>\r")
|
||||
TEXT("<Comment>Confirm this is electric</Comment>\r")
|
||||
TEXT("</Item>\r")
|
||||
TEXT("<Item PartNumber=\"926-AA\">\r")
|
||||
TEXT("<ProductName>Baby Monitor</ProductName>\r")
|
||||
TEXT("<Quantity>2</Quantity>\r")
|
||||
TEXT("<USPrice>39.98</USPrice>\r")
|
||||
TEXT("<ShipDate>1999-05-21</ShipDate>\r")
|
||||
TEXT("</Item>\r")
|
||||
TEXT("</Items>\r")
|
||||
TEXT("</PurchaseOrder>\r");
|
||||
|
||||
{
|
||||
EEasyXMLParserErrorCode result;
|
||||
FString errorMessage;
|
||||
auto rootNode = UEasyXMLParseManager::LoadFromString(XMLSource, result, errorMessage);
|
||||
|
||||
TestEqual(TEXT("success read"), rootNode->ReadInt(TEXT("PurchaseOrder.@PurchaseOrderNumber")), 99503);
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.@OrderDate")), TEXT("1999-10-20"));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Address[0].@Type")), TEXT("Shipping"));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Address[0].Name")), TEXT("Ellen Adams"));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Address[0].Street")), TEXT("123 Maple Street"));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Address[0].City")), TEXT("Mill Valley"));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Address[0].State")), TEXT("CA"));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Address[0].Zip")), TEXT("10999"));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Address[0].Country")), TEXT("USA"));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Address[1].@Type")), TEXT("Billing"));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Address[1].Name")), TEXT("Tai Yee"));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Address[1].Street")), TEXT("8 Oak Avenue"));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Address[1].City")), TEXT("Old Town"));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Address[1].State")), TEXT("PA"));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Address[1].Zip")), TEXT("95819"));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Address[1].Country")), TEXT("USA"));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.DeliveryNotes")), TEXT("Please leave packages in shed by driveway."));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Items.Item[0].@PartNumber")), TEXT("872-AA"));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Items.Item[0].ProductName")), TEXT("Lawnmower"));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Items.Item[0].Quantity")), TEXT("1"));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Items.Item[0].USPrice")), TEXT("148.95"));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Items.Item[0].Comment")), TEXT("Confirm this is electric"));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Items.Item[1].@PartNumber")), TEXT("926-AA"));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Items.Item[1].ProductName")), TEXT("Baby Monitor"));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Items.Item[1].Quantity")), TEXT("2"));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Items.Item[1].USPrice")), TEXT("39.98"));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Items.Item[1].ShipDate")), TEXT("1999-05-21"));
|
||||
}
|
||||
|
||||
{
|
||||
EEasyXMLParserErrorCode result;
|
||||
FString errorMessage;
|
||||
auto rootNode = UEasyXMLParseManager::LoadFromString(XMLSource, result, errorMessage);
|
||||
|
||||
EEasyXMLParserFound retFound;
|
||||
auto Address0Node = rootNode->ReadElement(TEXT("PurchaseOrder.Address[0]"), retFound);
|
||||
TestTrue(TEXT("success read"), retFound == EEasyXMLParserFound::Found);
|
||||
auto Address1Node = rootNode->ReadElement(TEXT("PurchaseOrder.Address[1]"), retFound);
|
||||
TestTrue(TEXT("success read"), retFound == EEasyXMLParserFound::Found);
|
||||
auto Item0Node = rootNode->ReadElement(TEXT("PurchaseOrder.Items.Item[0]"), retFound);
|
||||
TestTrue(TEXT("success read"), retFound == EEasyXMLParserFound::Found);
|
||||
auto Item1Node = rootNode->ReadElement(TEXT("PurchaseOrder.Items.Item[1]"), retFound);
|
||||
TestTrue(TEXT("success read"), retFound == EEasyXMLParserFound::Found);
|
||||
|
||||
TestEqual(TEXT("success read"), rootNode->ReadInt(TEXT("PurchaseOrder.@PurchaseOrderNumber")), 99503);
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.@OrderDate")), TEXT("1999-10-20"));
|
||||
TestEqual(TEXT("success read"), Address0Node->ReadString(TEXT("@Type")), TEXT("Shipping"));
|
||||
TestEqual(TEXT("success read"), Address0Node->ReadString(TEXT("Name")), TEXT("Ellen Adams"));
|
||||
TestEqual(TEXT("success read"), Address0Node->ReadString(TEXT("Street")), TEXT("123 Maple Street"));
|
||||
TestEqual(TEXT("success read"), Address0Node->ReadString(TEXT("City")), TEXT("Mill Valley"));
|
||||
TestEqual(TEXT("success read"), Address0Node->ReadString(TEXT("State")), TEXT("CA"));
|
||||
TestEqual(TEXT("success read"), Address0Node->ReadString(TEXT("Zip")), TEXT("10999"));
|
||||
TestEqual(TEXT("success read"), Address0Node->ReadString(TEXT("Country")), TEXT("USA"));
|
||||
TestEqual(TEXT("success read"), Address1Node->ReadString(TEXT("@Type")), TEXT("Billing"));
|
||||
TestEqual(TEXT("success read"), Address1Node->ReadString(TEXT("Name")), TEXT("Tai Yee"));
|
||||
TestEqual(TEXT("success read"), Address1Node->ReadString(TEXT("Street")), TEXT("8 Oak Avenue"));
|
||||
TestEqual(TEXT("success read"), Address1Node->ReadString(TEXT("City")), TEXT("Old Town"));
|
||||
TestEqual(TEXT("success read"), Address1Node->ReadString(TEXT("State")), TEXT("PA"));
|
||||
TestEqual(TEXT("success read"), Address1Node->ReadString(TEXT("Zip")), TEXT("95819"));
|
||||
TestEqual(TEXT("success read"), Address1Node->ReadString(TEXT("Country")), TEXT("USA"));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.DeliveryNotes")), TEXT("Please leave packages in shed by driveway."));
|
||||
TestEqual(TEXT("success read"), Item0Node->ReadString(TEXT("@PartNumber")), TEXT("872-AA"));
|
||||
TestEqual(TEXT("success read"), Item0Node->ReadString(TEXT("ProductName")), TEXT("Lawnmower"));
|
||||
TestEqual(TEXT("success read"), Item0Node->ReadString(TEXT("Quantity")), TEXT("1"));
|
||||
TestEqual(TEXT("success read"), Item0Node->ReadString(TEXT("USPrice")), TEXT("148.95"));
|
||||
TestEqual(TEXT("success read"), Item0Node->ReadString(TEXT("Comment")), TEXT("Confirm this is electric"));
|
||||
TestEqual(TEXT("success read"), Item1Node->ReadString(TEXT("@PartNumber")), TEXT("926-AA"));
|
||||
TestEqual(TEXT("success read"), Item1Node->ReadString(TEXT("ProductName")), TEXT("Baby Monitor"));
|
||||
TestEqual(TEXT("success read"), Item1Node->ReadString(TEXT("Quantity")), TEXT("2"));
|
||||
TestEqual(TEXT("success read"), Item1Node->ReadString(TEXT("USPrice")), TEXT("39.98"));
|
||||
TestEqual(TEXT("success read"), Item1Node->ReadString(TEXT("ShipDate")), TEXT("1999-05-21"));
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
EEasyXMLParserErrorCode result;
|
||||
FString errorMessage;
|
||||
auto rootNode = UEasyXMLParseManager::LoadFromString(XMLSource, result, errorMessage);
|
||||
|
||||
EEasyXMLParserFound retFound;
|
||||
auto AddressNodes = rootNode->ReadElements(TEXT("PurchaseOrder.Address"), retFound);
|
||||
TestTrue(TEXT("success read"), retFound == EEasyXMLParserFound::Found);
|
||||
auto ItemNodes = rootNode->ReadElements(TEXT("PurchaseOrder.Items.Item"), retFound);
|
||||
TestTrue(TEXT("success read"), retFound == EEasyXMLParserFound::Found);
|
||||
|
||||
TestEqual(TEXT("success read"), AddressNodes[0]->ReadString(TEXT("@Type")), TEXT("Shipping"));
|
||||
TestEqual(TEXT("success read"), AddressNodes[0]->ReadString(TEXT("Name")), TEXT("Ellen Adams"));
|
||||
TestEqual(TEXT("success read"), AddressNodes[0]->ReadString(TEXT("Street")), TEXT("123 Maple Street"));
|
||||
TestEqual(TEXT("success read"), AddressNodes[0]->ReadString(TEXT("City")), TEXT("Mill Valley"));
|
||||
TestEqual(TEXT("success read"), AddressNodes[0]->ReadString(TEXT("State")), TEXT("CA"));
|
||||
TestEqual(TEXT("success read"), AddressNodes[0]->ReadString(TEXT("Zip")), TEXT("10999"));
|
||||
TestEqual(TEXT("success read"), AddressNodes[0]->ReadString(TEXT("Country")), TEXT("USA"));
|
||||
TestEqual(TEXT("success read"), AddressNodes[1]->ReadString(TEXT("@Type")), TEXT("Billing"));
|
||||
TestEqual(TEXT("success read"), AddressNodes[1]->ReadString(TEXT("Name")), TEXT("Tai Yee"));
|
||||
TestEqual(TEXT("success read"), AddressNodes[1]->ReadString(TEXT("Street")), TEXT("8 Oak Avenue"));
|
||||
TestEqual(TEXT("success read"), AddressNodes[1]->ReadString(TEXT("City")), TEXT("Old Town"));
|
||||
TestEqual(TEXT("success read"), AddressNodes[1]->ReadString(TEXT("State")), TEXT("PA"));
|
||||
TestEqual(TEXT("success read"), AddressNodes[1]->ReadString(TEXT("Zip")), TEXT("95819"));
|
||||
TestEqual(TEXT("success read"), AddressNodes[1]->ReadString(TEXT("Country")), TEXT("USA"));
|
||||
|
||||
TestEqual(TEXT("success read"), ItemNodes[0]->ReadString(TEXT("@PartNumber")), TEXT("872-AA"));
|
||||
TestEqual(TEXT("success read"), ItemNodes[0]->ReadString(TEXT("ProductName")), TEXT("Lawnmower"));
|
||||
TestEqual(TEXT("success read"), ItemNodes[0]->ReadString(TEXT("Quantity")), TEXT("1"));
|
||||
TestEqual(TEXT("success read"), ItemNodes[0]->ReadString(TEXT("USPrice")), TEXT("148.95"));
|
||||
TestEqual(TEXT("success read"), ItemNodes[0]->ReadString(TEXT("Comment")), TEXT("Confirm this is electric"));
|
||||
TestEqual(TEXT("success read"), ItemNodes[1]->ReadString(TEXT("@PartNumber")), TEXT("926-AA"));
|
||||
TestEqual(TEXT("success read"), ItemNodes[1]->ReadString(TEXT("ProductName")), TEXT("Baby Monitor"));
|
||||
TestEqual(TEXT("success read"), ItemNodes[1]->ReadString(TEXT("Quantity")), TEXT("2"));
|
||||
TestEqual(TEXT("success read"), ItemNodes[1]->ReadString(TEXT("USPrice")), TEXT("39.98"));
|
||||
TestEqual(TEXT("success read"), ItemNodes[1]->ReadString(TEXT("ShipDate")), TEXT("1999-05-21"));
|
||||
}
|
||||
|
||||
{
|
||||
EEasyXMLParserErrorCode result;
|
||||
FString errorMessage;
|
||||
auto rootNode = UEasyXMLParseManager::LoadFromString(XMLSource, result, errorMessage);
|
||||
|
||||
TestEqual(TEXT("success read"), rootNode->ReadInt(TEXT("PurchaseOrder.PurchaseOrderNumber")), 0);
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.OrderDate")), TEXT(""));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Address[0].Type")), TEXT(""));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Address[0].Name-")), TEXT(""));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrde-r.Address[0].Street")), TEXT(""));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Address-[0].City")), TEXT(""));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Address[0].State-")), TEXT(""));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder-.Address[0].Zip")), TEXT(""));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Address[0]-.Country")), TEXT(""));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Address[1]-.@Type")), TEXT(""));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder-.Address[1].Name")), TEXT(""));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Address[1].Stree-t")), TEXT(""));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Address[1]-.City")), TEXT(""));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder-.Address[1].State")), TEXT(""));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Address[1].Zip-")), TEXT(""));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Address[1]-.Country")), TEXT(""));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder-.DeliveryNotes")), TEXT(""));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Items.Item[0].@PartNumber-")), TEXT(""));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Items.Item[0]-.ProductName")), TEXT(""));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Items-.Item[0].Quantity")), TEXT(""));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Items.Item[4].USPrice")), TEXT(""));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Items.Item[-1].Comment")), TEXT(""));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Items.Item[8].@PartNumber")), TEXT(""));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Items.Item[99].ProductName")), TEXT(""));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Items.Item[7].Quantity")), TEXT(""));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Items.Item[555].USPrice")), TEXT(""));
|
||||
TestEqual(TEXT("success read"), rootNode->ReadString(TEXT("PurchaseOrder.Items.Item[9999].ShipDate")), TEXT(""));
|
||||
}
|
||||
|
||||
{
|
||||
EEasyXMLParserErrorCode result;
|
||||
FString errorMessage;
|
||||
auto rootNode = UEasyXMLParseManager::LoadFromString(XMLSource, result, errorMessage);
|
||||
|
||||
EEasyXMLParserFound retFound;
|
||||
auto AddressNodes = rootNode->ReadElements(TEXT("PurchaseOrder.Address"), retFound);
|
||||
TestTrue(TEXT("success read"), retFound == EEasyXMLParserFound::Found);
|
||||
auto ItemNodes = rootNode->ReadElements(TEXT("PurchaseOrder.Items.Item"), retFound);
|
||||
TestTrue(TEXT("success read"), retFound == EEasyXMLParserFound::Found);
|
||||
|
||||
TestEqual(TEXT("success read"), AddressNodes[0]->ReadString(TEXT("@Type-")), TEXT(""));
|
||||
TestEqual(TEXT("success read"), AddressNodes[0]->ReadString(TEXT("Name-")), TEXT(""));
|
||||
TestEqual(TEXT("success read"), AddressNodes[0]->ReadString(TEXT("Street-")), TEXT(""));
|
||||
TestEqual(TEXT("success read"), AddressNodes[0]->ReadString(TEXT("City-")), TEXT(""));
|
||||
TestEqual(TEXT("success read"), AddressNodes[0]->ReadString(TEXT("State-")), TEXT(""));
|
||||
TestEqual(TEXT("success read"), AddressNodes[0]->ReadString(TEXT("Zip-")), TEXT(""));
|
||||
TestEqual(TEXT("success read"), AddressNodes[0]->ReadString(TEXT("Country-")), TEXT(""));
|
||||
TestEqual(TEXT("success read"), AddressNodes[1]->ReadString(TEXT("@Type-")), TEXT(""));
|
||||
TestEqual(TEXT("success read"), AddressNodes[1]->ReadString(TEXT("Name-")), TEXT(""));
|
||||
TestEqual(TEXT("success read"), AddressNodes[1]->ReadString(TEXT("Street-")), TEXT(""));
|
||||
TestEqual(TEXT("success read"), AddressNodes[1]->ReadString(TEXT("City-")), TEXT(""));
|
||||
TestEqual(TEXT("success read"), AddressNodes[1]->ReadString(TEXT("State-")), TEXT(""));
|
||||
TestEqual(TEXT("success read"), AddressNodes[1]->ReadString(TEXT("Zip-")), TEXT(""));
|
||||
TestEqual(TEXT("success read"), AddressNodes[1]->ReadString(TEXT("Country-")), TEXT(""));
|
||||
|
||||
TestEqual(TEXT("success read"), ItemNodes[0]->ReadString(TEXT("@PartNumber-")), TEXT(""));
|
||||
TestEqual(TEXT("success read"), ItemNodes[0]->ReadString(TEXT("ProductName-")), TEXT(""));
|
||||
TestEqual(TEXT("success read"), ItemNodes[0]->ReadString(TEXT("Quantity-")), TEXT(""));
|
||||
TestEqual(TEXT("success read"), ItemNodes[0]->ReadString(TEXT("USPrice-")), TEXT(""));
|
||||
TestEqual(TEXT("success read"), ItemNodes[0]->ReadString(TEXT("Comment-")), TEXT(""));
|
||||
TestEqual(TEXT("success read"), ItemNodes[1]->ReadString(TEXT("@PartNumber-")), TEXT(""));
|
||||
TestEqual(TEXT("success read"), ItemNodes[1]->ReadString(TEXT("ProductName-")), TEXT(""));
|
||||
TestEqual(TEXT("success read"), ItemNodes[1]->ReadString(TEXT("Quantity-")), TEXT(""));
|
||||
TestEqual(TEXT("success read"), ItemNodes[1]->ReadString(TEXT("USPrice-")), TEXT(""));
|
||||
TestEqual(TEXT("success read"), ItemNodes[1]->ReadString(TEXT("ShipDate-")), TEXT(""));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,428 @@
|
||||
// Copyright 2019 ayumax. All Rights Reserved.
|
||||
#include "Misc/AutomationTest.h"
|
||||
#include "EasyXMLParseManager.h"
|
||||
|
||||
IMPLEMENT_SIMPLE_AUTOMATION_TEST(FReadValueTest_Int, "EasyXMLParser.ReadValueTest.Int", EAutomationTestFlags::ApplicationContextMask | EAutomationTestFlags::SmokeFilter)
|
||||
|
||||
bool FReadValueTest_Int::RunTest(const FString& Parameters)
|
||||
{
|
||||
// parse success
|
||||
{
|
||||
FString xmlString = TEXT("<root>\r")
|
||||
TEXT("<!-- comment desu -->\r")
|
||||
TEXT("<abc attr1=\"10\" attr2=\"false\">\r")
|
||||
TEXT("123\r")
|
||||
TEXT("</abc>\r")
|
||||
TEXT("</root>");
|
||||
|
||||
EEasyXMLParserErrorCode result;
|
||||
FString errorMessage;
|
||||
auto rootNode = UEasyXMLParseManager::LoadFromString(xmlString, result, errorMessage);
|
||||
|
||||
TestEqual(TEXT("success read int"), rootNode->ReadInt(TEXT("root.abc"), 0), 123);
|
||||
}
|
||||
|
||||
// parse success
|
||||
{
|
||||
FString xmlString = TEXT("<root>")
|
||||
TEXT("<abc>")
|
||||
TEXT("-123")
|
||||
TEXT("</abc>")
|
||||
TEXT("</root>");
|
||||
|
||||
EEasyXMLParserErrorCode result;
|
||||
FString errorMessage;
|
||||
auto rootNode = UEasyXMLParseManager::LoadFromString(xmlString, result, errorMessage);
|
||||
|
||||
TestEqual(TEXT("success read int"), rootNode->ReadInt(TEXT("root.abc"), 0), -123);
|
||||
}
|
||||
|
||||
// parse success
|
||||
{
|
||||
FString xmlString = TEXT("<root>")
|
||||
TEXT("<abc>")
|
||||
TEXT("123456789")
|
||||
TEXT("</abc>")
|
||||
TEXT("</root>");
|
||||
|
||||
EEasyXMLParserErrorCode result;
|
||||
FString errorMessage;
|
||||
auto rootNode = UEasyXMLParseManager::LoadFromString(xmlString, result, errorMessage);
|
||||
|
||||
|
||||
TestEqual(TEXT("success read int"), rootNode->ReadInt(TEXT("root.abc"), 0), 123456789);
|
||||
}
|
||||
|
||||
|
||||
// parse ng(string)
|
||||
{
|
||||
FString xmlString = TEXT("<root>")
|
||||
TEXT("<abc>")
|
||||
TEXT("text")
|
||||
TEXT("</abc>")
|
||||
TEXT("</root>");
|
||||
|
||||
EEasyXMLParserErrorCode result;
|
||||
FString errorMessage;
|
||||
auto rootNode = UEasyXMLParseManager::LoadFromString(xmlString, result, errorMessage);
|
||||
|
||||
|
||||
TestEqual(TEXT("ng read int(string)"), rootNode->ReadInt(TEXT("root.abc"), 0), 0);
|
||||
}
|
||||
|
||||
// parse ng(float)
|
||||
{
|
||||
FString xmlString = TEXT("<root>")
|
||||
TEXT("<abc>")
|
||||
TEXT("3.14")
|
||||
TEXT("</abc>")
|
||||
TEXT("</root>");
|
||||
|
||||
EEasyXMLParserErrorCode result;
|
||||
FString errorMessage;
|
||||
auto rootNode = UEasyXMLParseManager::LoadFromString(xmlString, result, errorMessage);
|
||||
|
||||
|
||||
TestEqual(TEXT("ng read int(float)"), rootNode->ReadInt(TEXT("root.abc"), 0), 0);
|
||||
}
|
||||
|
||||
// parse ng(xml)
|
||||
{
|
||||
FString xmlString = TEXT("<root>")
|
||||
TEXT("<abc>")
|
||||
TEXT("<def>")
|
||||
TEXT("123")
|
||||
TEXT("</def>")
|
||||
TEXT("</abc>")
|
||||
TEXT("</root>");
|
||||
|
||||
EEasyXMLParserErrorCode result;
|
||||
FString errorMessage;
|
||||
auto rootNode = UEasyXMLParseManager::LoadFromString(xmlString, result, errorMessage);
|
||||
|
||||
|
||||
TestEqual(TEXT("ng read int(xml)"), rootNode->ReadInt(TEXT("root.abc"), 0), 0);
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
IMPLEMENT_SIMPLE_AUTOMATION_TEST(FReadValueTest_Float, "EasyXMLParser.ReadValueTest.Float", EAutomationTestFlags::ApplicationContextMask | EAutomationTestFlags::SmokeFilter)
|
||||
|
||||
bool FReadValueTest_Float::RunTest(const FString& Parameters)
|
||||
{
|
||||
// parse success
|
||||
{
|
||||
FString xmlString = TEXT("<root>")
|
||||
TEXT("<abc>")
|
||||
TEXT("1.23")
|
||||
TEXT("</abc>")
|
||||
TEXT("</root>");
|
||||
|
||||
EEasyXMLParserErrorCode result;
|
||||
FString errorMessage;
|
||||
auto rootNode = UEasyXMLParseManager::LoadFromString(xmlString, result, errorMessage);
|
||||
|
||||
|
||||
TestEqual(TEXT("success read float"), rootNode->ReadFloat(TEXT("root.abc"), 0), 1.23f);
|
||||
}
|
||||
|
||||
// parse success
|
||||
{
|
||||
FString xmlString = TEXT("<root>")
|
||||
TEXT("<abc>")
|
||||
TEXT("-1.23")
|
||||
TEXT("</abc>")
|
||||
TEXT("</root>");
|
||||
|
||||
EEasyXMLParserErrorCode result;
|
||||
FString errorMessage;
|
||||
auto rootNode = UEasyXMLParseManager::LoadFromString(xmlString, result, errorMessage);
|
||||
|
||||
|
||||
TestEqual(TEXT("success read float"), rootNode->ReadFloat(TEXT("root.abc"), 0), -1.23f);
|
||||
}
|
||||
|
||||
// parse success
|
||||
{
|
||||
FString xmlString = TEXT("<root>")
|
||||
TEXT("<abc>")
|
||||
TEXT("123.456789")
|
||||
TEXT("</abc>")
|
||||
TEXT("</root>");
|
||||
|
||||
EEasyXMLParserErrorCode result;
|
||||
FString errorMessage;
|
||||
auto rootNode = UEasyXMLParseManager::LoadFromString(xmlString, result, errorMessage);
|
||||
|
||||
|
||||
TestEqual(TEXT("success read float"), rootNode->ReadFloat(TEXT("root.abc"), 0), 123.456789f);
|
||||
}
|
||||
|
||||
// parse success
|
||||
{
|
||||
FString xmlString = TEXT("<root>")
|
||||
TEXT("<abc>")
|
||||
TEXT("123")
|
||||
TEXT("</abc>")
|
||||
TEXT("</root>");
|
||||
|
||||
EEasyXMLParserErrorCode result;
|
||||
FString errorMessage;
|
||||
auto rootNode = UEasyXMLParseManager::LoadFromString(xmlString, result, errorMessage);
|
||||
|
||||
|
||||
TestEqual(TEXT("success read float"), rootNode->ReadFloat(TEXT("root.abc"), 0), 123.0f);
|
||||
}
|
||||
|
||||
|
||||
// parse ng(string)
|
||||
{
|
||||
FString xmlString = TEXT("<root>")
|
||||
TEXT("<abc>")
|
||||
TEXT("text")
|
||||
TEXT("</abc>")
|
||||
TEXT("</root>");
|
||||
|
||||
EEasyXMLParserErrorCode result;
|
||||
FString errorMessage;
|
||||
auto rootNode = UEasyXMLParseManager::LoadFromString(xmlString, result, errorMessage);
|
||||
|
||||
|
||||
TestEqual(TEXT("ng read float(string)"), rootNode->ReadFloat(TEXT("root.abc"), 0), 0.0f);
|
||||
}
|
||||
|
||||
// parse ng(xml)
|
||||
{
|
||||
FString xmlString = TEXT("<root>")
|
||||
TEXT("<abc>")
|
||||
TEXT("<def>")
|
||||
TEXT("1.23")
|
||||
TEXT("</def>")
|
||||
TEXT("</abc>")
|
||||
TEXT("</root>");
|
||||
|
||||
EEasyXMLParserErrorCode result;
|
||||
FString errorMessage;
|
||||
auto rootNode = UEasyXMLParseManager::LoadFromString(xmlString, result, errorMessage);
|
||||
|
||||
|
||||
TestEqual(TEXT("ng read float(xml)"), rootNode->ReadFloat(TEXT("root.abc"), 0), 0.0f);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
IMPLEMENT_SIMPLE_AUTOMATION_TEST(FReadValueTest_Bool, "EasyXMLParser.ReadValueTest.Bool", EAutomationTestFlags::ApplicationContextMask | EAutomationTestFlags::SmokeFilter)
|
||||
|
||||
bool FReadValueTest_Bool::RunTest(const FString& Parameters)
|
||||
{
|
||||
// parse success
|
||||
{
|
||||
FString xmlString = TEXT("<root>")
|
||||
TEXT("<abc>")
|
||||
TEXT("True")
|
||||
TEXT("</abc>")
|
||||
TEXT("</root>");
|
||||
|
||||
EEasyXMLParserErrorCode result;
|
||||
FString errorMessage;
|
||||
auto rootNode = UEasyXMLParseManager::LoadFromString(xmlString, result, errorMessage);
|
||||
|
||||
|
||||
TestEqual(TEXT("success read bool"), rootNode->ReadBool(TEXT("root.abc"), false), true);
|
||||
}
|
||||
|
||||
// parse success
|
||||
{
|
||||
FString xmlString = TEXT("<root>")
|
||||
TEXT("<abc>")
|
||||
TEXT("tRue")
|
||||
TEXT("</abc>")
|
||||
TEXT("</root>");
|
||||
|
||||
EEasyXMLParserErrorCode result;
|
||||
FString errorMessage;
|
||||
auto rootNode = UEasyXMLParseManager::LoadFromString(xmlString, result, errorMessage);
|
||||
|
||||
|
||||
TestEqual(TEXT("success read bool"), rootNode->ReadBool(TEXT("root.abc"), false), true);
|
||||
}
|
||||
|
||||
// parse success
|
||||
{
|
||||
FString xmlString = TEXT("<root>")
|
||||
TEXT("<abc>")
|
||||
TEXT("False")
|
||||
TEXT("</abc>")
|
||||
TEXT("</root>");
|
||||
|
||||
EEasyXMLParserErrorCode result;
|
||||
FString errorMessage;
|
||||
auto rootNode = UEasyXMLParseManager::LoadFromString(xmlString, result, errorMessage);
|
||||
|
||||
|
||||
TestEqual(TEXT("success read bool"), rootNode->ReadBool(TEXT("root.abc"), true), false);
|
||||
}
|
||||
|
||||
// parse success
|
||||
{
|
||||
FString xmlString = TEXT("<root>")
|
||||
TEXT("<abc>")
|
||||
TEXT("fAlse")
|
||||
TEXT("</abc>")
|
||||
TEXT("</root>");
|
||||
|
||||
EEasyXMLParserErrorCode result;
|
||||
FString errorMessage;
|
||||
auto rootNode = UEasyXMLParseManager::LoadFromString(xmlString, result, errorMessage);
|
||||
|
||||
|
||||
TestEqual(TEXT("success read bool"), rootNode->ReadBool(TEXT("root.abc"), true), false);
|
||||
}
|
||||
|
||||
|
||||
// parse ng(string)
|
||||
{
|
||||
FString xmlString = TEXT("<root>")
|
||||
TEXT("<abc>")
|
||||
TEXT("text")
|
||||
TEXT("</abc>")
|
||||
TEXT("</root>");
|
||||
|
||||
EEasyXMLParserErrorCode result;
|
||||
FString errorMessage;
|
||||
auto rootNode = UEasyXMLParseManager::LoadFromString(xmlString, result, errorMessage);
|
||||
|
||||
|
||||
TestEqual(TEXT("ng read bool(string)"), rootNode->ReadBool(TEXT("root.abc"), false), false);
|
||||
}
|
||||
|
||||
// parse ng(xml)
|
||||
{
|
||||
FString xmlString = TEXT("<root>")
|
||||
TEXT("<abc>")
|
||||
TEXT("<def>")
|
||||
TEXT("true")
|
||||
TEXT("</def>")
|
||||
TEXT("</abc>")
|
||||
TEXT("</root>");
|
||||
|
||||
EEasyXMLParserErrorCode result;
|
||||
FString errorMessage;
|
||||
auto rootNode = UEasyXMLParseManager::LoadFromString(xmlString, result, errorMessage);
|
||||
|
||||
|
||||
TestEqual(TEXT("ng read bool(xml)"), rootNode->ReadBool(TEXT("root.abc"), false), false);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
IMPLEMENT_SIMPLE_AUTOMATION_TEST(FReadValueTest_String, "EasyXMLParser.ReadValueTest.String", EAutomationTestFlags::ApplicationContextMask | EAutomationTestFlags::SmokeFilter)
|
||||
|
||||
bool FReadValueTest_String::RunTest(const FString& Parameters)
|
||||
{
|
||||
// parse success
|
||||
{
|
||||
FString xmlString = TEXT("<root>")
|
||||
TEXT("<abc>")
|
||||
TEXT("text")
|
||||
TEXT("</abc>")
|
||||
TEXT("</root>");
|
||||
|
||||
EEasyXMLParserErrorCode result;
|
||||
FString errorMessage;
|
||||
auto rootNode = UEasyXMLParseManager::LoadFromString(xmlString, result, errorMessage);
|
||||
|
||||
|
||||
TestEqual(TEXT("success read string"), rootNode->ReadString(TEXT("root.abc"), TEXT("")), TEXT("text"));
|
||||
}
|
||||
|
||||
// parse success
|
||||
{
|
||||
FString xmlString = TEXT("<root>")
|
||||
TEXT("<abc>")
|
||||
TEXT("123")
|
||||
TEXT("</abc>")
|
||||
TEXT("</root>");
|
||||
|
||||
EEasyXMLParserErrorCode result;
|
||||
FString errorMessage;
|
||||
auto rootNode = UEasyXMLParseManager::LoadFromString(xmlString, result, errorMessage);
|
||||
|
||||
|
||||
TestEqual(TEXT("success read string"), rootNode->ReadString(TEXT("root.abc"), TEXT("")), TEXT("123"));
|
||||
}
|
||||
|
||||
// parse success
|
||||
{
|
||||
FString xmlString = TEXT("<root>")
|
||||
TEXT("<abc>")
|
||||
TEXT("1.23")
|
||||
TEXT("</abc>")
|
||||
TEXT("</root>");
|
||||
|
||||
EEasyXMLParserErrorCode result;
|
||||
FString errorMessage;
|
||||
auto rootNode = UEasyXMLParseManager::LoadFromString(xmlString, result, errorMessage);
|
||||
|
||||
|
||||
TestEqual(TEXT("success read string"), rootNode->ReadString(TEXT("root.abc"), TEXT("")), TEXT("1.23"));
|
||||
}
|
||||
|
||||
// parse success
|
||||
{
|
||||
FString xmlString = TEXT("<root>")
|
||||
TEXT("<abc>")
|
||||
TEXT("true")
|
||||
TEXT("</abc>")
|
||||
TEXT("</root>");
|
||||
|
||||
EEasyXMLParserErrorCode result;
|
||||
FString errorMessage;
|
||||
auto rootNode = UEasyXMLParseManager::LoadFromString(xmlString, result, errorMessage);
|
||||
|
||||
|
||||
TestEqual(TEXT("success read string"), rootNode->ReadString(TEXT("root.abc"), TEXT("")), TEXT("true"));
|
||||
}
|
||||
|
||||
// parse success
|
||||
{
|
||||
FString xmlString = TEXT("<root>")
|
||||
TEXT("<abc>")
|
||||
TEXT("false")
|
||||
TEXT("</abc>")
|
||||
TEXT("</root>");
|
||||
|
||||
EEasyXMLParserErrorCode result;
|
||||
FString errorMessage;
|
||||
auto rootNode = UEasyXMLParseManager::LoadFromString(xmlString, result, errorMessage);
|
||||
|
||||
|
||||
TestEqual(TEXT("success read string"), rootNode->ReadString(TEXT("root.abc"), TEXT("")), TEXT("false"));
|
||||
}
|
||||
|
||||
// parse ng(xml)
|
||||
{
|
||||
FString xmlString = TEXT("<root>")
|
||||
TEXT("<abc>")
|
||||
TEXT("<def>")
|
||||
TEXT("text")
|
||||
TEXT("</def>")
|
||||
TEXT("</abc>")
|
||||
TEXT("</root>");
|
||||
|
||||
EEasyXMLParserErrorCode result;
|
||||
FString errorMessage;
|
||||
auto rootNode = UEasyXMLParseManager::LoadFromString(xmlString, result, errorMessage);
|
||||
|
||||
TestEqual(TEXT("success read string"), rootNode->ReadString(TEXT("root.abc"), TEXT("")), TEXT(""));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
// Copyright 2019 ayumax. All Rights Reserved.
|
||||
#include "CustomXMLParser.h"
|
||||
|
||||
#include "Misc/FeedbackContext.h"
|
||||
#include "EasyXMLElement.h"
|
||||
#include "EasyXMLAttribute.h"
|
||||
|
||||
CustomXMLParser::CustomXMLParser()
|
||||
{
|
||||
}
|
||||
|
||||
CustomXMLParser::~CustomXMLParser()
|
||||
{
|
||||
}
|
||||
|
||||
UEasyXMLElement *CustomXMLParser::Parse(FString xmlString, FString &ErrorMessage)
|
||||
{
|
||||
RootElement = NewObject<UEasyXMLElement>();
|
||||
XMLObjectStack.Emplace(RootElement);
|
||||
|
||||
FText _errorMessage;
|
||||
int32 _errorMessageNumber;
|
||||
|
||||
if (!FFastXml::ParseXmlFile(this, TEXT(""), &xmlString[0], nullptr, false, false, _errorMessage, _errorMessageNumber))
|
||||
{
|
||||
ErrorMessage = FString::Printf(TEXT("line=%d, %s"), _errorMessageNumber, *_errorMessage.ToString());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return RootElement;
|
||||
}
|
||||
|
||||
bool CustomXMLParser::ProcessXmlDeclaration(const TCHAR *ElementData, int32 XmlFileLineNumber)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CustomXMLParser::ProcessElement(const TCHAR *ElementName, const TCHAR *ElementData, int32 XmlFileLineNumber)
|
||||
{
|
||||
auto currentNode = XMLObjectStack.Num() > 0 ? XMLObjectStack.Last() : nullptr;
|
||||
|
||||
auto newNode = UEasyXMLElement::CreateElement(currentNode, ElementName, ElementData, XmlFileLineNumber);
|
||||
|
||||
if (currentNode)
|
||||
{
|
||||
currentNode->Children.Emplace(newNode);
|
||||
}
|
||||
|
||||
XMLObjectStack.Emplace(newNode);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CustomXMLParser::ProcessAttribute(const TCHAR *AttributeName, const TCHAR *AttributeValue)
|
||||
{
|
||||
auto currentNode = XMLObjectStack.Last();
|
||||
|
||||
if (!currentNode) return false;
|
||||
if (currentNode->Attributes.Contains(AttributeName)) return false;
|
||||
|
||||
auto newAttribute = UEasyXMLAttribute::CreateAttribute(currentNode, AttributeName, AttributeValue);
|
||||
currentNode->Attributes.Add(AttributeName, newAttribute);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CustomXMLParser::ProcessClose(const TCHAR *Element)
|
||||
{
|
||||
if (XMLObjectStack.Num() == 0) return false;
|
||||
|
||||
XMLObjectStack.RemoveAt(XMLObjectStack.Num() - 1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CustomXMLParser::ProcessComment(const TCHAR *Comment)
|
||||
{
|
||||
if (XMLObjectStack.Num() == 0) return false;
|
||||
|
||||
XMLObjectStack.Last()->Comments.Emplace(Comment);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
// Copyright 2019 ayumax. All Rights Reserved.
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "FastXml.h"
|
||||
|
||||
class UEasyXMLElement;
|
||||
|
||||
class CustomXMLParser : public IFastXmlCallback
|
||||
{
|
||||
public:
|
||||
CustomXMLParser();
|
||||
virtual ~CustomXMLParser();
|
||||
|
||||
UEasyXMLElement* Parse(FString xmlString, FString& ErrorMessage);
|
||||
|
||||
/**
|
||||
* Called after the XML's header is parsed. This is usually the first call that you'll get back.
|
||||
*
|
||||
* @param ElementData Optional data for this element, nullptr if none
|
||||
* @param XmlFileLineNumber Line number in the XML file we're on
|
||||
*
|
||||
* @return You should return true to continue processing the file, or false to stop processing immediately.
|
||||
*/
|
||||
virtual bool ProcessXmlDeclaration(const TCHAR* ElementData, int32 XmlFileLineNumber) override;
|
||||
|
||||
/**
|
||||
* Called when a new XML element is encountered, starting a new scope. You'll receive a call to ProcessClose()
|
||||
* when this element's scope has ended.
|
||||
*
|
||||
* @param ElementName The name of the element
|
||||
* @param ElementData Optional data for this element, nullptr if none
|
||||
* @param XmlFileLineNumber The line number in the XML file we're on
|
||||
*
|
||||
* @return You should return true to continue processing the file, or false to stop processing immediately.
|
||||
*/
|
||||
virtual bool ProcessElement(const TCHAR* ElementName, const TCHAR* ElementData, int32 XmlFileLineNumber) override;
|
||||
|
||||
/**
|
||||
* Called when an XML attribute is encountered for the current scope's element.
|
||||
*
|
||||
* @param AttributeName The name of the attribute
|
||||
* @param AttributeValue The value of the attribute
|
||||
*
|
||||
* @return You should return true to continue processing the file, or false to stop processing immediately.
|
||||
*/
|
||||
virtual bool ProcessAttribute(const TCHAR* AttributeName, const TCHAR* AttributeValue) override;
|
||||
|
||||
/**
|
||||
* Called when an element's scope ends in the XML file
|
||||
*
|
||||
* @param ElementName Name of the element whose scope closed
|
||||
*
|
||||
* @return You should return true to continue processing the file, or false to stop processing immediately.
|
||||
*/
|
||||
virtual bool ProcessClose(const TCHAR* Element) override;
|
||||
|
||||
/**
|
||||
* Called when a comment is encountered. This can happen pretty much anywhere in the file.
|
||||
*
|
||||
* @param Comment The comment text
|
||||
*/
|
||||
virtual bool ProcessComment(const TCHAR* Comment) override;
|
||||
|
||||
private:
|
||||
TArray<UEasyXMLElement*> XMLObjectStack;
|
||||
UEasyXMLElement* RootElement;
|
||||
};
|
||||
@@ -0,0 +1,40 @@
|
||||
// Copyright 2019 ayumax. All Rights Reserved.
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Kismet/BlueprintAsyncActionBase.h"
|
||||
#include "UObject/NoExportTypes.h"
|
||||
#include "EasyXMLElement.h"
|
||||
#include "EasyXMLAsyncLoadFromFile.generated.h"
|
||||
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FEasyXMLAsyncLoadFromFile_Result, UEasyXMLElement*, XMLObject, FString, ErrorMessage);
|
||||
|
||||
|
||||
UCLASS()
|
||||
class EASYXMLPARSER_API UEasyXMLAsyncLoadFromFile : public UBlueprintAsyncActionBase
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UPROPERTY(BlueprintAssignable)
|
||||
FEasyXMLAsyncLoadFromFile_Result Successed;
|
||||
|
||||
UPROPERTY(BlueprintAssignable)
|
||||
FEasyXMLAsyncLoadFromFile_Result Failed;
|
||||
|
||||
private:
|
||||
UPROPERTY(Transient)
|
||||
FString _XMLFile;
|
||||
UPROPERTY(Transient)
|
||||
bool _IsAblolute;
|
||||
|
||||
public:
|
||||
UEasyXMLAsyncLoadFromFile(const FObjectInitializer& ObjectInitializer);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "EasyXMLParser", meta = (WorldContext = "WorldContextObject", BlueprintInternalUseOnly = "true"))
|
||||
static UEasyXMLAsyncLoadFromFile * AsyncLoadFromFile(UObject * WorldContextObject, const FString& FilePath, bool IsAblolute);
|
||||
|
||||
|
||||
virtual void Activate() override;
|
||||
|
||||
};
|
||||
@@ -0,0 +1,38 @@
|
||||
// Copyright 2019 ayumax. All Rights Reserved.
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Kismet/BlueprintAsyncActionBase.h"
|
||||
#include "UObject/NoExportTypes.h"
|
||||
#include "EasyXMLElement.h"
|
||||
#include "EasyXMLAsyncLoadFromString.generated.h"
|
||||
|
||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FEasyXMLAsyncLoadFromString_Result, UEasyXMLElement*, XMLObject, FString, ErrorMessage);
|
||||
|
||||
|
||||
UCLASS()
|
||||
class EASYXMLPARSER_API UEasyXMLAsyncLoadFromString : public UBlueprintAsyncActionBase
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UPROPERTY(BlueprintAssignable)
|
||||
FEasyXMLAsyncLoadFromString_Result Successed;
|
||||
|
||||
UPROPERTY(BlueprintAssignable)
|
||||
FEasyXMLAsyncLoadFromString_Result Failed;
|
||||
|
||||
private:
|
||||
UPROPERTY(Transient)
|
||||
FString _XMLString;
|
||||
|
||||
public:
|
||||
UEasyXMLAsyncLoadFromString(const FObjectInitializer& ObjectInitializer);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "EasyXMLParser", meta = (WorldContext = "WorldContextObject", BlueprintInternalUseOnly = "true"))
|
||||
static UEasyXMLAsyncLoadFromString* AsyncLoadFromString(UObject * WorldContextObject, const FString& XMLString);
|
||||
|
||||
|
||||
virtual void Activate() override;
|
||||
|
||||
};
|
||||
@@ -0,0 +1,18 @@
|
||||
// Copyright 2019 ayumax. All Rights Reserved.
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "EasyXMLObject.h"
|
||||
#include "EasyXMLAttribute.generated.h"
|
||||
|
||||
class UEasyXMLElement;
|
||||
|
||||
UCLASS(BlueprintType, Blueprintable)
|
||||
class EASYXMLPARSER_API UEasyXMLAttribute : public UEasyXMLObject
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
static UEasyXMLAttribute* CreateAttribute(UEasyXMLElement* ParentObject, FString Name, FString Value);
|
||||
|
||||
};
|
||||
@@ -0,0 +1,62 @@
|
||||
// Copyright 2019 ayumax. All Rights Reserved.
|
||||
#pragma once
|
||||
|
||||
#include "EasyXMLObject.h"
|
||||
#include "EasyXMLParserEnums.h"
|
||||
#include "EasyXMLElement.generated.h"
|
||||
|
||||
class UEasyXMLAttribute;
|
||||
|
||||
UCLASS(BlueprintType, Blueprintable)
|
||||
class EASYXMLPARSER_API UEasyXMLElement : public UEasyXMLObject
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
static UEasyXMLElement* CreateElement(UEasyXMLObject* ParentObject, FString Tag, FString Content, int32 LineNumber);
|
||||
|
||||
public:
|
||||
UFUNCTION(BlueprintPure, Category = "EasyXMLParser|ReadValue")
|
||||
int32 ReadInt(const FString& AccessString, int32 DefaultValue = 0);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "EasyXMLParser|ReadValue")
|
||||
float ReadFloat(const FString& AccessString, float DefaultValue = 0.0f);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "EasyXMLParser|ReadValue")
|
||||
FString ReadString(const FString& AccessString, const FString& DefaultValue = TEXT(""));
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "EasyXMLParser|ReadValue")
|
||||
bool ReadBool(const FString& AccessString, bool DefaultValue = false);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "EasyXMLParser|ReadValue", meta = (ExpandEnumAsExecs = "Result"))
|
||||
UEasyXMLElement* ReadElement(const FString& AccessString, EEasyXMLParserFound& Result);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "EasyXMLParser|ReadValue", meta = (ExpandEnumAsExecs = "Result"))
|
||||
TArray<UEasyXMLElement*> ReadElements(const FString& AccessString, EEasyXMLParserFound& Result);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "EasyXMLParser|Object", meta = (ExpandEnumAsExecs = "Result"))
|
||||
UEasyXMLAttribute* GetAttribute(const FString& AtrributeName, EEasyXMLParserFound& Result);
|
||||
|
||||
|
||||
public:
|
||||
UEasyXMLObject* ReadEasyXMLObject(const FString& AccessString);
|
||||
TArray<UEasyXMLElement*> GetElementsByTagName(const FString& TagName);
|
||||
bool IsContainAttributeKeys(const TArray<FString>& Keys, TArray<FString>& FoundAttributeKeys);
|
||||
|
||||
private:
|
||||
bool IsAccessAsArray(const FString& AccessName, FString& ElementName, int32& ArrayIndex);
|
||||
|
||||
|
||||
public:
|
||||
UPROPERTY(BlueprintReadOnly, Category = "EasyXMLParser|Object")
|
||||
int32 LineNumber = 0;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, Category = "EasyXMLParser|Object")
|
||||
TArray<UEasyXMLElement*> Children;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, Category = "EasyXMLParser|Object")
|
||||
TMap<FString, UEasyXMLAttribute*> Attributes;
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, Category = "EasyXMLParser|Object")
|
||||
TArray<FString> Comments;
|
||||
};
|
||||
@@ -0,0 +1,37 @@
|
||||
// Copyright 2019 ayumax. All Rights Reserved.
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/NoExportTypes.h"
|
||||
#include "EasyXMLObject.generated.h"
|
||||
|
||||
|
||||
UCLASS(BlueprintType, Blueprintable)
|
||||
class EASYXMLPARSER_API UEasyXMLObject : public UObject
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UFUNCTION(BlueprintPure, Category = "EasyXMLParser|GetValue")
|
||||
int32 GetIntValue(int32 DefaultValue = 0);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "EasyXMLParser|GetValue")
|
||||
float GetFloatValue(float DefaultValue = 0.0f);
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "EasyXMLParser|GetValue")
|
||||
FString GetStringValue(FString DefaultValue = TEXT(""));
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = "EasyXMLParser|GetValue")
|
||||
bool GetBoolValue(bool DefaultValue = false);
|
||||
|
||||
public:
|
||||
UPROPERTY(BlueprintReadOnly, Category = "EasyXMLParser|Object")
|
||||
FString Name = TEXT("");
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, Category = "EasyXMLParser|Object")
|
||||
FString Value = TEXT("");
|
||||
|
||||
UPROPERTY(BlueprintReadOnly, Category = "EasyXMLParser|Object")
|
||||
UEasyXMLObject* Parent = nullptr;
|
||||
|
||||
};
|
||||
@@ -0,0 +1,36 @@
|
||||
// Copyright 2019 ayumax. All Rights Reserved.
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "UObject/NoExportTypes.h"
|
||||
#include "EasyXMLElement.h"
|
||||
#include "EasyXMLParserEnums.h"
|
||||
#include "EasyXMLParseManager.generated.h"
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UCLASS(BlueprintType, Blueprintable)
|
||||
class EASYXMLPARSER_API UEasyXMLParseManager : public UObject
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
/**
|
||||
* load xml file
|
||||
* @param FilePath - xml file path
|
||||
* @param IsAblolute - true:FilePath is absolute path, false:Relative path from "Content"
|
||||
* @return xml object
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category = "EasyXMLParser", meta = (ExpandEnumAsExecs = "Result"))
|
||||
static UEasyXMLElement* LoadFromFile(const FString& FilePath, bool IsAblolute, EEasyXMLParserErrorCode& Result, FString& ErrorMessage);
|
||||
|
||||
/**
|
||||
* load xml string
|
||||
* @param XMLString - xml file path
|
||||
* @return xml object
|
||||
*/
|
||||
UFUNCTION(BlueprintCallable, Category = "EasyXMLParser", meta = (ExpandEnumAsExecs = "Result"))
|
||||
static UEasyXMLElement* LoadFromString(const FString& XMLString, EEasyXMLParserErrorCode& Result, FString& ErrorMessage);
|
||||
|
||||
};
|
||||
@@ -0,0 +1,15 @@
|
||||
// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Modules/ModuleManager.h"
|
||||
|
||||
class FEasyXMLParserModule : public IModuleInterface
|
||||
{
|
||||
public:
|
||||
|
||||
/** IModuleInterface implementation */
|
||||
virtual void StartupModule() override;
|
||||
virtual void ShutdownModule() override;
|
||||
};
|
||||
@@ -0,0 +1,19 @@
|
||||
// Copyright 2019 ayumax. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class EEasyXMLParserErrorCode : uint8
|
||||
{
|
||||
Successed,
|
||||
Failed
|
||||
};
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class EEasyXMLParserFound : uint8
|
||||
{
|
||||
Found,
|
||||
NotFound
|
||||
};
|
||||
Binary file not shown.
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"BuildId": "23058290",
|
||||
"Modules":
|
||||
{
|
||||
"JPrinter": "UnrealEditor-JPrinter.dll"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"FileVersion": 3,
|
||||
"Version": 1,
|
||||
"VersionName": "1.0",
|
||||
"FriendlyName": "JPrinter",
|
||||
"Description": "Now you can print picture from unreal direcly!, you print from file or even print a texture, only for windows, soon mac ox",
|
||||
"Category": "Hardware",
|
||||
"CreatedBy": "ZKarmaKun",
|
||||
"CreatedByURL": "",
|
||||
"DocsURL": "",
|
||||
"MarketplaceURL": "",
|
||||
"SupportURL": "",
|
||||
"EngineVersion": "5.1.0",
|
||||
"CanContainContent": false,
|
||||
"Installed": true,
|
||||
"Modules": [
|
||||
{
|
||||
"Name": "JPrinter",
|
||||
"Type": "Runtime",
|
||||
"LoadingPhase": "Default"
|
||||
}
|
||||
]
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 32 KiB |
@@ -0,0 +1,69 @@
|
||||
// Some copyright should be here...
|
||||
|
||||
using UnrealBuildTool;
|
||||
using System.IO;
|
||||
|
||||
public class JPrinter : ModuleRules
|
||||
{
|
||||
public JPrinter(ReadOnlyTargetRules Target): base( Target )
|
||||
{
|
||||
|
||||
PublicIncludePaths.AddRange(
|
||||
new string[] {
|
||||
"JPrinter/Public"
|
||||
|
||||
// ... add public include paths required here ...
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
PrivateIncludePaths.AddRange(
|
||||
new string[] {
|
||||
"JPrinter/Private",
|
||||
|
||||
// ... add other private include paths required here ...
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
PublicDependencyModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
"Core",
|
||||
|
||||
// ... add other public dependencies that you statically link with here ...
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
PrivateDependencyModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
"CoreUObject",
|
||||
"Engine",
|
||||
"Slate",
|
||||
"SlateCore",
|
||||
"ImageWrapper",
|
||||
// ... add private dependencies that you statically link with here ...
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
DynamicallyLoadedModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
// ... add any modules that your module loads dynamically here ...
|
||||
}
|
||||
);
|
||||
|
||||
//string ModulePath = Path.GetDirectoryName(RulesCompiler.GetModuleFilename(this.GetType().Name));
|
||||
/*
|
||||
string ThirdParty = Path.GetFullPath(Path.Combine(ModuleDirectory, "../../ThirdParty/"));
|
||||
|
||||
string IncludePaths = Path.Combine(ThirdParty, "opencv", "include");
|
||||
string LibPath = Path.Combine(ThirdParty, "opencv", "lib");
|
||||
PublicIncludePaths.Add(IncludePaths);
|
||||
PublicAdditionalLibraries.Add(LibPath + "/opencv_world300.lib");
|
||||
PublicAdditionalLibraries.Add(LibPath + "/opencv_ts300.lib");*/
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
|
||||
#include "JPrinter.h"
|
||||
#include "JPrinterPrivatePCH.h"
|
||||
|
||||
#define LOCTEXT_NAMESPACE "FJPrinterModule"
|
||||
|
||||
void FJPrinterModule::StartupModule()
|
||||
{
|
||||
// This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module
|
||||
|
||||
}
|
||||
|
||||
void FJPrinterModule::ShutdownModule()
|
||||
{
|
||||
// This function may be called during shutdown to clean up your module. For modules that support dynamic reloading,
|
||||
// we call this function before unloading the module.
|
||||
|
||||
}
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
|
||||
IMPLEMENT_MODULE(FJPrinterModule, JPrinter)
|
||||
@@ -0,0 +1,266 @@
|
||||
// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
|
||||
#include "JPrinterBPLibrary.h"
|
||||
#include "JPrinterPrivatePCH.h"
|
||||
|
||||
#define print(txt) GEngine->AddOnScreenDebugMessage(-1,10,FColor::Green, txt)
|
||||
DEFINE_LOG_CATEGORY_STATIC(JPrinterLog, Log, All);
|
||||
|
||||
UJPrinterBPLibrary::UJPrinterBPLibrary(const FObjectInitializer& ObjectInitializer)
|
||||
: Super(ObjectInitializer)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
TArray<FString> UJPrinterBPLibrary::getPrinterList()
|
||||
{
|
||||
TArray<FString> out;
|
||||
#if PLATFORM_WINDOWS
|
||||
LPBYTE pPrinterEnum;
|
||||
unsigned long pcbNeeded, pcbReturned;
|
||||
PRINTER_INFO_2* printerInfo = NULL;
|
||||
EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &pcbNeeded, &pcbReturned);
|
||||
|
||||
pPrinterEnum = new BYTE[pcbNeeded];
|
||||
if (EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 2, pPrinterEnum, pcbNeeded, &pcbNeeded, &pcbReturned))
|
||||
{
|
||||
printerInfo = ((PRINTER_INFO_2*)pPrinterEnum);
|
||||
for (unsigned short i = 0; i < pcbReturned; i++)
|
||||
{
|
||||
TCHAR* wname = printerInfo[i].pPrinterName;
|
||||
FString name = wname;
|
||||
out.Add(name);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return out;
|
||||
}
|
||||
|
||||
FString UJPrinterBPLibrary::getPrimaryPrinterName()
|
||||
{
|
||||
FString out;
|
||||
#if PLATFORM_WINDOWS
|
||||
unsigned long size = 0;
|
||||
GetDefaultPrinter(NULL, &size);
|
||||
if (size)
|
||||
{
|
||||
TCHAR* buffer = new TCHAR[size];
|
||||
GetDefaultPrinter(buffer, &size);
|
||||
out = buffer;
|
||||
}
|
||||
#endif
|
||||
return out;
|
||||
}
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
printerInfo UJPrinterBPLibrary::getPrinterInfo(FString printer, bool usePrimary)
|
||||
{
|
||||
printerInfo out;
|
||||
unsigned long size = 0;
|
||||
LPWSTR defaultName = NULL;
|
||||
GetDefaultPrinter(NULL, &size);
|
||||
if (size)
|
||||
{
|
||||
TCHAR* buffer = new TCHAR[size];
|
||||
GetDefaultPrinter(buffer, &size);
|
||||
defaultName = buffer;
|
||||
}
|
||||
|
||||
if (defaultName)
|
||||
{
|
||||
out.deviceName = defaultName;
|
||||
LPBYTE pPrinterEnum;
|
||||
unsigned long pcbNeeded, pcbReturned;
|
||||
PRINTER_INFO_2* printerInfo = NULL;
|
||||
EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 2, NULL, 0, &pcbNeeded, &pcbReturned);
|
||||
|
||||
pPrinterEnum = new BYTE[pcbNeeded];
|
||||
if (EnumPrinters(PRINTER_ENUM_LOCAL, NULL, 2, pPrinterEnum, pcbNeeded, &pcbNeeded, &pcbReturned))
|
||||
{
|
||||
printerInfo = ((PRINTER_INFO_2*)pPrinterEnum);
|
||||
std::wstring wsdefaultName(defaultName);
|
||||
std::string sdefaultName(wsdefaultName.begin(), wsdefaultName.end());
|
||||
|
||||
for (unsigned int i = 0; i < pcbReturned; i++)
|
||||
{
|
||||
LPWSTR name = printerInfo[i].pPrinterName;
|
||||
std::wstring wsname(name);
|
||||
std::string sname(wsname.begin(), wsname.end());
|
||||
if (usePrimary)
|
||||
{
|
||||
if (sname == sdefaultName)
|
||||
{
|
||||
out.driver = printerInfo[i].pDriverName;
|
||||
out.portName = printerInfo[i].pPortName;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string choosen(TCHAR_TO_ANSI(*printer));
|
||||
if (sname == choosen)
|
||||
{
|
||||
out.driver = printerInfo[i].pDriverName;
|
||||
out.portName = printerInfo[i].pPortName;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
HBITMAP UJPrinterBPLibrary::getHBITMAPFromData(TArray<FColor>& bgraData, int32 width, int32 height, int32 bitDepth)
|
||||
{
|
||||
if (bgraData.Num() <= 0) return NULL;
|
||||
|
||||
uint8* rgb = new uint8[width * height * 3];
|
||||
for (int i = 0; i < (width * height); i++)
|
||||
{
|
||||
rgb[3 * i + 0] = bgraData[i].B;
|
||||
rgb[3 * i + 1] = bgraData[i].G;
|
||||
rgb[3 * i + 2] = bgraData[i].R;
|
||||
}
|
||||
// Create DIB
|
||||
HBITMAP hbmp = CreateBitmap(width, height, 1, 24, rgb);
|
||||
if (hbmp == NULL) {
|
||||
delete rgb;
|
||||
return hbmp;
|
||||
}
|
||||
delete rgb;
|
||||
return hbmp;
|
||||
}
|
||||
#endif
|
||||
|
||||
FString UJPrinterBPLibrary::Replace(FString source, FString in, FString out)
|
||||
{
|
||||
TArray<TCHAR> ar = source.GetCharArray();
|
||||
FString result;
|
||||
for (int i = 0; i < ar.Num(); i++)
|
||||
{
|
||||
if (ar[i] != in[0])
|
||||
{
|
||||
result += ar[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
result += out;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool UJPrinterBPLibrary::printImage(FString path, FString printer, bool usePrimary)
|
||||
{
|
||||
if (!FPaths::FileExists(path)) {
|
||||
UE_LOG(JPrinterLog, Log, TEXT("%s"), *path)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (usePrimary)
|
||||
{
|
||||
printer = getPrimaryPrinterName();
|
||||
}
|
||||
|
||||
path = "\"" + path + "\"";
|
||||
path = Replace(path, "/", "\\");
|
||||
FString args = " c:\\WINDOWS\\system32\\shimgvw.dll,ImageView_PrintTo /pt " + path + " \"" + printer + "\"";
|
||||
FString prg = "rundll32";
|
||||
UE_LOG(JPrinterLog, Log, TEXT("%s%s"), *prg,*args);
|
||||
int error=33; //= WinExec(TCHAR_TO_ANSI(*fullPath), SW_SHOW);
|
||||
FPlatformProcess::CreateProc(
|
||||
*prg,
|
||||
*args,
|
||||
false,//* @param bLaunchDetached if true, the new process will have its own window
|
||||
false,//* @param bLaunchHidded if true, the new process will be minimized in the task bar
|
||||
false,//* @param bLaunchReallyHidden if true, the new process will not have a window or be in the task bar
|
||||
0,
|
||||
0,
|
||||
nullptr,//const TCHAR* OptionalWorkingDirectory,
|
||||
nullptr
|
||||
);
|
||||
return (error == 33) ? true : false;
|
||||
}
|
||||
|
||||
bool UJPrinterBPLibrary::printTexture2D(UTexture2D* texture, FString printer, bool usePrimary, EPaperSize paperSize)
|
||||
{
|
||||
if (!texture) return false;
|
||||
|
||||
//const double DPIConvertion = 142.0643729189789;
|
||||
//const float DPIConvertion = 142.0643729189789f;
|
||||
const float DPIConvertion = 142.06437f;
|
||||
|
||||
bool out = false;
|
||||
int32 width = texture->GetSizeX();
|
||||
int32 height = texture->GetSizeY();
|
||||
int32 bitDepth = 24;
|
||||
TArray<FColor> colorData;
|
||||
colorData.Init(FColor(), width * height);
|
||||
FTexture2DMipMap& Mip = texture->PlatformData->Mips[0];
|
||||
uint8* Data = (uint8*)Mip.BulkData.Lock(LOCK_READ_WRITE);
|
||||
|
||||
for (int i = 0; i < colorData.Num(); i++)
|
||||
{
|
||||
colorData[i].R = Data[4 * i + 2];
|
||||
colorData[i].G = Data[4 * i + 1];
|
||||
colorData[i].B = Data[4 * i + 0];
|
||||
colorData[i].A = 255;
|
||||
}
|
||||
|
||||
Mip.BulkData.Unlock();
|
||||
texture->UpdateResource();
|
||||
|
||||
if (paperSize != EPaperSize::None)
|
||||
{
|
||||
|
||||
float scale = 1;
|
||||
switch (paperSize)
|
||||
{
|
||||
case EPaperSize::letter:
|
||||
if (width == 2969) break;
|
||||
scale = FMath::FloorToFloat((2969.f / width) * 100) / 100.f;
|
||||
break;
|
||||
case EPaperSize::photo:
|
||||
if (width == 1373) break;
|
||||
scale = FMath::FloorToFloat((1373.f / width) * 1000) / 1000.f;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (scale != 1)
|
||||
{
|
||||
TArray<FColor> fixColorData;
|
||||
FImageUtils::ImageResize(width, height, colorData, width * scale, height * scale, fixColorData, true);
|
||||
width = width * scale;
|
||||
height = height * scale;
|
||||
colorData = fixColorData;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
HWND currentWindow = GetActiveWindow();
|
||||
printerInfo dev = getPrinterInfo(printer, usePrimary);
|
||||
|
||||
HBITMAP hBMP = getHBITMAPFromData(colorData, width, height, bitDepth);
|
||||
//HBITMAP hBMP = (HBITMAP)LoadImage(NULL, L"D:/gokuHQ.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
|
||||
HDC printerHDC = CreateDC(dev.driver, dev.deviceName, dev.portName, NULL);
|
||||
if (printerHDC)
|
||||
{
|
||||
HDC hdc = CreateCompatibleDC(printerHDC);
|
||||
SelectObject(hdc, hBMP);
|
||||
Escape(printerHDC, STARTDOC, 8, "Happy-Doc", NULL);
|
||||
BitBlt(printerHDC, 0, 0, width, height, hdc, 0, 0, SRCCOPY2);
|
||||
Escape(printerHDC, NEWFRAME, 0, NULL, NULL);
|
||||
Escape(printerHDC, ENDDOC, 0, NULL, NULL);
|
||||
|
||||
UE_LOG(JPrinterLog,Log, TEXT("Printing... wPX=%i hPX=%i"), width, height);
|
||||
|
||||
DeleteDC(printerHDC);
|
||||
out = true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return out;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#include "JPrinter.h"
|
||||
|
||||
// You should place include statements to your module's private header files here. You only need to
|
||||
// add includes for headers that are used in most of your module's source files though.
|
||||
@@ -0,0 +1,14 @@
|
||||
// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Modules/ModuleManager.h"
|
||||
|
||||
class FJPrinterModule : public IModuleInterface
|
||||
{
|
||||
public:
|
||||
|
||||
/** IModuleInterface implementation */
|
||||
virtual void StartupModule() override;
|
||||
virtual void ShutdownModule() override;
|
||||
};
|
||||
@@ -0,0 +1,69 @@
|
||||
// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
#if PLATFORM_WINDOWS
|
||||
#include "Windows/AllowWindowsPlatformTypes.h"
|
||||
#include "Windows.h"
|
||||
#include "winspool.h"
|
||||
#include "iostream"
|
||||
#include "time.h"
|
||||
#include "fstream"
|
||||
#include "string"
|
||||
#include "Windows/HideWindowsPlatformTypes.h"
|
||||
#endif
|
||||
#include "Engine.h"
|
||||
#include "ImageUtils.h"
|
||||
|
||||
//opencv
|
||||
//#include "opencv/cv.hpp"
|
||||
|
||||
#include "JPrinterBPLibrary.generated.h"
|
||||
|
||||
//using namespace cv;
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
struct printerInfo
|
||||
{
|
||||
LPCWSTR portName;
|
||||
LPCWSTR driver;
|
||||
LPCWSTR deviceName;
|
||||
LPCWSTR output = NULL;
|
||||
};
|
||||
#define SRCCOPY2 (unsigned long)0x00CC0020
|
||||
#endif
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class EPaperSize : uint8
|
||||
{
|
||||
None UMETA(DisplayName = "None"),
|
||||
letter UMETA(DisplayName = "Letter 8 1/2 x 11 in"),
|
||||
photo UMETA(DisplayName = "Photo 4 x 6 in"),
|
||||
};
|
||||
|
||||
UCLASS()
|
||||
class UJPrinterBPLibrary : public UBlueprintFunctionLibrary
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
public:
|
||||
UFUNCTION(BlueprintPure, Category = JPrinter)
|
||||
static TArray<FString> getPrinterList();
|
||||
|
||||
UFUNCTION(BlueprintPure, Category = JPrinter)
|
||||
static FString getPrimaryPrinterName();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = JPrinter)
|
||||
static bool printImage(FString path, FString printer, bool usePrimary = true);
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = JPrinter)
|
||||
static bool printTexture2D(UTexture2D* texture, FString printer, bool usePrimary, EPaperSize paperSize = EPaperSize::None);
|
||||
|
||||
|
||||
static FString Replace(FString source, FString in, FString out);
|
||||
|
||||
#if PLATFORM_WINDOWS
|
||||
static printerInfo getPrinterInfo(FString printer, bool usePrimary);
|
||||
static HBITMAP getHBITMAPFromData(TArray<FColor>& bgraData, int32 width, int32 height, int32 bitDepth);
|
||||
#endif
|
||||
|
||||
};
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"BuildId": "23058290",
|
||||
"Modules":
|
||||
{
|
||||
"createProcess": "UnrealEditor-createProcess.dll"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 28 KiB |
@@ -0,0 +1,22 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#include "createProcess.h"
|
||||
|
||||
#define LOCTEXT_NAMESPACE "FcreateProcessModule"
|
||||
|
||||
void FcreateProcessModule::StartupModule()
|
||||
{
|
||||
// This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module
|
||||
|
||||
}
|
||||
|
||||
void FcreateProcessModule::ShutdownModule()
|
||||
{
|
||||
// This function may be called during shutdown to clean up your module. For modules that support dynamic reloading,
|
||||
// we call this function before unloading the module.
|
||||
|
||||
}
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
|
||||
IMPLEMENT_MODULE(FcreateProcessModule, createProcess)
|
||||
@@ -0,0 +1,46 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#include "createProcessBPLibrary.h"
|
||||
#include "createProcess.h"
|
||||
|
||||
UcreateProcessBPLibrary::UcreateProcessBPLibrary(const FObjectInitializer& ObjectInitializer)
|
||||
: Super(ObjectInitializer)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void UcreateProcessBPLibrary::createProc(FString FullPathOfProgramToRun, TArray<FString> CommandlineArgs, bool Detach, bool Hidden, int32 Priority, FString OptionalWorkingDirectory)
|
||||
{ //Please note ProcessId should really be uint32 but that is not supported by BP yet
|
||||
|
||||
FString Args = "";
|
||||
if (CommandlineArgs.Num() > 1)
|
||||
{
|
||||
Args = CommandlineArgs[0];
|
||||
for (int32 v = 1; v < CommandlineArgs.Num(); v++)
|
||||
{
|
||||
Args += " " + CommandlineArgs[v];
|
||||
}
|
||||
}
|
||||
else if (CommandlineArgs.Num() > 0)
|
||||
{
|
||||
Args = CommandlineArgs[0];
|
||||
}
|
||||
|
||||
//uint32 NeedBPUINT32 = 0;
|
||||
FPlatformProcess::CreateProc(
|
||||
*FullPathOfProgramToRun,
|
||||
*Args,
|
||||
Detach,//* @param bLaunchDetached if true, the new process will have its own window
|
||||
false,//* @param bLaunchHidded if true, the new process will be minimized in the task bar
|
||||
Hidden,//* @param bLaunchReallyHidden if true, the new process will not have a window or be in the task bar
|
||||
0,
|
||||
Priority,
|
||||
(OptionalWorkingDirectory != "") ? *OptionalWorkingDirectory : nullptr,//const TCHAR* OptionalWorkingDirectory,
|
||||
nullptr
|
||||
);
|
||||
}
|
||||
|
||||
void UcreateProcessBPLibrary::RunSystemCommand(FString Command)
|
||||
{
|
||||
system(TCHAR_TO_ANSI(*Command));
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Modules/ModuleManager.h"
|
||||
|
||||
class FcreateProcessModule : public IModuleInterface
|
||||
{
|
||||
public:
|
||||
|
||||
/** IModuleInterface implementation */
|
||||
virtual void StartupModule() override;
|
||||
virtual void ShutdownModule() override;
|
||||
};
|
||||
@@ -0,0 +1,36 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||
#include "GenericPlatform/GenericPlatformProcess.h"
|
||||
#include "createProcessBPLibrary.generated.h"
|
||||
|
||||
/*
|
||||
* Function library class.
|
||||
* Each function in it is expected to be static and represents blueprint node that can be called in any blueprint.
|
||||
*
|
||||
* When declaring function you can define metadata for the node. Key function specifiers will be BlueprintPure and BlueprintCallable.
|
||||
* BlueprintPure - means the function does not affect the owning object in any way and thus creates a node without Exec pins.
|
||||
* BlueprintCallable - makes a function which can be executed in Blueprints - Thus it has Exec pins.
|
||||
* DisplayName - full name of the node, shown when you mouse over the node and in the blueprint drop down menu.
|
||||
* Its lets you name the node using characters not allowed in C++ function names.
|
||||
* CompactNodeTitle - the word(s) that appear on the node.
|
||||
* Keywords - the list of keywords that helps you to find node when you search for it using Blueprint drop-down menu.
|
||||
* Good example is "Print String" node which you can find also by using keyword "log".
|
||||
* Category - the category your node will be under in the Blueprint drop-down menu.
|
||||
*
|
||||
* For more info on custom blueprint nodes visit documentation:
|
||||
* https://wiki.unrealengine.com/Custom_Blueprint_Node_Creation
|
||||
*/
|
||||
UCLASS()
|
||||
class UcreateProcessBPLibrary : public UBlueprintFunctionLibrary
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "createProcess")
|
||||
static void createProc(FString FullPathOfProgramToRun, TArray<FString> CommandlineArgs, bool Detach, bool Hidden, int32 Priority, FString OptionalWorkingDirectory);
|
||||
UFUNCTION(BlueprintCallable, Category = "createProcess")
|
||||
static void RunSystemCommand(FString Command);
|
||||
};
|
||||
@@ -0,0 +1,53 @@
|
||||
// Some copyright should be here...
|
||||
|
||||
using UnrealBuildTool;
|
||||
|
||||
public class createProcess : ModuleRules
|
||||
{
|
||||
public createProcess(ReadOnlyTargetRules Target) : base(Target)
|
||||
{
|
||||
PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
|
||||
|
||||
PublicIncludePaths.AddRange(
|
||||
new string[] {
|
||||
// ... add public include paths required here ...
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
PrivateIncludePaths.AddRange(
|
||||
new string[] {
|
||||
// ... add other private include paths required here ...
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
PublicDependencyModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
"Core",
|
||||
// ... add other public dependencies that you statically link with here ...
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
PrivateDependencyModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
"CoreUObject",
|
||||
"Engine",
|
||||
"Slate",
|
||||
"SlateCore",
|
||||
// ... add private dependencies that you statically link with here ...
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
DynamicallyLoadedModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
// ... add any modules that your module loads dynamically here ...
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"FileVersion": 3,
|
||||
"Version": 1,
|
||||
"VersionName": "1.0",
|
||||
"FriendlyName": "createProcess",
|
||||
"Description": "",
|
||||
"Category": "Process",
|
||||
"CreatedBy": "Dron",
|
||||
"CreatedByURL": "",
|
||||
"DocsURL": "",
|
||||
"MarketplaceURL": "",
|
||||
"SupportURL": "",
|
||||
"EngineVersion": "5.1.0",
|
||||
"CanContainContent": false,
|
||||
"Installed": true,
|
||||
"Modules": [
|
||||
{
|
||||
"Name": "createProcess",
|
||||
"Type": "Runtime",
|
||||
"LoadingPhase": "PostEngineInit",
|
||||
"WhitelistPlatforms": [
|
||||
"Win64"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"BuildId": "23058290",
|
||||
"Modules":
|
||||
{
|
||||
"manageTextFile": "UnrealEditor-manageTextFile.dll"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 2.0 KiB |
@@ -0,0 +1,22 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#include "manageTextFile.h"
|
||||
|
||||
#define LOCTEXT_NAMESPACE "FmanageTextFileModule"
|
||||
|
||||
void FmanageTextFileModule::StartupModule()
|
||||
{
|
||||
// This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module
|
||||
|
||||
}
|
||||
|
||||
void FmanageTextFileModule::ShutdownModule()
|
||||
{
|
||||
// This function may be called during shutdown to clean up your module. For modules that support dynamic reloading,
|
||||
// we call this function before unloading the module.
|
||||
|
||||
}
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
|
||||
IMPLEMENT_MODULE(FmanageTextFileModule, manageTextFile)
|
||||
@@ -0,0 +1,75 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#include "manageTextFileBPLibrary.h"
|
||||
#include "manageTextFile.h"
|
||||
|
||||
UmanageTextFileBPLibrary::UmanageTextFileBPLibrary(const FObjectInitializer& ObjectInitializer)
|
||||
: Super(ObjectInitializer)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool UmanageTextFileBPLibrary::CreateTextFile(FString Path, FString FileName, FString Text)
|
||||
{
|
||||
if (Path == "" || FileName == "") {
|
||||
UE_LOG(LogTemp, Warning, TEXT("Empty Path or FileName, aborting"));
|
||||
return false;
|
||||
}
|
||||
Path.ReplaceInline(TEXT("/"), TEXT("\\"));
|
||||
FString fullpath(Path + "\\" + FileName);
|
||||
return FFileHelper::SaveStringToFile(Text, *fullpath, FFileHelper::EEncodingOptions::ForceUTF8);
|
||||
}
|
||||
|
||||
bool UmanageTextFileBPLibrary::AppendStringToFile(FString Path, FString FileName, FString Text)
|
||||
{
|
||||
if (Path == "" || FileName == "") {
|
||||
UE_LOG(LogTemp, Warning, TEXT("Empty Path or FileName, aborting"));
|
||||
return false;
|
||||
}
|
||||
Path.ReplaceInline(TEXT("/"), TEXT("\\"));
|
||||
FString fullpath(Path + "\\" + FileName);
|
||||
|
||||
FString OldText;
|
||||
if (FPaths::FileExists(fullpath))
|
||||
{
|
||||
FFileHelper::LoadFileToString(OldText, *fullpath);
|
||||
OldText += Text;
|
||||
return FFileHelper::SaveStringToFile(Text, *fullpath, FFileHelper::EEncodingOptions::ForceUTF8, &IFileManager::Get(), FILEWRITE_Append);
|
||||
}
|
||||
else
|
||||
{
|
||||
return CreateTextFile(Path, FileName, Text);
|
||||
}
|
||||
}
|
||||
|
||||
bool UmanageTextFileBPLibrary::FileExists(FString Path, FString FileName)
|
||||
{
|
||||
if (Path == "" || FileName == "") {
|
||||
UE_LOG(LogTemp, Warning, TEXT("Empty Path or FileName, aborting"));
|
||||
return false;
|
||||
}
|
||||
Path.ReplaceInline(TEXT("/"), TEXT("\\"));
|
||||
return FPaths::FileExists(Path + "\\" + FileName);
|
||||
}
|
||||
|
||||
bool UmanageTextFileBPLibrary::DeleteFile(FString Path, FString FileName)
|
||||
{
|
||||
if (Path == "" || FileName == "") {
|
||||
UE_LOG(LogTemp, Warning, TEXT("Empty Path or FileName, aborting"));
|
||||
return false;
|
||||
}
|
||||
Path.ReplaceInline(TEXT("/"), TEXT("\\"));
|
||||
FString fullpath = Path + "\\" + FileName;
|
||||
return FPlatformFileManager::Get().GetPlatformFile().DeleteFile(*fullpath);
|
||||
}
|
||||
|
||||
bool UmanageTextFileBPLibrary::readFile(FString Path, FString FileName,FString &Str) {
|
||||
if (Path == "" || FileName == "") {
|
||||
UE_LOG(LogTemp, Warning, TEXT("Empty Path or FileName, aborting"));
|
||||
return false;
|
||||
}
|
||||
|
||||
FString fullpath = Path + "\\" + FileName;
|
||||
return FFileHelper::LoadFileToString(Str, *fullpath);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Modules/ModuleManager.h"
|
||||
|
||||
class FmanageTextFileModule : public IModuleInterface
|
||||
{
|
||||
public:
|
||||
|
||||
/** IModuleInterface implementation */
|
||||
virtual void StartupModule() override;
|
||||
virtual void ShutdownModule() override;
|
||||
};
|
||||
@@ -0,0 +1,43 @@
|
||||
// Copyright Epic Games, Inc. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||
#include "Misc/FileHelper.h"
|
||||
#include "Misc/Paths.h"
|
||||
#include "HAL/PlatformFilemanager.h"
|
||||
#include "manageTextFileBPLibrary.generated.h"
|
||||
|
||||
/*
|
||||
* Function library class.
|
||||
* Each function in it is expected to be static and represents blueprint node that can be called in any blueprint.
|
||||
*
|
||||
* When declaring function you can define metadata for the node. Key function specifiers will be BlueprintPure and BlueprintCallable.
|
||||
* BlueprintPure - means the function does not affect the owning object in any way and thus creates a node without Exec pins.
|
||||
* BlueprintCallable - makes a function which can be executed in Blueprints - Thus it has Exec pins.
|
||||
* DisplayName - full name of the node, shown when you mouse over the node and in the blueprint drop down menu.
|
||||
* Its lets you name the node using characters not allowed in C++ function names.
|
||||
* CompactNodeTitle - the word(s) that appear on the node.
|
||||
* Keywords - the list of keywords that helps you to find node when you search for it using Blueprint drop-down menu.
|
||||
* Good example is "Print String" node which you can find also by using keyword "log".
|
||||
* Category - the category your node will be under in the Blueprint drop-down menu.
|
||||
*
|
||||
* For more info on custom blueprint nodes visit documentation:
|
||||
* https://wiki.unrealengine.com/Custom_Blueprint_Node_Creation
|
||||
*/
|
||||
UCLASS()
|
||||
class UmanageTextFileBPLibrary : public UBlueprintFunctionLibrary
|
||||
{
|
||||
GENERATED_UCLASS_BODY()
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category = "manageTextFile")
|
||||
static bool CreateTextFile(FString Path, FString FileName, FString Text);
|
||||
UFUNCTION(BlueprintCallable, Category = "manageTextFile")
|
||||
static bool AppendStringToFile(FString Path, FString FileName, FString Text);
|
||||
UFUNCTION(BlueprintCallable, Category = "manageTextFile")
|
||||
static bool FileExists(FString Path, FString FileName);
|
||||
UFUNCTION(BlueprintCallable, Category = "manageTextFile")
|
||||
static bool DeleteFile(FString Path, FString FileName);
|
||||
UFUNCTION(BlueprintCallable, Category = "manageTextFile")
|
||||
static bool readFile(FString Path, FString FileName, FString & Str);
|
||||
};
|
||||
@@ -0,0 +1,53 @@
|
||||
// Some copyright should be here...
|
||||
|
||||
using UnrealBuildTool;
|
||||
|
||||
public class manageTextFile : ModuleRules
|
||||
{
|
||||
public manageTextFile(ReadOnlyTargetRules Target) : base(Target)
|
||||
{
|
||||
PCHUsage = ModuleRules.PCHUsageMode.UseExplicitOrSharedPCHs;
|
||||
|
||||
PublicIncludePaths.AddRange(
|
||||
new string[] {
|
||||
// ... add public include paths required here ...
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
PrivateIncludePaths.AddRange(
|
||||
new string[] {
|
||||
// ... add other private include paths required here ...
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
PublicDependencyModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
"Core",
|
||||
// ... add other public dependencies that you statically link with here ...
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
PrivateDependencyModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
"CoreUObject",
|
||||
"Engine",
|
||||
"Slate",
|
||||
"SlateCore",
|
||||
// ... add private dependencies that you statically link with here ...
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
DynamicallyLoadedModuleNames.AddRange(
|
||||
new string[]
|
||||
{
|
||||
// ... add any modules that your module loads dynamically here ...
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"FileVersion": 3,
|
||||
"Version": 1,
|
||||
"VersionName": "1.0",
|
||||
"FriendlyName": "manageTextFile",
|
||||
"Description": "",
|
||||
"Category": "fileIO",
|
||||
"CreatedBy": "Dron",
|
||||
"CreatedByURL": "",
|
||||
"DocsURL": "",
|
||||
"MarketplaceURL": "",
|
||||
"SupportURL": "",
|
||||
"CanContainContent": false,
|
||||
"Installed": true,
|
||||
"Modules": [
|
||||
{
|
||||
"Name": "manageTextFile",
|
||||
"Type": "Runtime",
|
||||
"LoadingPhase": "PostEngineInit",
|
||||
"WhitelistPlatforms": [
|
||||
"Win64"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user