File include/dialogue.h changed (mode: 100755) (index ca3df6a..2e70e69) |
... |
... |
class Talk { |
51 |
51 |
std::vector<Screen> screens; |
std::vector<Screen> screens; |
52 |
52 |
std::map<std::string,double> numbers; |
std::map<std::string,double> numbers; |
53 |
53 |
std::map<std::string,std::string> strings; |
std::map<std::string,std::string> strings; |
|
54 |
|
std::map<std::string,std::vector<std::string>> arrays; |
54 |
55 |
std::function<double(std::string)> callback; |
std::function<double(std::string)> callback; |
55 |
56 |
void go( const std::string &id ); |
void go( const std::string &id ); |
56 |
57 |
void append( std::string filePath ); |
void append( std::string filePath ); |
|
... |
... |
class Talk { |
62 |
63 |
void setVariable( const std::string &key, double valueNumber ); |
void setVariable( const std::string &key, double valueNumber ); |
63 |
64 |
int parseJSON( std::string &text ); |
int parseJSON( std::string &text ); |
64 |
65 |
std::string stringifyNumber( double n ); |
std::string stringifyNumber( double n ); |
|
66 |
|
std::string stringifyArray( const std::vector<std::string> &arr ); |
65 |
67 |
Operation getOperation( std::string key, double valueNumber, const std::string &valueKey ); |
Operation getOperation( std::string key, double valueNumber, const std::string &valueKey ); |
66 |
68 |
void operate( Operation o ); |
void operate( Operation o ); |
67 |
69 |
void transformString( std::string &str ); |
void transformString( std::string &str ); |
|
... |
... |
double Talk::getVariable( std::string key ){ |
186 |
188 |
}else if( key.length() >= 6 && key.substr( 0, 6 ) == "STRLEN" ){ |
}else if( key.length() >= 6 && key.substr( 0, 6 ) == "STRLEN" ){ |
187 |
189 |
// Returns the length of the parameter string. |
// Returns the length of the parameter string. |
188 |
190 |
return std::max( key.length() - 7.0, 0.0 ); |
return std::max( key.length() - 7.0, 0.0 ); |
|
191 |
|
}else if( key.length() >= 6 && key.substr( 0, 6 ) == "ARRLEN" ){ |
|
192 |
|
// Returns the length of the named array if it exists, otherwise 0. |
|
193 |
|
if( key.back() == '@' ) key.resize( key.length() - 1 ); |
|
194 |
|
if( key.length() >= 8 ){ |
|
195 |
|
auto it = arrays.find( key.substr( 7 ) ); |
|
196 |
|
if( it != arrays.end() ) return it->second.size(); |
|
197 |
|
} |
189 |
198 |
}else if( key.length() >= 5 && key.substr( 0, 5 ) == "GOSUB" ){ |
}else if( key.length() >= 5 && key.substr( 0, 5 ) == "GOSUB" ){ |
190 |
199 |
// Executes the specified dialogue, then returns 0. |
// Executes the specified dialogue, then returns 0. |
191 |
200 |
std::string arg = key.length() >= 7 ? key.substr( 6 ) : ""; |
std::string arg = key.length() >= 7 ? key.substr( 6 ) : ""; |
192 |
201 |
go( arg ); |
go( arg ); |
193 |
|
return 0.0; |
|
194 |
202 |
}else{ |
}else{ |
195 |
203 |
// Returns the value of a variable if it exists, otherwise 0. |
// Returns the value of a variable if it exists, otherwise 0. |
196 |
204 |
auto it = numbers.find( key ); |
auto it = numbers.find( key ); |
|
... |
... |
std::string Talk::stringifyNumber( double n ){ |
283 |
291 |
} |
} |
284 |
292 |
} |
} |
285 |
293 |
|
|
|
294 |
|
// Return a #-separated list of strings with each string's # characters |
|
295 |
|
// escaped as: \# |
|
296 |
|
std::string Talk::stringifyArray( const std::vector<std::string> &arr ){ |
|
297 |
|
std::string result; |
|
298 |
|
for( size_t i = 0; i < arr.size(); i++ ){ |
|
299 |
|
// Add separating # characters. |
|
300 |
|
if( i > 0 ) result += "#"; |
|
301 |
|
// Replace # characters with \# and add the fragments to result. |
|
302 |
|
const std::string &str = arr[i]; |
|
303 |
|
size_t start = 0, end = 0; |
|
304 |
|
while( ( end = str.find( '#', start ) ) != std::string::npos ){ |
|
305 |
|
result += str.substr( start, end - start ) + "\\#"; |
|
306 |
|
start = end + 1; |
|
307 |
|
} |
|
308 |
|
result += str.substr( start ); |
|
309 |
|
} |
|
310 |
|
return result; |
|
311 |
|
} |
|
312 |
|
|
286 |
313 |
Operation Talk::getOperation( std::string key, double valueNumber, const std::string &valueKey ){ |
Operation Talk::getOperation( std::string key, double valueNumber, const std::string &valueKey ){ |
287 |
314 |
char op = ':'; |
char op = ':'; |
288 |
|
if( key.length() > 0 && key.find_last_of( "$=!<>?%*/+-_" ) == key.length() - 1 ){ |
|
|
315 |
|
if( key.length() > 0 && key.find_last_of( "$@=!<>?%*/+-_" ) == key.length() - 1 ){ |
289 |
316 |
op = key.back(); |
op = key.back(); |
290 |
317 |
key.resize( key.length() - 1 ); |
key.resize( key.length() - 1 ); |
291 |
318 |
} |
} |
|
... |
... |
void Talk::operate( Operation o ){ |
311 |
338 |
} |
} |
312 |
339 |
return; |
return; |
313 |
340 |
} |
} |
|
341 |
|
// Array assignment. |
|
342 |
|
if( o.op == '@' ){ |
|
343 |
|
transformString( o.valueKey ); |
|
344 |
|
// Make an empty array and get the iterator. |
|
345 |
|
const auto [it, success] = arrays.insert( { o.key, {} } ); |
|
346 |
|
if( !success ) it->second = {}; |
|
347 |
|
// Parse the array. |
|
348 |
|
size_t start = 0, off = 0, end = 0; |
|
349 |
|
while( ( end = o.valueKey.find( '#', start + off ) ) != std::string::npos ){ |
|
350 |
|
// Allow \# escaping. TODO: \\ escaping. |
|
351 |
|
if( end > 0 && o.valueKey[end - 1] == '\\' ){ |
|
352 |
|
// Remove the \ character from the string. |
|
353 |
|
o.valueKey.erase( end - 1, 1 ); |
|
354 |
|
// `end` now points to the character after the #. |
|
355 |
|
off = end - start; |
|
356 |
|
continue; |
|
357 |
|
} |
|
358 |
|
it->second.push_back( o.valueKey.substr( start, end - start ) ); |
|
359 |
|
start = end + 1; |
|
360 |
|
off = 0; |
|
361 |
|
} |
|
362 |
|
it->second.push_back( o.valueKey.substr( start ) ); |
|
363 |
|
return; |
|
364 |
|
} |
314 |
365 |
// Numerical operations. |
// Numerical operations. |
315 |
366 |
double in = o.valueNumber, out = getVariable( o.key ); |
double in = o.valueNumber, out = getVariable( o.key ); |
316 |
367 |
if( o.valueKey.length() > 0 ){ |
if( o.valueKey.length() > 0 ){ |
|
... |
... |
void Talk::transformString( std::string &str ){ |
368 |
419 |
if( it != strings.end() ) |
if( it != strings.end() ) |
369 |
420 |
outStr += it->second; |
outStr += it->second; |
370 |
421 |
} |
} |
|
422 |
|
}else if( key.back() == '@' ){ |
|
423 |
|
key.resize( key.length() - 1 ); |
|
424 |
|
auto it = arrays.find( key ); |
|
425 |
|
if( it != arrays.end() ) |
|
426 |
|
outStr += stringifyArray( it->second ); |
371 |
427 |
}else{ |
}else{ |
372 |
428 |
outStr += stringifyNumber( getVariable( key ) ); |
outStr += stringifyNumber( getVariable( key ) ); |
373 |
429 |
} |
} |