GSoC:2008 GenIPC
- Student: Leonid Evdokimov
- Mentor: Anders Waldenborg
- Current milestone: Student accepted
- Next milestone: C clientlib
client library code generator that should ease consistent API definition. Detailed description of project
That's temporary place to unload mess from the brain to.
- Low-level IPC that knows nothing about XMMS2
- connect(URL), that should register itself within mainloop too
- buffered(?) write
- reading bytes and sending them to upper layer, it's GenIPC work to split stream into packets
- forcing disconnection
- Serialization to basic types:
- «int32» and «uint32» – should be sent in network-byte order
- «string» – should be sent in UTF-8 encoding
- «data» – some set of bytes that should fit in memory, sending DVD images over XMMS2 is not the best idea
NO, it makes things too low-level.
Right now every message sent to server looks like:
data | meaning |
---|---|
Type of Object ID | Reserved integer, almost like IANA's TCP ports. |
Method ID | Another hardcoded integer |
Object ID | Playlist name, collection name, medialib entry id |
payload | some weird bytes |
Well, that's cool, but RESERVED NUMBERS?!
Why am I against reserved numbers? That's easy, XML does not have numbers inside, any text description does not have any reserved numbers inside.
Adding reserved numbers to text description makes things worse, they need maintaining, they should preserve compatibility. Reserved number should be generated and all we have are names of "class", "method" and/or "property". Reserved number should remain persistent in case of reordering entries in XML file.
Destroying reserved numbers and replacing reserved numbers with reserved words makes service clients more natural.
Should it be possible to register two instances of same "service client" in case of name collision? No, only one client should do actual work, other clients should listen for an event about the work done, though spying function calls MAY be useful.
There are two major types of Xmms2 objects that are manipulated with API: Singleton/Monostate objects (like "stats" or "medialib") and "numerous" objects, e.g. playlists or collections that have some identifier attached. It should be possible to apply any function to any numerous object, e.g. it should be possible to shuffle stored playlist (well, xmms2d may return "non implemented" error at first).
LOGICAL_EXP: 'NOT' LOGICAL_EXP
| LOGICAL_EXP "AND" LOGICAL_EXP
| LOGICAL_EXP "OR" LOGICAL_EXP
| '(' LOGICAL_EXP ')'
| 'TRUE'
| 'FALSE'
| MATH_EXP '<' MATH_EXP
| MATH_EXP '>' MATH_EXP
| MATH_EXP '<=' MATH_EXP
| MATH_EXP '>=' MATH_EXP
| MATH_EXP '==' MATH_EXP
MATH_EXP: 'actual_value'
| 'actual_time'
| 'last_sent_value'
| 'last_sent_time'
| '(' MATH_EXP ')'
| NUMERIC
| MATH_EXP '+' MATH_EXP
| MATH_EXP '-' MATH_EXP
| MATH_EXP '*' MATH_EXP
| MATH_EXP '/' MATH_EXP
NUMERIC: /* some integer or floating number */
I hope, nobody wants "sin" and "log".
Maybe I should use BC as a library?
Property manipulation functions, every function returns new value:
- numerical:
- type add(type X)
- type sub(type X)
- type set(type X)
- type get()
- list:
- int length watchable, is numerical property
- map<K, V>:
- list keys
Changing sub-value (e.g. map<K, V>[k] = new_v) fires watch functions attached to container. For example, that makes possible to watch either all config key-value pairs or only equaliser-related ones.
Evey watch function may have some LOGICAL_EXP's attached, every function may introduce time-related limits, function watching numerical types can also attach value-related limits. FIXME: review grammar to limit possible expressions. It's bad idea to recheck expression during every iteration, time-related expressions should be convertable to timers, value-related expressions can be checked on value modification.
Static methods:
- list list()
-
string current()it becomes impossible to have two playback streams with different playlist - void create(string name)
Object methods:
- void ->destroy()
- void ->shuffle()
- void ->insert(binstring url, bool recursive = false, int pos = -1) non-encoded URL should be given
- void ->insert(int track_id, int pos = -1) WTF: that's just a helper, it creates idlist internally
- void ->insert(collection idlist, int pos = -1)
- void ->insert(collection coll, list order, int pos = -1)
- void ->erase(int position)
- void ->clear()
- void ->sort(list order)
- void ->move(int old_pos, int new_pos)
- void ->load()
Object's data members:
- int ->position
- list ->tracklist readonly
xmmsc_result_t *xmmsc_broadcast_playlist_changed (xmmsc_connection_t *c);
xmmsc_result_t *xmmsc_broadcast_playlist_current_pos (xmmsc_connection_t *c);
watching Playlist(name)->tracklist, Playlist(name)->position
xmmsc_result_t *xmmsc_broadcast_playlist_loaded (xmmsc_connection_t *c);
is moved to Playback(name)->playlist
Types:
- enumeration status { PLAY, STOP, PAUSE }
Static methods:
- void create(string name)
Static data members:
- list ->list
Object's data members:
- enumeration status ->status
status.set(PLAY) while playing ~= tickle(), i.e. forcing decoding the song at
Playlist(this->playlist).position
- string ->playlist
- int ->timestamp_ms
- int ->timestamp_samples
- map<string, int> ->volume volume.keys is immutable
- int ->current_id readonly it's used to show the track that is REALLY playing, e.g. current playlist and playlist position could be changed while the track is playing, but playing new track was not enforced, so it's stored here
xmmsc_result_t *xmmsc_broadcast_playback_volume_changed (xmmsc_connection_t *c);
xmmsc_result_t *xmmsc_broadcast_playback_status (xmmsc_connection_t *c);
xmmsc_result_t *xmmsc_signal_playback_playtime (xmmsc_connection_t *c);
xmmsc_result_t *xmmsc_broadcast_playback_current_id (xmmsc_connection_t *c);
watching Playback(name)->volume[channel], Playback(name)->timestamp_ms, Playback(name)->status, Playback(name)->current_id
Static methods:
- void register(string key, string default_value)
Static data members:
- map<string, string> value
xmmsc_result_t *xmmsc_broadcast_configval_changed (xmmsc_connection_t *c);
This article or section needs to be updated. Parts of this article or section have been identified as no longer being up to date. Please update the article to reflect recent events, and remove this text when finished.
Static methods:
- string entry_format(property_dict)
- void add(binstring url, bool recursive = false) non-encoded URL should be given
- property_dict get_info(int id)
- void rehash(int id = 0)
- int get_id(binstring url)
- void erase(int id)
- void rename(int id, binstring url)
- void property_set(int id, string key, int value)
- void property_set(int id, string source, string key, int value)
- void property_set(int id, string key, string value)
- void property_set(int id, string source, string key, string value)
- void property_remove(int id, string key)
- void property_remove(int id, string source, string key)
xmmsc_result_t *xmmsc_broadcast_medialib_entry_changed (xmmsc_connection_t *c);
xmmsc_result_t *xmmsc_broadcast_medialib_entry_added (xmmsc_connection_t *c);
source
defaults to "client/${CLIENT_NAME}"
Types:
- dict dentry { path: string, isdir: bool, realpath?: string, ... }
Static methods:
- list browse(binstring url)
Static methods:
- string add(binstring buffer)
- void remove(string hash)
Static data members:
- list keys readonly
- binstring data[string keys] readonly
This article or section needs to be updated. Parts of this article or section have been identified as no longer being up to date. Please update the article to reflect recent events, and remove this text when finished.
This article or section needs to be updated. Parts of this article or section have been identified as no longer being up to date. Please update the article to reflect recent events, and remove this text when finished.
Content is available under GNU Free Documentation License 1.2 unless otherwise noted.
- Community
- Development