mirror of
				https://github.com/ElvishArtisan/rivendell.git
				synced 2025-10-30 09:13:51 +01:00 
			
		
		
		
	* Documented the font management system in 'docs/apis/fonts.xml' (built as 'docs/apis/fonts.pdf'.
		
			
				
	
	
		
			344 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			344 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| This is the CODINGSTYLE file for the Rivendell package.
 | |
| 
 | |
| OVERVIEW:
 | |
| This file, CODINGSTYLE, describes the coding style guidelines for writing
 | |
| new code, how to submit patches to be incorporated into the official
 | |
| Rivendell Git repository, and other code related information. General info
 | |
| on the Rivendell project can be found at the http://www.rivendellaudio.org/
 | |
| web page and also in the 'README' and 'INSTALL' files.  
 | |
| 
 | |
| The code style used for Rivendell is a somewhat idiosyncratic mixture of
 | |
| the style generally used for Qt C++ programs combined with the classic UNIX
 | |
| C style. Some of the specifics include:
 | |
| 
 | |
| 
 | |
| LINE LENGTH:
 | |
| Should not be longer than 78 characters unless doing so would severely
 | |
| compromise the readability of the code. Where it is necessary to break a
 | |
| line, it should be done at a point that preserves maximum clarity and ease
 | |
| of reading.
 | |
| 
 | |
| Good:
 | |
|   *report+=QString(" ")+
 | |
|     logLine(i)->startTime(RDLogLine::Logged).toString("hh:mm:ss")+
 | |
|     QString().sprintf(" - cart %06d [",logLine(i)->cartNumber())+
 | |
|     q->value(1).toString()+"] "+QObject::tr("is not playable")+"\n";
 | |
| 
 | |
| Bad:
 | |
|   *report+=QString(" ")+logLine(i)->startTime(RDLogLine::Logged).toString("hh:mm:ss")+QString().sprintf(" - cart %06d [",logLine(i)->cartNumber())+q->value(1).toString()+"] "+QObject::tr("is not playable")+"\n";
 | |
| 
 | |
| 
 | |
| INDENTATION:
 | |
| Should be two spaces per level. This helps to keep the line length down.
 | |
| 
 | |
| Good:
 | |
|   if(to_line<0) {
 | |
|     to_line=size();
 | |
|     for(int i=from_line;i<size();i++) {
 | |
|       if(logLine(i)->timeType()==RDLogLine::Hard) {
 | |
| 	to_line=i;
 | |
| 	i=size();
 | |
| 	if(sched_time!=NULL) {
 | |
| 	  *sched_time=logLine(i)->startTime(RDLogLine::Logged);
 | |
| 	}
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
| Bad:
 | |
|   if(to_line<0) {
 | |
|           to_line=size();
 | |
| 	  for(int i=from_line;i<size();i++) {
 | |
|                   if(logLine(i)->timeType()==RDLogLine::Hard) {
 | |
| 	                  to_line=i;
 | |
| 	                  i=size();
 | |
| 	                  if(sched_time!=NULL) {
 | |
| 	                          *sched_time=logLine(i)->startTime(RDLogLine::Logged);
 | |
| 	                  }
 | |
|                    }
 | |
|            }
 | |
|   }
 | |
| 
 | |
| 
 | |
| CURLY BRACES:
 | |
| Conditional statements (such as 'if' and 'for') should *always* use curly
 | |
| braces, even where the affected block is but one line long. The opening
 | |
| brace should be on the same line as the conditional and the closing one on
 | |
| a line by itself. This style greatly facilitates debugging, allowing a
 | |
| single line to be provisionally commented out or additional lines to be
 | |
| provisionally added without making the enclosing conditional syntactically
 | |
| invalid.
 | |
| 
 | |
| Good:
 | |
|   if(i==12) {
 | |
|     printf("i is equal to twelve!\n");
 | |
|   }
 | |
| 
 | |
| Bad:
 | |
|   if(i==12)
 | |
|     printf("i is equal to twelve!\n");
 | |
| 
 | |
| 
 | |
| PADDING WHITESPACE:
 | |
| Wherever possible, there should be no whitespace between constants/variables
 | |
| and operators. This helps to keep the line length down.
 | |
| 
 | |
| Good:
 | |
|   for(int i=from_line;i<size();i++) {
 | |
|     if(logLine(i)->timeType()==RDLogLine::Hard) {
 | |
|       to_line=i;
 | |
|     }
 | |
|   }
 | |
| 
 | |
| Bad:
 | |
|   for(int i = from_line; i < size(); i++) {
 | |
|     if(logLine(i)->timeType() == RDLogLine::Hard) {
 | |
|       to_line = i;
 | |
|     }
 | |
|   }
 | |
| 
 | |
| 
 | |
| CLASS NAMES:
 | |
| Should have the initial letter of each word capitalized, e.g. 'ThisIsMyClass'.
 | |
| If the class is part of the librd convenience library (in 'lib/'), the name
 | |
| should be prefaced with the uppercase letters 'RD', e.g. 'RDThisIsMyClass'.
 | |
| 
 | |
| 
 | |
| METHOD NAMES:
 | |
| Public method names as well as signal and slot method names should follow
 | |
| the general style used by Qt. A special convention for Rivendell is to
 | |
| reserve names beginning with an uppercase letter for private methods only.
 | |
| 
 | |
| Good:
 | |
| class RDLogPlay
 | |
| {
 | |
|  Q_OBJECT
 | |
|  public:
 | |
|   RDLogPlay(int id,RDEventPlayer *player,QObject *parent=0);
 | |
|   QString serviceName() const;
 | |
|   void setServiceName(const QString &svcname);
 | |
| 
 | |
|  private slots:
 | |
|   void transTimerData();
 | |
|   void graceTimerData();
 | |
| 
 | |
|  signals:
 | |
|   void renamed();
 | |
|   void reloaded();
 | |
|   void transportChanged();
 | |
| 
 | |
|  private:
 | |
|   bool StartEvent(int line,RDLogLine::TransType trans_type,int trans_length,
 | |
| 		  RDLogLine::StartSource src,int mport=-1,int duck_length=0);
 | |
|   bool StartAudioEvent(int line);
 | |
| };
 | |
| 
 | |
| Bad:
 | |
| class RDLogPlay
 | |
| {
 | |
|  Q_OBJECT
 | |
|  public:
 | |
|   RDLogPlay(int id,RDEventPlayer *player,QObject *parent=0);
 | |
|   QString servicename() const;
 | |
|   void set_service_name(const QString &svcname);
 | |
| 
 | |
|  private slots:
 | |
|   void TransTimerData();
 | |
|   void grace_timer_data();
 | |
| 
 | |
|  signals:
 | |
|   void RENAMED();
 | |
|   void Reloaded();
 | |
|   void transport_changed();
 | |
| 
 | |
|  private:
 | |
|   bool startEvent(int line,RDLogLine::TransType trans_type,int trans_length,
 | |
| 		  RDLogLine::StartSource src,int mport=-1,int duck_length=0);
 | |
|   bool startAudioEvent(int line);
 | |
| };
 | |
| 
 | |
| 
 | |
| VARIABLE NAMES:
 | |
| *All* variables should be lowercase only, with uppercase being reserved for
 | |
| class and method names. Words should be separated by underscores.
 | |
| 
 | |
| Good:
 | |
|   int log_position_number=1;
 | |
| 
 | |
| Bad:
 | |
|   int logPositionNumnber=1;
 | |
| 
 | |
| Class variables should be prefaced with a short base name that is common to
 | |
| all, followed by an underscore. For example, the class 'MyClass' might use
 | |
| 'myclass_', as in 'myclass_foo1', 'myclass_foo2', etc. Local variables
 | |
| (including function parameter names) should be kept short, preferably a
 | |
| single word.
 | |
| 
 | |
| 
 | |
| SQL STATEMENTS:
 | |
| When embedding SQL statements in code, the following guidelines should be
 | |
| followed:
 | |
| 
 | |
| 1) All table and field names are uppercase-only, while SQL operators
 | |
|    should be all lowercase.
 | |
| 
 | |
| Good:
 | |
|   sql="select FIELD1,FIELD2 from MY_TABLE where ID=2";
 | |
| 
 | |
| Bad:
 | |
|   sql="SELECT FIELD1,FIELD2 FROM MY_TABLE WHERE ID=2";
 | |
| 
 | |
| 2) Long or complex SQL statements should be broken into multiple lines in
 | |
|    a manner to enhance the readability of both C++ and SQL. For 'select'
 | |
|    queries that return more than two fields per row, each field should be
 | |
|    commented with its ordinal number to assist in determining the
 | |
|    appropriate value to give to 'RDSqlQuery::value()' for referencing
 | |
|    the fields.
 | |
| 
 | |
| Good:
 | |
|   sql=QString("select ")+
 | |
|     "CART.TITLE,"+         // 00
 | |
|     "CART.ARTIST,"+        // 01
 | |
|     "CART.PUBLISHER,"+     // 02
 | |
|     "CART.COMPOSER,"+      // 03
 | |
|     "CART.USAGE_CODE,"+    // 04
 | |
|     "CUTS.ISRC,"+          // 05
 | |
|     "CART.ALBUM,"+         // 06
 | |
|     "CART.LABEL,"+         // 07
 | |
|     "CUTS.ISCI,"+          // 08
 | |
|     "CART.CONDUCTOR,"+     // 09
 | |
|     "CART.USER_DEFINED,"+  // 10
 | |
|     "CART.SONG_ID,"+       // 11
 | |
|     "CUTS.DESCRIPTION,"+   // 12
 | |
|     "CUTS.OUTCUE "+        // 13
 | |
|     "from CART left join CUTS "+
 | |
|     "on CART.NUMBER=CUTS.CART_NUMBER where "+
 | |
|     "CUTS.CUT_NAME=\""+RDEscapeString(button->cutName())+"\"";
 | |
| 
 | |
| Bad:
 | |
|   sql="select CART.TITLE,CART.ARTIST,CART.PUBLISHER,CART.COMPOSER,CART.USAGE_CODE,CUTS.ISRC,CART.ALBUM,CART.LABEL,CUTS.ISCI,CART.CONDUCTOR,CART.USER_DEFINED,"+ CART.SONG_ID,CUTS.DESCRIPTION,CUTS.OUTCUE from CART left join CUTS on CART.NUMBER=CUTS.CART_NUMBER where CUTS.CUT_NAME=\""+RDEscapeString(button->cutName())+"\"";
 | |
| 
 | |
| 
 | |
| SCHEMA CHANGES:
 | |
| Changes that alter the schema of the database must include:
 | |
| 
 | |
|   A) Incrementation of the 'RD_VERSION_DATABASE' value in 'lib/dbversion.h'.
 | |
| 
 | |
|   B) Code that implements the schema change, in the
 | |
|      'utils/rddbmgr/updateschema.cpp' file.
 | |
| 
 | |
|   C) Code the implements an exact, perfect reversal of the schema change,
 | |
|      in the 'utils/rddbmgr/revertschema.cpp' file.
 | |
| 
 | |
|   D) Updating of the schema map in the 'MainObject::InitializeSchemaMap()'
 | |
|      method in the 'utils/rddbmgr/schemamap.cpp' file. (See the comment at
 | |
|      the top of the method definition for details).
 | |
| 
 | |
|   E) Update the table documentation appropriately in 'docs/tables/'.
 | |
| 
 | |
|   F) [VERY IMPORTANT] - Document the changes to the schema in your
 | |
|      'ChangeLog' entry, including the new value of 'RD_VERSION_DATABASE'.
 | |
| 
 | |
| 
 | |
| FONT MANGEMENT:
 | |
| All fonts used in Rivendell are managed by the RDFontEngine class, which
 | |
| provides them on the basis of abstract "roles" so as to provide consistency
 | |
| across the entire set of modules. See the file 'docs/apis/fonts.pdf' for
 | |
| a detailed description of this sub-system, including screenshot examples.
 | |
| 
 | |
| 
 | |
| WRITING TO THE SYSLOG:
 | |
| Rivendell makes extensive use of the syslog(3) system found on all
 | |
| POSIX-compliant systems. Sending messages to the syslog should almost
 | |
| always be done by means of the following method in 'RDApplication':
 | |
| 
 | |
|   void RDApplication::syslog(int priority,const char *format,...)
 | |
| 
 | |
| The exception to the above is when the application context does not
 | |
| include a global RDApplication object --e.g. in caed(8). For those
 | |
| cases, the following static RDApplication method should be used:
 | |
| 
 | |
|   void RDApplication::syslog(RDConfig *c,int priority,const char *format,...)
 | |
| 
 | |
| For a discussion of the parameters of these methods, see the syslog(3) man
 | |
| page. The 'priority' parameter should be one of the following values:
 | |
| 
 | |
|     LOG_ERR - Indicates that a fatal error has occurred; 'fatal' meaning
 | |
|               that the program is unable to continue and will now exit.
 | |
| 
 | |
| LOG_WARNING - Indicates that a non-fatal error has occured; meaning
 | |
|               that the program will continue to operate, but with
 | |
|               possibly significant operational degradation. This would be
 | |
|               appropriate for things like failure to connect to an
 | |
|               external switcher or other device.
 | |
| 
 | |
|    LOG_INFO - Information useful for tracking operational state --e.g.
 | |
|               a cart play-out has begun, a new Rivendell log has been
 | |
|               loaded, etc.
 | |
| 
 | |
|   LOG_DEBUG - Information useful for tracking or verifying Rivendell
 | |
|               software internal state. These messages will not normally
 | |
|               be seen by users, but can be made visible to allow for
 | |
| 	      program debugging.  
 | |
| 
 | |
| NOTE: A 'facility' value should *not* be included in the 'priority'
 | |
| argument. The appropriate 'facility' value, as determined by the
 | |
| 'SyslogFacility=' directive in rd.conf(5), will be added automatically.
 | |
| 
 | |
| 
 | |
| CONTRIBUTING CHANGES:
 | |
| The master code repository for Rivendell resides at GitHub, and can be
 | |
| found at:
 | |
| 
 | |
|       https://github.com/ElvishArtisan/rivendell
 | |
| 
 | |
| Changes should be submitted in the form of a pull request [PR] against
 | |
| the 'master' branch. Information about drafting and submitting PRs can
 | |
| be found at:
 | |
| 
 | |
|     https://help.github.com/en/articles/about-pull-requests
 | |
| 
 | |
| 
 | |
| PULL REQUEST CHECKLIST:
 | |
| Before submitting a pull request, the following guidelines should be
 | |
| completed:
 | |
| 
 | |
| 1) The code should compile without errors or warnings [the '-Werrors' switch
 | |
|    for gcc(1) is your friend here!].
 | |
| 
 | |
| 2) Add an entry to the 'ChangeLog' file at the base of the Rivendell source
 | |
|    code tree, describing your changes. The format of the ChangeLog file has
 | |
|    the most recent changes at the bottom of the file. Entries start with a
 | |
|    date stamp and have a format like:
 | |
| 
 | |
|     YYYY-MM-DD NAME <EMAIL>
 | |
|     * Description of change
 | |
| 
 | |
| For example:
 | |
|     2007-02-23 John Coder <coder@example.com>
 | |
| 	* Modified the code in 'lib/rdimport_audio.cpp' to use the
 | |
| 	'RDCart::setMetadata()' and 'RDCut::setMetadata()' methods.
 | |
| 
 | |
| 3) If your change alters any user-visible aspect (UI or behavior), update
 | |
|    the user documentation appropriately. The documentation is written
 | |
|    in DocBook 5 markup, and can be found at the following locations in
 | |
|    the source tree:
 | |
| 
 | |
|    Operations Guide - 'docs/opsguide/'
 | |
| 
 | |
|    Manual pages - 'docs/manpages/'
 | |
| 
 | |
|    Internal and public APIs - 'docs/apis/'.
 | |
| 
 | |
| 4) If you wish your work to be mentioned in the 'Credits' list displayed in
 | |
|    rdadmin(1), add or modify the appropriate entry in the 'AUTHORS' file.
 | |
|    Entries should be sorted by surname, then christian name of the author.
 | |
| 
 | |
| 
 | |
| QUESTIONS:
 | |
| Questions about coding style, or indeed any aspect of Rivendell development,
 | |
| are welcomed on the Rivendell-prog mailing list. Subscription information
 | |
| and list archives are available at:
 | |
| 
 | |
|     http://caspian.paravelsystems.com/mailman/listinfo/rivendell-prog
 |