-
Notifications
You must be signed in to change notification settings - Fork 0
Architecture
- Main (UI)
- Audio
- Spotify
- Should each thread contain a private message loop?
Yes - Should session management be on a separate thread?
Yes, see here - Are session callbacks run on a main thread (in particular, are they run on the thread they were registered at)?
No
- UI (platform specific)
- Configuration
- Parser (use INI format and boost property tree library)
- Search engine
- Search
- SearchQuery
- Audio system (audio playing subsystem will be platform specific)
- MainLoop (platform specific; used to register sp_session_process_events)
- Session (split it into sub-interfaces? hardly possible!)
Currently configuration management is not very flexible. Load/save API is coupled with what properties configuration object stores. Thus, if a second configuration object would be needed it would need to contain its own load/save API crafted specifically for it needs. In that case it would be a good idea to decouple load/save API from a configuration object. This, however, would require for the configuration object to be a mapping container (simple solution) or it would have to provide serializing/deserializing API. The actual loading/saving could be done by a separate entity - Configuration Manager.
Configuration Manager could additionally watch for external changes in the configuration file (edited by user via an external editor) and either trigger configuration update in run-time or if necessary forward notification to the user with suggestion to restart the application.
This component should outlive all others.
Preallocate some memory for buffering
- Allocate a buffer (pool?) for delivered frames
- music_delivery fills a buffer if it is unused (up to the size of the buffer), if not 0 is returned so that libspotify resends the frames
- music_delivery calls on_frame_delivered (on engine thread)
- on_frame_delivered launches all the signals
- on_frame_delivered marks the buffer as unused
Should active_ flag be set not only via a task but explicitly in the stop() method as well?
Pros
- If there are many tasks in the queue all of the non-timed tasks would have to be executed before the one that sets the active_ flag but this way loop can finish at the next iteration (but is it a good approach?)
Cons
- It has to be atomic
If it is decided that active_ should be set in stop() as well then queue would have to be cleared so that on next call to start(), though not a common use case, old tasks are not restored (don't I want that?). This would have to be done probably in the start() method since it can't be done in stop() (since quit task is queued there).