Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
dev:creating_events.txt [2013/07/02 10:55]
127.0.0.1 external edit
dev:creating_events.txt [2022/05/06 16:07] (current)
Line 3: Line 3:
 ====== Events ====== ====== Events ======
  
-To create a new sort of event, you just create an Event with +An Event is the object type in Rosegarden that corresponds to a musical note.  It can also represent a rest, a time signature, a tempo change, a key signature.  In fact, just about anything that lives at particular time in the score is represented as an event
-type name that hasn't been used before, and to add properties, +
-you just use new property name.+
  
-(We have big potential problem with namespacing property +How does Event manage to represent all those different things?  Well, it doesn't use polymorphism - Event is single C++ class.  It uses properties. 
-names, as there's no central registry of names that have been + 
-used.  I've been considering adding something that might help+Properties are stored inside events in a map from property name-string to property value.  They are not C++ fields, and in fact you would have to dig fairly deep in the code to get their real representation. 
-because we do actually intern PropertyName stringswe just + 
-don'yet complain about duplicates definitions -- but it won't +===== Property types ===== 
-prevent people from using literal strings that collide.  And + 
-property names are globalthey aren't local to a particular +There are four: Int, String, Bool, and RealTimeT.   
-event type.  SorryI digress.)+ 
 +Technically, they are template specializations on 4 enumeration values.  They are defined in Property.h.  Other than knowing the names, you probably don't need to pay attention to that part. 
 + 
 +  * Event::has(const PropertyName &name) returns whether an event has a value for the given property. 
 +  * The template Event::get<PropertyType P> returns the value for the given property.  There is also bool Event::get<PropertyType P>(name&val) which sets it by reference. 
 +  * The template Event::set<PropertyType P>(namevalue) sets the given property to a given value.  There is also setMaybe which sets it if it wasn't already set. 
 + 
 +===== Event nominal type ===== 
 + 
 +An event also stores a string that declares its nominal type.  This is a std::string.  Its text isn'important, though it should be descriptive, but it should be unique. 
 + 
 +  * Event::getType() returns an event's type string 
 +  * Event::isa() returns true if the event is of the given type. 
 +  * Some Event constructors take a type string. 
 + 
 +===== Other data that event stores ===== 
 + 
 +Aside from the properties and type string, 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 detailsand see iterators.txt for discussion of how this affects Segment iterators that may be pointing at those events). 
 + 
 +===== How to create new sort of event ===== 
 + 
 +To create a new sort of event, you will need these things: 
 +  * A unique name as a std:string 
 +  * A unique name for each new property, as a PropertyName which is basically an interned std::string. 
 +  * A suborderingwhich controls whether it is first if there are two events at the same time.  It's an integer that means sorting priority.  You probably shouldn't make the subordering negative, which is the realm of key signatures and time signatures. 
 + 
 +These things are typically provided by an event [[#Adapters|adapter]], but we won't get into that here.
  
 So, for example, let's say you want a new "cow" event and you So, for example, let's say you want a new "cow" event and you
Line 22: Line 47:
 (There are three property types; the other's int, and they're (There are three property types; the other's int, and they're
 defined in Property.h.) 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 All you have to do to create a cow and insert it in a segment is
Line 94: Line 103:
 persistent, the computed ones are not).  persistent, the computed ones are not). 
  
 +===== Uniqueness of property names =====
 +
 +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.
 +
 +===== Saving and restoring properties =====
 +
 +This part is easy.  You don't have to do anything special when you use a new property type.  Rosegarden automatically writes all of an event's properties to the savefile, and automatically reads all of them when you restore.  See [[XML_format]]
 +
 +===== Adapters =====
  
-===== XML format =====+When you adapt Event for a new purpose, it's often helpful to create an adapter class for them.  If you examine the files NotationTypes.h and NotationTypes.cpp, you will notice a number of classes that adapt Event for time signature, key signature, etc.
  
-Rosegarden's file format is a gzipped XML file with +One word: NotationTypes is already crowded.  We have a policy of putting visible classes in a pair of files of their own name, but NotationTypes flagrantly violates that rule.  Please don't follow our bad example.
-a .rg extension.  (We use zlib to read and write files.)+
  
-The most basic XML elements are event and property. +Typically an adapter includes: 
-Event has a type, subordering (sorry, forgot to describe +  
-that, it'not terribly important, it just indicates the +  * Fields that represent the event'data.  These are generally the only non-static data fields of the dapater. 
-ordering of events in a segment where the absolute times +  * A std::string that names the event type.  There can be more than only, but the primary one should be called EventType. 
-are equal -- so we can display clef before key before any +  * The subordering. 
-notes at that time, etc) and duration, and then the event +  * One constructor that constructs it just from reference to Event. 
-element contains a series of property elements each of +  * A method named getAsEvent thatgiven a time, returns a new Event (on the heapcorresponding to that adapter's data.
-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 resync +
-element (which specifies the starting time of the +
-following event, after which events continue to count from +
-there -- this is too verbosewe should change it to an +
-optional absolute time property on the event element). +
  
  
 
 
dev/creating_events.txt.1372762529.txt.gz · Last modified: 2022/05/06 16:07 (external edit)
Recent changes RSS feed Creative Commons License Valid XHTML 1.0 Valid CSS Driven by DokuWiki