-
Notifications
You must be signed in to change notification settings - Fork 7
/
AugmentedText.go
138 lines (119 loc) · 4.85 KB
/
AugmentedText.go
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
package edit
import (
"github.com/inkyblackness/hacked/ss1/content/audio"
"github.com/inkyblackness/hacked/ss1/edit/media"
"github.com/inkyblackness/hacked/ss1/resource"
)
// AugmentedTextBlockSetter modifies resource blocks.
type AugmentedTextBlockSetter interface {
SetResourceBlock(lang resource.Language, id resource.ID, index int, data []byte)
SetResourceBlocks(lang resource.Language, id resource.ID, data [][]byte)
DelResource(lang resource.Language, id resource.ID)
}
func augmentedTextAudioKeyFor(key resource.Key) resource.Key {
audioBase := KnownTexts().ByID(key.ID).audioBase
if audioBase == 0 {
return resource.KeyOf(0, resource.LangAny, 0)
}
soundKey := key
soundKey.ID = audioBase.Plus(key.Index)
soundKey.Index = 0
return soundKey
}
// AugmentedTextService provides read/write functionality.
type AugmentedTextService struct {
textViewer media.TextViewerService
textSetter media.TextSetterService
audioViewer media.AudioViewerService
audioSetter media.AudioSetterService
}
// NewAugmentedTextService returns a new instance based on given accessor.
func NewAugmentedTextService(
textViewer media.TextViewerService, textSetter media.TextSetterService,
audioViewer media.AudioViewerService, audioSetter media.AudioSetterService) AugmentedTextService {
return AugmentedTextService{
textViewer: textViewer,
textSetter: textSetter,
audioViewer: audioViewer,
audioSetter: audioSetter,
}
}
// WithAudio returns true if the identified resource is one with an audio component.
func (service AugmentedTextService) WithAudio(key resource.Key) bool {
return KnownTexts().ByID(key.ID).audioBase != 0
}
// Text returns the textual value of the identified text resource.
func (service AugmentedTextService) Text(key resource.Key) string {
return service.textViewer.Text(key)
}
// SetText changes the textual value of a text resource.
func (service AugmentedTextService) SetText(setter AugmentedTextBlockSetter, key resource.Key, value string) {
service.textSetter.Set(setter, key, value)
}
// RestoreTextFunc creates a snapshot of the current textual state and returns a function to restore it.
func (service AugmentedTextService) RestoreTextFunc(key resource.Key) func(setter AugmentedTextBlockSetter) {
oldText := service.textViewer.Text(key)
isModified := service.textViewer.Modified(key)
return func(setter AugmentedTextBlockSetter) {
if isModified {
service.textSetter.Set(setter, key, oldText)
} else {
service.textSetter.Remove(setter, key)
}
}
}
// Sound returns the audio value of the identified text resource.
// In case the text resource has no audio, an empty sound will be returned.
func (service AugmentedTextService) Sound(key resource.Key) audio.L8 {
if !service.WithAudio(key) {
return audio.L8{}
}
return service.audioViewer.Audio(augmentedTextAudioKeyFor(key))
}
// SetSound changes the sound of a text resource.
// Should the text resource have no audio component, this call does nothing.
func (service AugmentedTextService) SetSound(setter AugmentedTextBlockSetter, key resource.Key, sound audio.L8) { // nolint: interfacer
if service.WithAudio(key) {
service.audioSetter.Set(setter, augmentedTextAudioKeyFor(key), sound)
}
}
// RestoreSoundFunc creates a snapshot of the current sound and returns a function to restore it.
// In case the text resource has no audio, a stub method will be returned.
func (service AugmentedTextService) RestoreSoundFunc(key resource.Key) func(setter AugmentedTextBlockSetter) {
if !service.WithAudio(key) {
return func(setter AugmentedTextBlockSetter) {}
}
soundKey := augmentedTextAudioKeyFor(key)
isSoundModified := service.audioViewer.Modified(soundKey)
oldSound := service.audioViewer.Audio(soundKey)
return func(setter AugmentedTextBlockSetter) {
if isSoundModified {
service.audioSetter.Set(setter, soundKey, oldSound)
} else {
service.audioSetter.Remove(setter, soundKey)
}
}
}
// Clear sets the text to an empty string and sets an empty sound if audio is associated.
func (service AugmentedTextService) Clear(setter AugmentedTextBlockSetter, key resource.Key) {
service.textSetter.Clear(setter, key)
if service.WithAudio(key) {
service.audioSetter.Clear(setter, augmentedTextAudioKeyFor(key))
}
}
// Remove erases the text and audio from the resources.
func (service AugmentedTextService) Remove(setter AugmentedTextBlockSetter, key resource.Key) {
service.textSetter.Remove(setter, key)
if service.WithAudio(key) {
service.audioSetter.Remove(setter, augmentedTextAudioKeyFor(key))
}
}
// RestoreFunc creates a snapshot of all associated media components and returns a function to restore it.
func (service AugmentedTextService) RestoreFunc(key resource.Key) func(setter AugmentedTextBlockSetter) {
restoreText := service.RestoreTextFunc(key)
restoreSound := service.RestoreSoundFunc(key)
return func(setter AugmentedTextBlockSetter) {
restoreText(setter)
restoreSound(setter)
}
}