summaryrefslogtreecommitdiff
path: root/Analizator9000/Analizator9000/DealerWrapper.cs
blob: 65c09e7dd242decff9c4e8eeefbcc7efe6c465a9 (plain)
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
using System;
using System.Text;
using System.Diagnostics;
using System.IO;
using System.Text.RegularExpressions;

namespace Analizator9000
{
    /// <summary>
    /// Runs dealer generator and captures its output.
    /// </summary>
    class DealerWrapper
    {
        /// <summary>
        /// Calling user interfaces instance.
        /// </summary>
        private Form1 debugForm;
        /// <summary>
        /// Name of the input script file.
        /// </summary>
        private String scriptname;
        /// <summary>
        /// Stream to the generation results output file.
        /// </summary>
        private StreamWriter outputFile;
        /// <summary>
        /// Flag ensuring only one instance of dealer is running.
        /// </summary>
        private bool running = false;
        /// <summary>
        /// Number of lines (deals) to produce.
        /// </summary>
        private long produce = 0;
        /// <summary>
        /// Number of lines (deals) already produced.
        /// </summary>
        private long lineCount = 0;

        /// <summary>
        /// Dealer wrapper class constructor.
        /// </summary>
        /// <param name="scriptname">Input script file name.</param>
        /// <param name="debugForm">Calling interface form.</param>
        /// <param name="produce">Number of deals to produce.</param>
        public DealerWrapper(String scriptname, Form1 debugForm, long produce)
        {
            if (!File.Exists(scriptname))
            {
                throw new Exception(Form1.GetResourceManager().GetString("DealerWrapper_errorFileNotFound", Form1.GetCulture()) + ": " + scriptname);
            }
            if (produce < 1)
            {
                throw new Exception(Form1.GetResourceManager().GetString("DealerWrapper_errorInvalidDealCount", Form1.GetCulture()));
            }
            this.scriptname = scriptname;
            this.debugForm = debugForm;
            this.produce = produce;
        }

        /// <summary>
        /// Sends a single line to debug field of the calling form.
        /// </summary>
        /// <param name="line">Message to be appended to the debug output.</param>
        private void debugWriteLine(String line) {
            this.debugForm.addStatusLine(line);
        }

        /// <summary>
        /// Processes a chunk of dealer output.
        /// </summary>
        /// <param name="data">Output string of dealer instance.</param>
        /// <returns>TRUE if dealer it still running, FALSE if null string arrived -> process ended.</returns>
        private bool handleData(string data)
        {
            if (data != null)
            {
                String[] dataLines = data.Split('\n');
                foreach (String line in dataLines)
                {
                    Match lineMatch = Regex.Match(line.Trim(), @"^n\s*(\S*)\s*e\s*(\S*)\s*s\s*(\S*)\s*w\s*(\S*)$");
                    if (lineMatch.Success)
                    {
                        this.lineCount++;
                        this.outputFile.Write(this.lineCount);
                        this.outputFile.WriteLine(lineMatch.Result(": ${1} ${2} ${3} ${4}"));
                    }
                }
                int progress = ((int)(100 * this.lineCount / this.produce));
                this.debugForm.setProgress(progress);
                this.debugWriteLine(data);
                return true;
            }
            return false;
        }

        /// <summary>
        /// Closes the output file stream.
        /// </summary>
        public void closeFile()
        {
            this.outputFile.Close();
        }

        /// <summary>
        /// Delegate for process end callback invocation.
        /// </summary>
        /// <param name="filename">Output file name.</param>
        private delegate void onEndDelegate(String filename);
        /// <summary>
        /// Worker method for dealer generating.
        /// </summary>
        /// <param name="onEnd">Callback to the function which takes output file name as a parameter.</param>
        public void run(Action<String> onEnd)
        {
            if (!this.running)
            {
                this.running = true;
                this.lineCount = 0;
                String filename = Utils.getFilename("deals");
                this.outputFile = new StreamWriter(@"files\"+filename);
                ProcessStartInfo pInfo = new ProcessStartInfo();
                pInfo.FileName = @"bin\dealer.exe";
                pInfo.WindowStyle = ProcessWindowStyle.Hidden;
                pInfo.CreateNoWindow = true;
                pInfo.Arguments = "\"" + this.scriptname + "\"";
                pInfo.UseShellExecute = false;
                pInfo.RedirectStandardOutput = true;
                pInfo.RedirectStandardError = true;
                pInfo.StandardOutputEncoding = pInfo.StandardErrorEncoding = Encoding.UTF8;
                this.debugWriteLine(pInfo.FileName + " " + pInfo.Arguments);
                Process dealerProc = new Process();
                dealerProc.StartInfo = pInfo;
                dealerProc.OutputDataReceived += (sender, output) =>
                {
                    if (output != null)
                    {
                        if (!this.handleData(output.Data))
                        {
                            this.closeFile();
                            (new onEndDelegate(onEnd)).Invoke(filename);
                        }
                    }
                };
                dealerProc.ErrorDataReceived += (sender, error) => { if (error != null) { this.debugWriteLine(error.Data); } };
                dealerProc.Start();
                dealerProc.BeginErrorReadLine();
                dealerProc.BeginOutputReadLine();
            }
        }

    }
}