This repository was archived by the owner on Apr 21, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 38
/
Copy pathGraphViz.cpp
129 lines (102 loc) · 3.01 KB
/
GraphViz.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// Copyright (c) 2018-2020, Zhirnov Andrey. For more information see 'LICENSE'
#include "GraphViz.h"
#if defined(FG_GRAPHVIZ_DOT_EXECUTABLE) && defined(FS_HAS_FILESYSTEM)
#include "stl/Algorithms/ArrayUtils.h"
#include "stl/Algorithms/StringUtils.h"
#include "stl/Platforms/WindowsHeader.h"
#include <thread>
namespace FG
{
/*
=================================================
Execute
=================================================
*/
static bool Execute (StringView commands, uint timeoutMS)
{
# ifdef PLATFORM_WINDOWS
char buf[MAX_PATH] = {};
::GetSystemDirectoryA( buf, UINT(CountOf(buf)) );
String command_line;
command_line << '"' << buf << "\\cmd.exe\" /C " << commands;
STARTUPINFOA startup_info = {};
PROCESS_INFORMATION proc_info = {};
bool process_created = ::CreateProcessA(
NULL,
command_line.data(),
NULL,
NULL,
FALSE,
CREATE_NO_WINDOW,
NULL,
NULL,
OUT &startup_info,
OUT &proc_info
);
if ( not process_created )
return false;
if ( ::WaitForSingleObject( proc_info.hThread, timeoutMS ) != WAIT_OBJECT_0 )
return false;
DWORD process_exit;
::GetExitCodeProcess( proc_info.hProcess, OUT &process_exit );
::CloseHandle( proc_info.hProcess );
//std::this_thread::sleep_for( std::chrono::milliseconds(1) );
return true;
# else
return false;
# endif
}
/*
=================================================
Visualize
=================================================
*/
bool GraphViz::Visualize (StringView graph, const FS::path &filepath, StringView format, bool autoOpen, bool deleteOrigin)
{
CHECK_ERR( filepath.extension() == ".dot" );
FS::create_directories( filepath.parent_path() );
const String path = filepath.string();
const FS::path graph_path = FS::path{filepath}.concat( "."s << format );
// space in path is not supported
CHECK_ERR( path.find( ' ' ) == String::npos );
// save to '.dot' file
{
FileWStream wfile{ filepath };
CHECK_ERR( wfile.IsOpen() );
CHECK_ERR( wfile.Write( graph ));
}
// generate graph
{
// delete previous version
if ( FS::exists( graph_path ) )
{
CHECK( FS::remove( graph_path ));
std::this_thread::sleep_for( std::chrono::milliseconds(1) );
}
CHECK_ERR( Execute( "\""s << FG_GRAPHVIZ_DOT_EXECUTABLE << "\" -T" << format << " -O " << path, 30'000 ));
if ( deleteOrigin )
{
CHECK( FS::remove( filepath ));
std::this_thread::sleep_for( std::chrono::milliseconds(1) );
}
}
if ( autoOpen )
{
CHECK( Execute( graph_path.string(), 1000 ));
}
return true;
}
/*
=================================================
Visualize
=================================================
*/
bool GraphViz::Visualize (const FrameGraph &instance, const FS::path &filepath, StringView format, bool autoOpen, bool deleteOrigin)
{
String str;
CHECK_ERR( instance->DumpToGraphViz( OUT str ));
CHECK_ERR( Visualize( str, filepath, "png", autoOpen, deleteOrigin ));
return true;
}
} // FG
#endif // FG_GRAPHVIZ_DOT_EXECUTABLE and FS_HAS_FILESYSTEM