Try to improve spacing in Keys tab of prefs on macOS (#1550).
[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 "player_stress_tester.h"
22 #include "controls.h"
23 #include <dcp/raw_convert.h>
24 #include <dcp/util.h>
25 #include <wx/wx.h>
26 #include <boost/algorithm/string.hpp>
27 #include <boost/foreach.hpp>
28 #include <boost/bind.hpp>
29 #include <string>
30 #include <vector>
31 #include <iostream>
32
33 using std::string;
34 using std::vector;
35 using std::cout;
36 using dcp::raw_convert;
37 using boost::optional;
38
39 /* Interval to check for things to do with the stress script (in milliseconds) */
40 #define CHECK_INTERVAL 20
41
42 Command::Command (string line)
43         : type (NONE)
44         , int_param (0)
45 {
46         vector<string> bits;
47         boost::split (bits, line, boost::is_any_of(" "));
48         if (bits[0] == "O") {
49                 if (bits.size() != 2) {
50                         return;
51                 }
52                 type = OPEN;
53                 string_param = bits[1];
54         } else if (bits[0] == "P") {
55                 type = PLAY;
56         } else if (bits[0] == "W") {
57                 if (bits.size() != 2) {
58                         return;
59                 }
60                 type = WAIT;
61                 int_param = raw_convert<int>(bits[1]);
62         } else if (bits[0] == "S") {
63                 type = STOP;
64         } else if (bits[0] == "K") {
65                 if (bits.size() != 2) {
66                         return;
67                 }
68                 type = SEEK;
69                 int_param = raw_convert<int>(bits[1]);
70         }
71 }
72
73 PlayerStressTester::PlayerStressTester ()
74         : _parent (0)
75         , _controls (0)
76         , _suspended (false)
77 {
78
79 }
80
81
82 void
83 PlayerStressTester::setup (wxWindow* parent, Controls* controls)
84 {
85         _parent = parent;
86         _controls = controls;
87 }
88
89
90 void
91 PlayerStressTester::load_script (boost::filesystem::path file)
92 {
93         DCPOMATIC_ASSERT (_parent);
94
95         _timer.Bind (wxEVT_TIMER, boost::bind(&PlayerStressTester::check_commands, this));
96         _timer.Start (CHECK_INTERVAL);
97         vector<string> lines;
98         string const script = dcp::file_to_string(file);
99         boost::split (lines, script, boost::is_any_of("\n"));
100         BOOST_FOREACH (string i, lines) {
101                 _commands.push_back (Command(i));
102         }
103         _current_command = _commands.begin();
104 }
105
106 void
107 PlayerStressTester::check_commands ()
108 {
109         DCPOMATIC_ASSERT (_controls);
110
111         if (_suspended) {
112                 return;
113         }
114
115         if (_current_command == _commands.end()) {
116                 _timer.Stop ();
117                 cout << "ST: finished.\n";
118                 return;
119         }
120
121         switch (_current_command->type) {
122                 case Command::OPEN:
123                         LoadDCP(_current_command->string_param);
124                         ++_current_command;
125                         break;
126                 case Command::PLAY:
127                         cout << "ST: play\n";
128                         _controls->play ();
129                         ++_current_command;
130                         break;
131                 case Command::WAIT:
132                         /* int_param here is the number of milliseconds to wait */
133                         if (_wait_remaining) {
134                                 _wait_remaining = *_wait_remaining - CHECK_INTERVAL;
135                                 if (_wait_remaining < 0) {
136                                         cout << "ST: wait done.\n";
137                                         _wait_remaining = optional<int>();
138                                         ++_current_command;
139                                 }
140                         } else {
141                                 _wait_remaining = _current_command->int_param;
142                                 cout << "ST: waiting for " << *_wait_remaining << ".\n";
143                         }
144                         break;
145                 case Command::STOP:
146                         cout << "ST: stop\n";
147                         _controls->stop ();
148                         ++_current_command;
149                         break;
150                 case Command::NONE:
151                         ++_current_command;
152                         break;
153                 case Command::SEEK:
154                         /* int_param here is a number between 0 and 4095, corresponding to the possible slider positions */
155                         cout << "ST: seek to " << _current_command->int_param << "\n";
156                         _controls->seek (_current_command->int_param);
157                         ++_current_command;
158                         break;
159         }
160 }
161