Browse Source

iOS deployment from editor working

Josh Engebretson 10 years ago
parent
commit
2f5b9eefd7

+ 0 - 0
Data/AtomicEditor/Tools/.gitkeep


+ 1 - 0
Rakefile

@@ -118,6 +118,7 @@ namespace :build  do
 
 
       Dir.chdir(CMAKE_IOS_BUILD_FOLDER) do
       Dir.chdir(CMAKE_IOS_BUILD_FOLDER) do
         sh "#{ATOMICTOOL_BIN_MACOSX} bind #{$RAKE_ROOT} Script/Packages/Atomic/ IOS"
         sh "#{ATOMICTOOL_BIN_MACOSX} bind #{$RAKE_ROOT} Script/Packages/Atomic/ IOS"
+        sh "#{ATOMICTOOL_BIN_MACOSX} bind #{$RAKE_ROOT} Script/Packages/AtomicPlayer/ IOS"
         sh "cmake -DIOS=1 -DCMAKE_BUILD_TYPE=Release -G Xcode ../../"
         sh "cmake -DIOS=1 -DCMAKE_BUILD_TYPE=Release -G Xcode ../../"
         # the -s option adds $KEYCHAIN to the search scope, while the -d option adds $KEYCHAIN to the system domain; both are needed
         # the -s option adds $KEYCHAIN to the search scope, while the -d option adds $KEYCHAIN to the system domain; both are needed
         sh "security -v list-keychains -d system -s /Users/jenkins/Library/Keychains/codesign.keychain"
         sh "security -v list-keychains -d system -s /Users/jenkins/Library/Keychains/codesign.keychain"

+ 1 - 3
Script/AtomicEditor/ui/modal/build/platforms/IOSSettingsWidget.ts

@@ -55,9 +55,7 @@ class IOSSettingsWidget extends Atomic.UIWidget {
                     this.provisionPathEdit.text = path;
                     this.provisionPathEdit.text = path;
                     this.appIDPrefixField.text = prefix;
                     this.appIDPrefixField.text = prefix;
 
 
-                  }
-
-                  this.refreshWidgets();
+                  }                  
 
 
               }
               }
 
 

+ 1 - 11
Source/ToolCore/Build/BuildAndroid.cpp

@@ -23,7 +23,7 @@
 namespace ToolCore
 namespace ToolCore
 {
 {
 
 
-BuildAndroid::BuildAndroid(Context* context, Project* project) : BuildBase(context, project)
+BuildAndroid::BuildAndroid(Context* context, Project* project) : BuildBase(context, project, PLATFORMID_ANDROID)
 {
 {
     ToolSystem* toolSystem = GetSubsystem<ToolSystem>();
     ToolSystem* toolSystem = GetSubsystem<ToolSystem>();
     // this cast isn't great
     // this cast isn't great
@@ -36,16 +36,6 @@ BuildAndroid::~BuildAndroid()
 
 
 }
 }
 
 
-void BuildAndroid::SendBuildFailure(const String& message)
-{
-
-    VariantMap buildError;
-    buildError[BuildFailed::P_PLATFORMID] = PLATFORMID_ANDROID;
-    buildError[BuildFailed::P_MESSAGE] = message;
-    SendEvent(E_BUILDFAILED, buildError);
-
-}
-
 void BuildAndroid::HandleADBStartActivityComplete(StringHash eventType, VariantMap& eventData)
 void BuildAndroid::HandleADBStartActivityComplete(StringHash eventType, VariantMap& eventData)
 {
 {
 
 

+ 1 - 3
Source/ToolCore/Build/BuildAndroid.h

@@ -48,9 +48,7 @@ protected:
     void HandleRunADBInstallComplete(StringHash eventType, VariantMap& eventData);
     void HandleRunADBInstallComplete(StringHash eventType, VariantMap& eventData);
 
 
     void RunADBStartActivity();
     void RunADBStartActivity();
-    void HandleADBStartActivityComplete(StringHash eventType, VariantMap& eventData);
-
-    void SendBuildFailure(const String& message);
+    void HandleADBStartActivityComplete(StringHash eventType, VariantMap& eventData);    
 
 
     BuildPhase currentBuildPhase_;
     BuildPhase currentBuildPhase_;
 
 

+ 14 - 1
Source/ToolCore/Build/BuildBase.cpp

@@ -16,7 +16,9 @@
 namespace ToolCore
 namespace ToolCore
 {
 {
 
 
-BuildBase::BuildBase(Context * context, Project* project) : Object(context), containsMDL_(false)
+BuildBase::BuildBase(Context * context, Project* project, PlatformID platform) : Object(context),
+    platformID_(platform),
+    containsMDL_(false)
 {
 {
     if (UseResourcePackager())
     if (UseResourcePackager())
         resourcePackager_ = new ResourcePackager(context, this);
         resourcePackager_ = new ResourcePackager(context, this);
@@ -48,6 +50,17 @@ void BuildBase::BuildError(const String& error)
     buildErrors_.Push(error);
     buildErrors_.Push(error);
 }
 }
 
 
+void BuildBase::SendBuildFailure(const String& message)
+{
+
+    VariantMap buildError;
+    buildError[BuildFailed::P_PLATFORMID] = platformID_;
+    buildError[BuildFailed::P_MESSAGE] = message;
+    SendEvent(E_BUILDFAILED, buildError);
+
+}
+
+
 void BuildBase::HandleSubprocessOutputEvent(StringHash eventType, VariantMap& eventData)
 void BuildBase::HandleSubprocessOutputEvent(StringHash eventType, VariantMap& eventData)
 {
 {
     // E_SUBPROCESSOUTPUT
     // E_SUBPROCESSOUTPUT

+ 6 - 1
Source/ToolCore/Build/BuildBase.h

@@ -6,6 +6,7 @@
 
 
 #include <Atomic/Core/Object.h>
 #include <Atomic/Core/Object.h>
 #include "BuildTypes.h"
 #include "BuildTypes.h"
+#include "../Platform/Platform.h"
 
 
 using namespace Atomic;
 using namespace Atomic;
 
 
@@ -21,7 +22,7 @@ class BuildBase : public Object
 
 
 public:
 public:
 
 
-    BuildBase(Context* context, Project* project);
+    BuildBase(Context* context, Project* project, PlatformID platform);
     virtual ~BuildBase();
     virtual ~BuildBase();
 
 
     virtual void Build(const String& buildPath) = 0;
     virtual void Build(const String& buildPath) = 0;
@@ -44,6 +45,8 @@ public:
 
 
 protected:
 protected:
 
 
+    void SendBuildFailure(const String& message);
+
     void GenerateResourcePackage(const String& resourcePackagePath);
     void GenerateResourcePackage(const String& resourcePackagePath);
 
 
     void BuildResourceEntries();
     void BuildResourceEntries();
@@ -57,6 +60,8 @@ protected:
 
 
 private:
 private:
 
 
+    PlatformID platformID_;
+
     Vector<String> buildLog_;
     Vector<String> buildLog_;
     Vector<String> buildWarnings_;
     Vector<String> buildWarnings_;
     Vector<String> buildErrors_;
     Vector<String> buildErrors_;

+ 287 - 1
Source/ToolCore/Build/BuildIOS.cpp

@@ -2,18 +2,24 @@
 // Please see LICENSE.md in repository root for license information
 // Please see LICENSE.md in repository root for license information
 // https://github.com/AtomicGameEngine/AtomicGameEngine
 // https://github.com/AtomicGameEngine/AtomicGameEngine
 
 
+#include <Atomic/IO/File.h>
 #include <Atomic/IO/FileSystem.h>
 #include <Atomic/IO/FileSystem.h>
 
 
 #include "../ToolSystem.h"
 #include "../ToolSystem.h"
 #include "../ToolEnvironment.h"
 #include "../ToolEnvironment.h"
 #include "../Project/Project.h"
 #include "../Project/Project.h"
+#include "../Project/ProjectBuildSettings.h"
+
+#include "../Subprocess/SubprocessSystem.h"
+
 #include "BuildIOS.h"
 #include "BuildIOS.h"
+#include "BuildEvents.h"
 #include "BuildSystem.h"
 #include "BuildSystem.h"
 
 
 namespace ToolCore
 namespace ToolCore
 {
 {
 
 
-BuildIOS::BuildIOS(Context * context, Project *project) : BuildBase(context, project)
+BuildIOS::BuildIOS(Context * context, Project *project) : BuildBase(context, project, PLATFORMID_IOS)
 {
 {
 
 
 }
 }
@@ -23,6 +29,100 @@ BuildIOS::~BuildIOS()
 
 
 }
 }
 
 
+String BuildIOS::GenerateInfoPlist()
+{
+    ToolSystem* tsystem = GetSubsystem<ToolSystem>();
+    Project* project = tsystem->GetProject();
+    ProjectBuildSettings* buildSettings = project->GetBuildSettings();
+    IOSBuildSettings* iosSettings = buildSettings->GetIOSBuildSettings();
+
+    String plist = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
+    plist += "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n";
+    plist += "<plist version=\"1.0\">\n";
+    plist += "<dict>\n";
+
+    plist += "<key>CFBundleDevelopmentRegion</key>\n";
+    plist += "<string>English</string>\n";
+
+    plist += "<key>CFBundleExecutable</key>\n";
+    plist += "<string>AtomicPlayer</string>\n";
+
+    plist += "<key>CFBundleGetInfoString</key>\n";
+    plist += "<string>\"Atomic Player\"</string>\n";
+
+    plist += "<key>CFBundleIconFile</key>\n";
+    plist += "<string></string>\n";
+
+    plist += "<key>CFBundleIdentifier</key>\n";
+    plist.AppendWithFormat("<string>%s</string>\n", iosSettings->GetPackageName().CString());
+
+    plist += "<key>CFBundleInfoDictionaryVersion</key>\n";
+    plist += "<string>6.0</string>\n";
+
+    plist += "<key>CFBundleLongVersionString</key>\n";
+    plist += "<string></string>\n";
+
+    plist +=  "<key>CFBundleName</key>\n";
+    plist += "<string></string>\n";
+    plist += "<key>CFBundlePackageType</key>\n";
+    plist += "<string>APPL</string>\n";
+    plist += "<key>CFBundleShortVersionString</key>\n";
+    plist += "<string></string>\n";
+    plist += "<key>CFBundleSignature</key>\n";
+    plist += "<string>????</string>\n";
+    plist += "<key>CFBundleVersion</key>\n";
+    plist += "<string></string>\n";
+    plist += "<key>CSResourcesFileMapped</key>\n";
+    plist += "<true/>\n";
+    plist += "<key>LSRequiresCarbon</key>\n";
+    plist += "<true/>\n";
+    plist += "<key>NSHumanReadableCopyright</key>\n";
+    plist += "<string>\"(c) Your Company\"</string>\n";
+    plist += "<key>CFBundleIconFiles</key>\n";
+    plist += "<array>\n";
+    plist += "<string></string>\n";
+    plist += "</array>\n";
+    plist += "</dict>\n";
+    plist += "</plist>\n";
+
+    return plist;
+
+}
+
+String BuildIOS::GenerateEntitlements()
+{
+    ToolSystem* tsystem = GetSubsystem<ToolSystem>();
+    Project* project = tsystem->GetProject();
+    ProjectBuildSettings* buildSettings = project->GetBuildSettings();
+    IOSBuildSettings* iosSettings = buildSettings->GetIOSBuildSettings();
+
+    String app_identifer = iosSettings->GetAppIDPrefix() + ".";
+    app_identifer += iosSettings->GetPackageName();
+
+    String team_identifier = iosSettings->GetAppIDPrefix();
+
+    String keychain_access_group = app_identifer;
+
+    String entitlements = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
+    entitlements += "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n";
+    entitlements += "<plist version=\"1.0\">\n";
+    entitlements += "<dict>\n";
+    entitlements += "<key>application-identifier</key>\n";
+    entitlements.AppendWithFormat("<string>%s</string>\n", app_identifer.CString());
+    entitlements += "<key>com.apple.developer.team-identifier</key>\n";
+    entitlements.AppendWithFormat("<string>%s</string>\n", team_identifier.CString());
+    entitlements += "<key>get-task-allow</key>\n";
+    entitlements += "<true/>\n";
+    entitlements += "<key>keychain-access-groups</key>\n";
+    entitlements += "<array>\n";
+    entitlements.AppendWithFormat("<string>%s</string>\n", keychain_access_group.CString());
+    entitlements += "</array>\n";
+    entitlements += "</dict>\n";
+    entitlements += "</plist>\n";
+
+    return entitlements;
+}
+
 void BuildIOS::Initialize()
 void BuildIOS::Initialize()
 {
 {
     ToolSystem* tsystem = GetSubsystem<ToolSystem>();
     ToolSystem* tsystem = GetSubsystem<ToolSystem>();
@@ -45,8 +145,194 @@ void BuildIOS::Initialize()
 
 
 }
 }
 
 
+void BuildIOS::RunConvertPList()
+{
+    SubprocessSystem* subs = GetSubsystem<SubprocessSystem>();
+
+    Vector<String> args = String("-convert binary1 ./AtomicPlayer.app/Info.plist").Split(' ');
+
+    currentBuildPhase_ = ConvertPList;
+    Subprocess* subprocess = subs->Launch("/usr/bin/plutil", args, buildPath_);
+
+    if (!subprocess)
+    {
+        SendBuildFailure("BuildFailed::RunConvertPList");
+        return;
+    }
+
+    VariantMap buildOutput;
+    buildOutput[BuildOutput::P_TEXT] = "\n\n<color #D4FB79>Starting iOS Deployment</color>\n\n";
+    SendEvent(E_BUILDOUTPUT, buildOutput);
+
+
+    SubscribeToEvent(subprocess, E_SUBPROCESSCOMPLETE, HANDLER(BuildIOS, HandleConvertPListComplete));
+    SubscribeToEvent(subprocess, E_SUBPROCESSOUTPUT, HANDLER(BuildBase, HandleSubprocessOutputEvent));
+
+}
+
+void BuildIOS::HandleConvertPListComplete(StringHash eventType, VariantMap& eventData)
+{
+    int code = eventData[SubprocessComplete::P_RETCODE].GetInt();
+
+    if (!code)
+    {
+        RunCodeSign();
+    }
+    else
+    {
+        BuildSystem* buildSystem = GetSubsystem<BuildSystem>();
+        buildSystem->BuildComplete(PLATFORMID_IOS, buildPath_, false);
+    }
+
+}
+
+void BuildIOS::RunCodeSign()
+{
+    SubprocessSystem* subs = GetSubsystem<SubprocessSystem>();
+
+    Vector<String> args;
+    args.Push("--force");
+    args.Push("--sign");
+    args.Push("iPhone Developer");
+    args.Push("--entitlements");
+    args.Push("./AtomicPlayer.app.xcent");
+    args.Push("./AtomicPlayer.app");
+
+    Poco::Process::Env env;
+    env["CODESIGN_ALLOCATE"] =  "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/codesign_allocate";
+
+    currentBuildPhase_ = CodeSign;
+    Subprocess* subprocess = subs->Launch("/usr/bin/codesign", args, buildPath_, env);
+
+    if (!subprocess)
+    {
+        SendBuildFailure("BuildFailed::RunCodeSign");
+        return;
+    }
+
+    VariantMap buildOutput;
+    buildOutput[BuildOutput::P_TEXT] = "\n\n<color #D4FB79>Code Signing iOS Deployment</color>\n\n";
+    SendEvent(E_BUILDOUTPUT, buildOutput);
+
+    SubscribeToEvent(subprocess, E_SUBPROCESSCOMPLETE, HANDLER(BuildIOS, HandleCodeSignComplete));
+    SubscribeToEvent(subprocess, E_SUBPROCESSOUTPUT, HANDLER(BuildBase, HandleSubprocessOutputEvent));
+
+}
+
+void BuildIOS::HandleCodeSignComplete(StringHash eventType, VariantMap& eventData)
+{
+    int code = eventData[SubprocessComplete::P_RETCODE].GetInt();
+
+    if (!code)
+    {
+        RunDeploy();
+    }
+    else
+    {
+        BuildSystem* buildSystem = GetSubsystem<BuildSystem>();
+        buildSystem->BuildComplete(PLATFORMID_IOS, buildPath_, false);
+    }
+
+}
+
+void BuildIOS::RunDeploy()
+{
+    SubprocessSystem* subs = GetSubsystem<SubprocessSystem>();
+    ToolEnvironment* tenv = GetSubsystem<ToolEnvironment>();
+    String iosDeploy = tenv->GetIOSDeployBinary();
+
+    Vector<String> args;
+
+    // https://github.com/phonegap/ios-deploy/issues/152
+    // args.Push("--uninstall");
+
+    args.Push("--bundle");
+    args.Push("./AtomicPlayer.app");
+
+    currentBuildPhase_ = Deploy;
+
+    Subprocess* subprocess = subs->Launch(iosDeploy.CString(), args, buildPath_);
+
+    if (!subprocess)
+    {
+        SendBuildFailure("BuildFailed::RunDeploy");
+        return;
+    }
+
+    VariantMap buildOutput;
+    buildOutput[BuildOutput::P_TEXT] = "\n\n<color #D4FB79>Deploying to iOS Device</color>\n\n";
+    SendEvent(E_BUILDOUTPUT, buildOutput);
+
+    SubscribeToEvent(subprocess, E_SUBPROCESSCOMPLETE, HANDLER(BuildIOS, HandleDeployComplete));
+    SubscribeToEvent(subprocess, E_SUBPROCESSOUTPUT, HANDLER(BuildBase, HandleSubprocessOutputEvent));
+
+
+}
+
+void BuildIOS::HandleDeployComplete(StringHash eventType, VariantMap& eventData)
+{
+    int code = eventData[SubprocessComplete::P_RETCODE].GetInt();
+
+    BuildSystem* buildSystem = GetSubsystem<BuildSystem>();
+    buildSystem->BuildComplete(PLATFORMID_IOS, buildPath_, true);
+
+}
+
+
 void BuildIOS::Build(const String& buildPath)
 void BuildIOS::Build(const String& buildPath)
 {
 {
+    FileSystem* fileSystem = GetSubsystem<FileSystem>();
+    ToolEnvironment* tenv = GetSubsystem<ToolEnvironment>();
+    ToolSystem* tsystem = GetSubsystem<ToolSystem>();
+    Project* project = tsystem->GetProject();
+    ProjectBuildSettings* buildSettings = project->GetBuildSettings();
+    IOSBuildSettings* iosSettings = buildSettings->GetIOSBuildSettings();
+
+    buildPath_ = AddTrailingSlash(buildPath) + GetBuildSubfolder();
+
+    Initialize();
+
+    if (fileSystem->DirExists(buildPath_))
+        fileSystem->RemoveDir(buildPath_, true);
+
+    String buildSourceDir = tenv->GetToolDataDir();
+
+    String buildAppSourceDir = buildSourceDir + "Deployment/IOS/AtomicPlayer.app";
+
+    fileSystem->CreateDir(buildPath_);
+
+    String buildDestDist = buildPath_ + "/AtomicPlayer.app";
+
+    fileSystem->CreateDir(buildDestDist);
+
+    String resourcePackagePath = buildDestDist + "/AtomicResources.pak";
+    GenerateResourcePackage(resourcePackagePath);
+
+    fileSystem->Copy(buildAppSourceDir + "/AtomicPlayer", buildDestDist + "/AtomicPlayer");
+    fileSystem->Copy(buildAppSourceDir + "/PkgInfo", buildDestDist + "/PkgInfo");
+
+    fileSystem->Copy(iosSettings->GetProvisionFile(), buildDestDist + "/embedded.mobileprovision");
+
+    String entitlements = GenerateEntitlements();
+    String plist = GenerateInfoPlist();
+
+    File file(context_, buildPath_ + "/AtomicPlayer.app.xcent", FILE_WRITE);
+
+    if (file.IsOpen())
+    {
+        file.Write(entitlements.CString(), entitlements.Length());
+        file.Close();
+    }
+
+    File pfile(context_, buildDestDist + "/Info.plist", FILE_WRITE);
+
+    if (pfile.IsOpen())
+    {
+        pfile.Write(plist.CString(), plist.Length());
+        pfile.Close();
+    }
+
+    RunConvertPList();
 
 
 }
 }
 
 

+ 21 - 0
Source/ToolCore/Build/BuildIOS.h

@@ -26,8 +26,29 @@ public:
 
 
 protected:
 protected:
 
 
+    enum BuildPhase
+    {
+        ConvertPList,
+        CodeSign,
+        Deploy
+    };
+
+    void RunConvertPList();
+    void HandleConvertPListComplete(StringHash eventType, VariantMap& eventData);
+
+    void RunCodeSign();
+    void HandleCodeSignComplete(StringHash eventType, VariantMap& eventData);
+
+    void RunDeploy();
+    void HandleDeployComplete(StringHash eventType, VariantMap& eventData);
+
+    String GenerateInfoPlist();
+    String GenerateEntitlements();
+
     void Initialize();
     void Initialize();
 
 
+    BuildPhase currentBuildPhase_;
+
 
 
 };
 };
 
 

+ 1 - 1
Source/ToolCore/Build/BuildMac.cpp

@@ -13,7 +13,7 @@
 namespace ToolCore
 namespace ToolCore
 {
 {
 
 
-BuildMac::BuildMac(Context * context, Project *project) : BuildBase(context, project)
+BuildMac::BuildMac(Context * context, Project *project) : BuildBase(context, project, PLATFORMID_MAC)
 {
 {
 
 
 }
 }

+ 1 - 1
Source/ToolCore/Build/BuildWeb.cpp

@@ -15,7 +15,7 @@
 namespace ToolCore
 namespace ToolCore
 {
 {
 
 
-BuildWeb::BuildWeb(Context* context, Project* project) : BuildBase(context, project)
+BuildWeb::BuildWeb(Context* context, Project* project) : BuildBase(context, project, PLATFORMID_WEB)
 {
 {
 
 
 }
 }

+ 1 - 1
Source/ToolCore/Build/BuildWindows.cpp

@@ -13,7 +13,7 @@
 namespace ToolCore
 namespace ToolCore
 {
 {
 
 
-BuildWindows::BuildWindows(Context * context, Project *project) : BuildBase(context, project)
+BuildWindows::BuildWindows(Context * context, Project *project) : BuildBase(context, project, PLATFORMID_WINDOWS)
 {
 {
 
 
 }
 }

+ 2 - 2
Source/ToolCore/Platform/PlatformIOS.cpp

@@ -1,7 +1,7 @@
 
 
 #include <ThirdParty/PugiXml/src/pugixml.hpp>
 #include <ThirdParty/PugiXml/src/pugixml.hpp>
 
 
-#include "../Build/BuildWeb.h"
+#include "../Build/BuildIOS.h"
 #include "PlatformIOS.h"
 #include "PlatformIOS.h"
 
 
 #ifdef ATOMIC_PLATFORM_OSX
 #ifdef ATOMIC_PLATFORM_OSX
@@ -79,7 +79,7 @@ String PlatformIOS::ParseProvisionAppIdentifierPrefix(const String& provisionFil
 
 
 BuildBase* PlatformIOS::NewBuild(Project *project)
 BuildBase* PlatformIOS::NewBuild(Project *project)
 {
 {
-    return 0;
+    return new BuildIOS(context_, project);
 }
 }
 
 
 
 

+ 5 - 0
Source/ToolCore/ToolEnvironment.cpp

@@ -158,6 +158,11 @@ void ToolEnvironment::SetRootBuildDir(const String& buildDir, bool setBinaryPath
 
 
 }
 }
 
 
+String ToolEnvironment::GetIOSDeployBinary()
+{
+    return GetToolDataDir() + "Tools/IOSDeploy/ios-deploy";
+}
+
 void ToolEnvironment::Dump()
 void ToolEnvironment::Dump()
 {
 {
     LOGINFOF("Root Source Dir: %s", rootSourceDir_.CString());
     LOGINFOF("Root Source Dir: %s", rootSourceDir_.CString());

+ 3 - 0
Source/ToolCore/ToolEnvironment.h

@@ -61,6 +61,9 @@ public:
     // OSX
     // OSX
     const String& GetPlayerAppFolder() { return playerAppFolder_; }
     const String& GetPlayerAppFolder() { return playerAppFolder_; }
 
 
+    // iOS
+    String GetIOSDeployBinary();
+
     void Dump();
     void Dump();
 
 
 private:
 private: