|
|
dev:creating_events.txt [2013/07/02 10:55] 127.0.0.1 external edit |
dev:creating_events.txt [2022/05/06 16:07] |
//From email, 2002 01 04// | |
| |
====== Events ====== | |
| |
To create a new sort of event, you just create an Event with | |
a type name that hasn't been used before, and to add properties, | |
you just use a new property name. | |
| |
(We have a big potential problem with namespacing property | |
names, as there's no central registry of names that have been | |
used. I've been considering adding something that might help, | |
because we do actually intern PropertyName strings, we just | |
don't yet complain about duplicates definitions -- but it won't | |
prevent people from using literal strings that collide. And | |
property names are global, they aren't local to a particular | |
event type. Sorry, I digress.) | |
| |
So, for example, let's say you want a new "cow" event and you | |
want to give it a couple of properties, say a string property | |
for moo type (Moo, Low or Croak -- cows with colds sound | |
terrible) and a bool to indicate whether it is in fact a bull. | |
(There are three property types; the other's int, and they're | |
defined in Property.h.) | |
| |
Aside from the properties, an Event also has an absolute time | |
(the time in Rosegarden units -- see ../data_struct/units.txt -- | |
at which the event begins), a duration (the "performance" | |
duration of the event in the same units, so currently always | |
zero for anything but note or rest events) and a sub-ordering | |
value, which is used to order events that have the same | |
absolute time (it defaults to, and most usually is, zero; but | |
for some things like clef events it's a small negative number | |
so as to ensure they get processed and displayed before any | |
notes that appear at the same time). Unlike properties, the | |
time and subordering values can only be set once, when you | |
create the event -- to modify them you must copy the event and | |
pass new values into the copy constructor (see the header file | |
for details, and see iterators.txt for discussion of how this | |
affects Segment iterators that may be pointing at those events). | |
| |
All you have to do to create a cow and insert it in a segment is | |
| |
Event *e = new Event("cow", 1000, 0); // abs time, duration | |
e->set<String>("MooType", "Low"); | |
e->set<Bool>("isBull", true); | |
segment->insert(e); | |
| |
The strings are fairly arbitrary -- you just have to ensure | |
that nobody else has already used an event called cow or | |
properties called MooType and isBull. Of course, you don't | |
see much real code using literal strings; the event types are | |
generally just declared as string constants in various places | |
(actually almost all in NotationTypes.h), but the property | |
names are usually declared as constant PropertyName objects | |
(in NotationTypes, BaseProperties or notationproperties, most | |
usually) which is a class that's constructed from a string | |
constant but interns to an integer for faster lookup, not | |
that you need to deal with that at all. | |
| |
As another example, say you want to add a property to note | |
events that indicates the usual fret number. To do that, you | |
could declare a FRET_NUMBER property name in BaseProperties | |
or notationproperties (with a value of, say, "FretNumber") | |
and then do stuff like | |
| |
Segment::iterator i = getIteratorFromSomewhere(); | |
Event *e = (*i); | |
e->set<Int>(BaseProperties::FRET_NUMBER, 4); | |
++i; | |
long fret = (*i)->get<Int>(BaseProperties::FRET_NUMBER); | |
| |
The get/set code is obviously more laborious than it would | |
be with fixed accessor methods in classes, but it's good | |
when you haven't quite decided which properties you need, | |
and it means you can extend other peoples' events, and it | |
means you get I/O done for you. | |
| |
Another thing is, you may notice various calls to "setMaybe" | |
on Events as well as to "set". This is because Events | |
distinguish between persistent properties (which have | |
usually been set by the user through the GUI somehow) that | |
get streamed out to the XML file, and non-persistent ones | |
(usually resulting from caching following some calculation, | |
and usually possible to recalculate whenever required if | |
necessary) that don't. The set method can take an extra | |
argument specifying whether you're setting a persistent or | |
non-persistent property (the default is persistent), but | |
it's rarely used: instead to set non-persistent properties | |
we generally use setMaybe, which sets a non-persistent | |
property only if there is no existing persistent property | |
of the same name. This allows the user easily to override | |
computed values, for example in the stem-direction menu | |
functions on the score view (the user's settings are | |
persistent, the computed ones are not). | |
| |
| |
===== XML format ===== | |
| |
Rosegarden's file format is a gzipped XML file with | |
a .rg extension. (We use zlib to read and write files.) | |
| |
The most basic XML elements are event and property. | |
Event has a type, subordering (sorry, forgot to describe | |
that, it's not terribly important, it just indicates the | |
ordering of events in a segment where the absolute times | |
are equal -- so we can display clef before key before any | |
notes at that time, etc) and duration, and then the event | |
element contains a series of property elements each of | |
which specifies a single property by name and type. Events | |
are assumed to start at the time at which the previous | |
event ended, except when overridden by a chord element | |
(within which all events start at once) or a resync | |
element (which specifies the starting time of the | |
following event, after which events continue to count from | |
there -- this is too verbose, we should change it to an | |
optional absolute time property on the event element). | |
| |
| |