Skip to content

Commit 84403bf

Browse files
refactor: os dependent log reading loop
1 parent 88404c4 commit 84403bf

1 file changed

Lines changed: 107 additions & 39 deletions

File tree

src/core/scriptslog.rs

Lines changed: 107 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,64 @@ use crate::constants;
1010
/// the string passed to said printer will consist of one or more lines of text.
1111
pub fn tail_scriptslog<P>( printer: P, refresh_time_millis: u64, cancel_token: Receiver<()>, custom_path: Option<String> ) -> Option<String>
1212
where P: Fn(&String) -> () {
13-
match scriptslog_file(custom_path) {
13+
if let Some(p) = custom_path {
14+
tail_scriptslog_loop(Path::new(&p).to_path_buf(), printer, refresh_time_millis, cancel_token)
15+
} else {
16+
match scriptslog_file_path() {
17+
Ok(p) => {
18+
tail_scriptslog_loop(p, printer, refresh_time_millis, cancel_token)
19+
}
20+
Err(e) => {
21+
Some(e)
22+
}
23+
}
24+
}
25+
}
26+
27+
fn scriptslog_file_path() -> Result<PathBuf, String> {
28+
let mut docs = None;
29+
if let Some(ud) = UserDirs::new() {
30+
if cfg!(windows) {
31+
if let Some(path) = ud.document_dir() {
32+
docs = Some(path.to_owned());
33+
}
34+
}
35+
else if cfg!(unix) {
36+
if let Some(path) = Some(ud.home_dir()) {
37+
docs = Some(path.join(constants::LINUX_STEAM_PFX_PATH).to_owned());
38+
}
39+
}
40+
else {
41+
unimplemented!();
42+
}
43+
}
44+
45+
if let Some(docs) = docs {
46+
return Ok( docs.join(Path::new("The Witcher 3").join(constants::SCRIPTSLOG_FILE_NAME)) );
47+
} else {
48+
return Err( "Documents directory could not be found.".to_owned() );
49+
}
50+
}
51+
52+
fn open_scriptslog(path: &PathBuf) -> Result<File, String> {
53+
let file = OpenOptions::new()
54+
.read(true)
55+
.write(true) // so that it can be created if doesn't exist
56+
.create(true)
57+
.open(path);
58+
59+
if let Err(e) = file {
60+
println!("{:?}", e.kind());
61+
return Err("File open error: ".to_owned() + &e.to_string());
62+
} else {
63+
return Ok(file.unwrap());
64+
}
65+
}
66+
67+
#[cfg(target_os = "windows")]
68+
fn tail_scriptslog_loop<P>(scriptslog_path: PathBuf, printer: P, refresh_time_millis: u64, cancel_token: Receiver<()>) -> Option<String>
69+
where P: Fn(&String) -> () {
70+
match open_scriptslog(&scriptslog_path) {
1471
Ok(file) => {
1572
let mut reader = BufReader::new(&file);
1673
// start from the end of the file
@@ -53,50 +110,61 @@ where P: Fn(&String) -> () {
53110
Err(e) => {
54111
Some(e)
55112
}
56-
}
113+
}
57114
}
58115

59-
fn scriptslog_file(custon_path: Option<String>) -> Result<File, String> {
60-
let scriptslog_path: PathBuf;
61-
62-
if let Some(custom_path) = custon_path {
63-
scriptslog_path = Path::new(&custom_path).to_owned();
64-
} else if let Some(ud) = UserDirs::new() {
65-
let mut docs = None;
66-
if cfg!(windows) {
67-
if let Some(path) = ud.document_dir() {
68-
docs = Some(path.to_owned());
69-
}
70-
}
71-
else if cfg!(unix) {
72-
if let Some(path) = Some(ud.home_dir()) {
73-
docs = Some(path.join(constants::LINUX_STEAM_PFX_PATH).to_owned());
116+
#[cfg(target_os = "linux")]
117+
fn tail_scriptslog_loop<P>(scriptslog_path: PathBuf, printer: P, refresh_time_millis: u64, cancel_token: Receiver<()>) -> Option<String>
118+
where P: Fn(&String) -> () {
119+
let mut last_pos: u64;
120+
match open_scriptslog(&scriptslog_path) {
121+
Ok(file) => last_pos = file.metadata().unwrap().len(),
122+
Err(e) => {
123+
return Some(e)
124+
}
125+
}
126+
127+
let mut text = String::new();
128+
loop {
129+
match cancel_token.try_recv() {
130+
Ok(_) | Err(TryRecvError::Disconnected) => {
131+
break;
74132
}
75-
}
76-
else {
77-
unimplemented!();
133+
Err(_) => {}
78134
}
135+
136+
// on linux file system is different in a sense that we have to reopen the file to see the changes made to it
137+
match open_scriptslog(&scriptslog_path) {
138+
Ok(file) => {
139+
let mut reader = BufReader::new(&file);
140+
let filesize = file.metadata().unwrap().len();
79141

80-
if let Some(docs) = docs {
81-
scriptslog_path = docs.join(Path::new("The Witcher 3").join(constants::SCRIPTSLOG_FILE_NAME));
82-
} else {
83-
return Err( "Documents directory could not be found.".to_owned() );
84-
}
142+
if last_pos > filesize {
143+
last_pos = reader.seek(SeekFrom::Start(0)).unwrap();
144+
} else {
145+
reader.seek(SeekFrom::Start(last_pos)).unwrap();
146+
}
85147

86-
} else {
87-
return Err("Scriptslog path could not be resolved".to_owned());
148+
text.clear();
149+
match reader.read_to_string(&mut text) {
150+
Ok(size) => {
151+
if size > 0 {
152+
last_pos += size as u64;
153+
printer(&text);
154+
}
155+
}
156+
Err(e) => {
157+
return Some("File read error: ".to_owned() + &e.to_string())
158+
}
159+
}
160+
}
161+
Err(e) => {
162+
return Some(e)
163+
}
164+
}
165+
166+
std::thread::sleep( Duration::from_millis( refresh_time_millis ) );
88167
}
89168

90-
let file = OpenOptions::new()
91-
.read(true)
92-
.write(true) // so that it can be created if doesn't exist
93-
.create(true)
94-
.open(scriptslog_path);
95-
96-
if let Err(e) = file {
97-
println!("{:?}", e.kind());
98-
return Err("File open error: ".to_owned() + &e.to_string());
99-
} else {
100-
return Ok(file.unwrap());
101-
}
169+
None
102170
}

0 commit comments

Comments
 (0)