wolfrpg_map_parser/command/common_event_command/
event.rs

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
153
154
155
156
157
158
159
160
161
162
163
164
165
use crate::byte_utils::{as_u32_le, as_u32_vec, parse_string_vec};
use crate::command::common::u32_or_string::U32OrString;
use crate::command::common_event_command::argument_count::ArgumentCount;
use crate::command::common_event_command::options::Options;
#[cfg(feature = "serde")]
use serde::{Serialize, Deserialize};
use std::cmp::max;
use std::collections::VecDeque;

#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(PartialEq)]
pub struct Event {
    target: u32,
    argument_count: ArgumentCount,
    options: Options,
    number_arguments: Vec<u32>,
    string_arguments: Vec<U32OrString>,
    return_variable: Option<u32>,
    event_name: Option<String>,
}

impl Event {
    pub(crate) fn parse(bytes: &[u8]) -> (usize, Self) {
        let mut offset: usize = 0;

        let target: u32 = as_u32_le(&bytes[offset..offset+4]);
        offset += 4;

        let argument_count: u8 = bytes[offset];
        let argument_count: ArgumentCount = ArgumentCount::new(argument_count);
        offset += 1;

        let options: [u8; 3] = bytes[offset..offset+3].try_into().unwrap();
        let options: Options = Options::new(options);
        offset += 3;

        let (bytes_read, number_arguments): (usize, Vec<u32>)
            = Self::parse_u32_vec(bytes, offset, argument_count.number_arguments() as usize);
        offset += bytes_read;

        let (bytes_read, string_arguments_variables): (usize, Vec<u32>)
            = Self::parse_u32_vec(bytes, offset, argument_count.string_arguments() as usize);
        offset += bytes_read;

        let return_variable: Option<u32> = if options.has_return_value() {
            let ret: u32 = as_u32_le(&bytes[offset..offset+4]);
            offset += 4;

            Some(ret)
        } else {
            None
        };

        offset += 1; // padding

        let string_count: u8 = bytes[offset];
        offset += 1;

        let (bytes_read, strings): (usize, Vec<String>)
            = parse_string_vec(&bytes[offset..], string_count as usize);
        offset += bytes_read;

        let (event_name, string_arguments): (Option<String>, Vec<U32OrString>)
            = Self::convert_strings(string_arguments_variables, strings,
                                    argument_count.string_arguments() as usize, &options);

        offset += 1;

        (offset, Self {
            target,
            argument_count,
            options,
            number_arguments,
            string_arguments,
            return_variable,
            event_name,
        })
    }

    fn parse_u32_vec(bytes: &[u8], offset: usize, count: usize) -> (usize, Vec<u32>) {
        (count*4, as_u32_vec(&bytes[offset..offset + count*4]))
    }

    fn convert_strings(variables: Vec<u32>, strings: Vec<String>, count: usize, options: &Options)
        -> (Option<String>, Vec<U32OrString>) {
        let mut count: usize = max(count, strings.len());
        let mut string_arguments: Vec<U32OrString> = Vec::with_capacity(count);
        let mut strings: VecDeque<String> = strings.into_iter().collect();

        let event_name: Option<String> = if options.string_argument_count() < count as u8 {
            count -= 1;
            strings.pop_front()
        } else {
            None
        };

        for i in 0..count {
            let arg: U32OrString = if options.is_arg_string((i+1) as u8) {
                U32OrString::String(strings[i].clone())
            } else {
                U32OrString::U32(variables[i])
            };

            string_arguments.push(arg);
        }

        (event_name, string_arguments)
    }

    pub fn target(&self) -> u32 {
        self.target
    }

    pub fn target_mut(&mut self) -> &mut u32 {
        &mut self.target
    }

    pub fn argument_count(&self) -> &ArgumentCount {
        &self.argument_count
    }

    pub fn argument_count_mut(&mut self) -> &mut ArgumentCount {
        &mut self.argument_count
    }

    pub fn options(&self) -> &Options {
        &self.options
    }

    pub fn options_mut(&mut self) -> &mut Options {
        &mut self.options
    }

    pub fn number_arguments(&self) -> &Vec<u32> {
        &self.number_arguments
    }

    pub fn number_arguments_mut(&mut self) -> &mut Vec<u32> {
        &mut self.number_arguments
    }

    pub fn string_arguments(&self) -> &Vec<U32OrString> {
        &self.string_arguments
    }

    pub fn string_arguments_mut(&mut self) -> &mut Vec<U32OrString> {
        &mut self.string_arguments
    }

    pub fn return_variable(&self) -> Option<u32> {
        self.return_variable
    }

    pub fn return_variable_mut(&mut self) -> &mut Option<u32> {
        &mut self.return_variable
    }

    pub fn event_name(&self) -> &Option<String> {
        &self.event_name
    }

    pub fn event_name_mut(&mut self) -> &mut Option<String> {
        &mut self.event_name
    }
}