OXYGENHUB
◆ main openmsx / share / scripts / session_management.tcl
5.3 KiB · Tcl · last changed chore(): initial commit 1 month ago source blame history raw
1
# this file implements machine session management
2
3
namespace eval session_management {
4
5
set_help_text save_session \
6
{save_session [<name>]
7
8
Saves the state of all your currently running machines as a session with the
9
given name.
10
Any existing session with that name will be silently overwritten.
11
12
See also 'load_session', 'list_sessions' and 'delete_session'.
13
}
14
15
set_help_text load_session \
16
{load_session <name>
17
18
Restores the state of all machines of the session with the given name and
19
reactivates the machine that was active at save time. Note: all machines
20
already running will be silently destroyed! (Unless no single machine succeeded
21
to be restored.)
22
23
See also 'save_session', 'list_sessions' and 'delete_session'.
24
}
25
26
set_help_text list_sessions \
27
{list_sessions
28
29
Returns the names of all previously saved sessions.
30
31
See also 'save_session', 'load_session' and 'delete_session'.
32
}
33
34
set_help_text delete_session \
35
{delete_session <name>
36
37
Delete a previously saved session.
38
39
See also 'save_session', 'load_session' and 'list_sessions'.
40
}
41
42
43
user_setting create boolean enable_session_management "Whether to save your session at exit and restore it again at start up." false
44
45
proc tabcompletion {args} {
46
	return [list_sessions]
47
}
48
49
set_tabcompletion_proc load_session [namespace code tabcompletion]
50
set_tabcompletion_proc save_session [namespace code tabcompletion]
51
set_tabcompletion_proc delete_session [namespace code tabcompletion]
52
53
proc delete_session {name} {
54
	set directory [file normalize $::env(OPENMSX_USER_DATA)/../sessions/${name}]
55
56
	# remove old session under this name
57
	file delete -force -- $directory
58
}
59
60
proc list_sessions {} {
61
	set directory [file normalize $::env(OPENMSX_USER_DATA)/../sessions]
62
	return [lsort [glob -tails -directory $directory -type d -nocomplain *]]
63
}
64
65
proc get_machine_representation {machine_id} {
66
	return "[utils::get_machine_display_name $machine_id] @ [utils::get_machine_time $machine_id]"
67
}
68
69
proc save_session {{name "untitled"}} {
70
	if {[llength [list_machines]] == 0} {
71
		return "Nothing to save..."
72
	}
73
74
	set result ""
75
76
	set directory [file normalize $::env(OPENMSX_USER_DATA)/../sessions/${name}]
77
78
	# remove old session under this name
79
	delete_session $name
80
	file mkdir $directory
81
82
	# save using ID as file names
83
	foreach machine [list_machines] {
84
		append result "Saving machine $machine ([get_machine_representation $machine])...\n"
85
		store_machine $machine [file join $directory ${machine}.oms]
86
	}
87
	# save in a separate file the currently active machine
88
	set fileId [open [file join $directory active_machine] "w"]
89
	puts $fileId [format "%s.oms" [machine]]
90
	close $fileId
91
92
	append result "Session saved as $name\n"
93
	return $result
94
}
95
96
proc load_session {name} {
97
	set result ""
98
99
	# get all savestate files
100
	set directory [file normalize $::env(OPENMSX_USER_DATA)/../sessions/${name}]
101
	set states_to_restore [glob -tails -directory $directory -nocomplain *.oms]
102
103
	# abort if we have nothing to restore
104
	if {[llength $states_to_restore] == 0} {
105
		error "Nothing found to restore..."
106
	}
107
108
	# sort them in order of ID, to guarantee consistent order as saved
109
	set states_to_restore [lsort -dictionary $states_to_restore]
110
111
	# save the machines we start with
112
	set orginal_machines [list_machines]
113
114
	# try to load file with active machine
115
	set active_machine ""
116
	catch {
117
		set fp [open [file join $directory active_machine] "r"]
118
		set active_machine [read -nonewline $fp]
119
		close $fp
120
	}
121
122
	# restore all saved machines
123
	set first true
124
	foreach state $states_to_restore {
125
		set fullname [file join $directory $state]
126
		if {[catch { ;# skip machines failing to restore
127
			set newID [restore_machine $fullname]
128
			append result "Restored $state as $newID ([get_machine_representation $newID])...\n"
129
			# activate saved active machine or alternatively, first machine
130
			if {(($active_machine ne "") && ($state eq $active_machine)) || \
131
			    (($active_machine eq "") && $first)} {
132
				activate_machine $newID
133
			}
134
			set first false
135
		} error_result]} {
136
			append result "Skipping $state: $error_result\n"
137
		}
138
	}
139
140
	# if restoring at least one machine succeeded, delete all original machines
141
	if {[llength [list_machines]] > [llength $orginal_machines]} {
142
		foreach machine $orginal_machines {
143
			delete_machine $machine
144
		}
145
	} else {
146
		append result "Couldn't restore a single machine, aborting...\n"
147
	}
148
149
	# if the active machine failed to load, activate the first machine (if available):
150
	if {[activate_machine] eq "" && [llength [list_machines]] > 0} {
151
		activate_machine [lindex [list_machines] 0]
152
	}
153
154
	return $result
155
}
156
157
variable after_quit_id
158
159
# do actual session management
160
if {$::enable_session_management} {
161
	# need after realtime command here, because openMSX needs to have started up first
162
	after realtime 0 {load_session "default_session"}
163
	set after_quit_id [after quit {save_session "default_session"}]
164
}
165
166
proc setting_changed {name1 name2 op} {
167
	variable after_quit_id
168
169
	if {$::enable_session_management} {;# setting changed from disabled to enabled
170
		set after_quit_id [after quit {save_session "default_session"}]
171
	} else { ;# setting changed from enabled to disabled
172
		catch { after cancel $after_quit_id }
173
	}
174
}
175
176
trace add variable ::enable_session_management "write" [namespace code setting_changed]
177
178
namespace export save_session
179
namespace export load_session
180
namespace export list_sessions
181
namespace export delete_session
182
183
} ;# namespace session_management
184
185
namespace import session_management::*