ignore loadsa warnings.
[dcpomatic.git] / src / wx / player_stress_tester.cc
1 /*
2     Copyright (C) 2017-2020 Carl Hetherington <cth@carlh.net>
3
4     This file is part of DCP-o-matic.
5
6     DCP-o-matic is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     DCP-o-matic is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with DCP-o-matic.  If not, see <http://www.gnu.org/licenses/>.
18
19 */
20
21 #include "controls.h"
22 #include "player_stress_tester.h"
23 #include "lib/warnings.h"
24 #include <dcp/raw_convert.h>
25 #include <dcp/util.h>
26 DCPOMATIC_DISABLE_WARNINGS
27 #include <wx/wx.h>
28 DCPOMATIC_ENABLE_WARNINGS
29 #include <boost/algorithm/string.hpp>
30 #include <boost/bind/bind.hpp>
31 #include <string>
32 #include <vector>
33 #include <iostream>
34
35 using std::string;
36 using std::vector;
37 using std::cout;
38 using dcp::raw_convert;
39 using boost::optional;
40
41 /* Interval to check for things to do with the stress script (in milliseconds) */
42 #define CHECK_INTERVAL 20
43
44 Command::Command (string line)
45         : type (NONE)
46         , int_param (0)
47 {
48         vector<string> bits;
49         boost::split (bits, line, boost::is_any_of(" "));
50         if (bits[0] == "O") {
51                 if (bits.size() != 2) {
52                         return;
53                 }
54                 type = OPEN;
55                 string_param = bits[1];
56         } else if (bits[0] == "P") {
57                 type = PLAY;
58         } else if (bits[0] == "W") {
59                 if (bits.size() != 2) {
60                         return;
61                 }
62                 type = WAIT;
63                 int_param = raw_convert<int>(bits[1]);
64         } else if (bits[0] == "S") {
65                 type = STOP;
66         } else if (bits[0] == "K") {
67                 if (bits.size() != 2) {
68                         return;
69                 }
70                 type = SEEK;
71                 int_param = raw_convert<int>(bits[1]);
72         } else if (bits[0] == "E") {
73                 type = EXIT;
74         }
75 }
76
77 PlayerStressTester::PlayerStressTester ()
78         : _parent (0)
79         , _controls (0)
80         , _suspended (false)
81 {
82
83 }
84
85
86 void
87 PlayerStressTester::setup (wxWindow* parent, Controls* controls)
88 {
89         _parent = parent;
90         _controls = controls;
91 }
92
93
94 void
95 PlayerStressTester::load_script (boost::filesystem::path file)
96 {
97         DCPOMATIC_ASSERT (_parent);
98
99         _timer.Bind (wxEVT_TIMER, boost::bind(&PlayerStressTester::check_commands, this));
100         _timer.Start (CHECK_INTERVAL);
101         vector<string> lines;
102         string const script = dcp::file_to_string(file);
103         boost::split (lines, script, boost::is_any_of("\n"));
104         for (auto i: lines) {
105                 _commands.push_back (Command(i));
106         }
107         _current_command = _commands.begin();
108 }
109
110 void
111 PlayerStressTester::check_commands ()
112 {
113         DCPOMATIC_ASSERT (_controls);
114
115         if (_suspended) {
116                 return;
117         }
118
119         if (_current_command == _commands.end()) {
120                 _timer.Stop ();
121                 cout << "ST: finished.\n";
122                 return;
123         }
124
125         switch (_current_command->type) {
126                 case Command::OPEN:
127                         LoadDCP(_current_command->string_param);
128                         ++_current_command;
129                         break;
130                 case Command::PLAY:
131                         cout << "ST: play\n";
132                         _controls->play ();
133                         ++_current_command;
134                         break;
135                 case Command::WAIT:
136                         /* int_param here is the number of milliseconds to wait */
137                         if (_wait_remaining) {
138                                 _wait_remaining = *_wait_remaining - CHECK_INTERVAL;
139                                 if (_wait_remaining < 0) {
140                                         cout << "ST: wait done.\n";
141                                         _wait_remaining = optional<int>();
142                                         ++_current_command;
143                                 }
144                         } else {
145                                 _wait_remaining = _current_command->int_param;
146                                 cout << "ST: waiting for " << *_wait_remaining << ".\n";
147                         }
148                         break;
149                 case Command::STOP:
150                         cout << "ST: stop\n";
151                         _controls->stop ();
152                         ++_current_command;
153                         break;
154                 case Command::NONE:
155                         ++_current_command;
156                         break;
157                 case Command::SEEK:
158                         /* int_param here is a number between 0 and 4095, corresponding to the possible slider positions */
159                         cout << "ST: seek to " << _current_command->int_param << "\n";
160                         _controls->seek (_current_command->int_param);
161                         ++_current_command;
162                         break;
163                 case Command::EXIT:
164                         wxTheApp->GetTopWindow()->Destroy();
165                         break;
166         }
167 }
168