PCSX2 Documentation/Code Formatting Guidelines: Difference between revisions

no edit summary
No edit summary
 
(10 intermediate revisions by 2 users not shown)
Line 25: Line 25:
Note that using the C++ atomic types <code>float</code> and <code>double</code> are acceptable, and that there are no defined alternatives at this time.
Note that using the C++ atomic types <code>float</code> and <code>double</code> are acceptable, and that there are no defined alternatives at this time.


**Special note:** PCSX2-specific types <code>uptr</code> and <code>sptr</code> are meant to be integer-typed containers for pointer addresses, and should be used in situations where pointer arithmetic is needed. <code>uptr/sptr</code> definitions are not type safe and <code>void*</code> or <code>u8*</code> should be used for parameter passing instead, when possible.
'''Special note:''' PCSX2-specific types <code>uptr</code> and <code>sptr</code> are meant to be integer-typed containers for pointer addresses, and should be used in situations where pointer arithmetic is needed. <code>uptr/sptr</code> definitions are not type safe and <code>void*</code> or <code>u8*</code> should be used for parameter passing instead, when possible.


==Topic 3: Do not use <code>private</code> class members; use <code>protected</code> instead.==
==Topic 3: Do not use <code>private</code> class members; use <code>protected</code> instead.==
Line 31: Line 31:
There is no justifiable reason for any class in PCSX2 to use private variable members. Private members are only useful in the context of _dynamically shared core libraries_, and only hinder the object extensibility of non-shared application code. Use <code>protected</code> for all non-public members instead, as it protects members from unwanted public access while still allowing the object to be extended into a derived class without having to waste a lot of silly effort to dance around private mess.
There is no justifiable reason for any class in PCSX2 to use private variable members. Private members are only useful in the context of _dynamically shared core libraries_, and only hinder the object extensibility of non-shared application code. Use <code>protected</code> for all non-public members instead, as it protects members from unwanted public access while still allowing the object to be extended into a derived class without having to waste a lot of silly effort to dance around private mess.


==Topic 4: Name Protected Class Members with 'm_'==
==Topic 4: Name Protected Class Members with <code>m_</code>==


It is highly recommended to prefix protected class members with <code>m_</code>; such as <code>m_SomeVar</code> or <code>m_somevar</code>. This is a widely accepted convention that many IDEs are adding special built in support and handling for, and for that reason it can help improve class organization considerably for all contributors to the project. However, like most other guidelines it is not a definitive requirement.
It is highly recommended to prefix protected class members with <code>m_</code>; such as <code>m_SomeVar</code> or <code>m_somevar</code>. This is a widely accepted convention that many IDEs are adding special built in support and handling for, and for that reason it can help improve class organization considerably for all contributors to the project. However, like most other guidelines it is not a definitive requirement.
Line 37: Line 37:
==Topic 5: Avoid compounding complex operations onto a single line with a function declaration.==
==Topic 5: Avoid compounding complex operations onto a single line with a function declaration.==


===Example:===
'''Example:'''
  <nowiki>
  <nowiki>
// Not so good...
// Not so good...
void DoSomething() { Function1(); Function2(); var += 1; }</code>
void DoSomething() { Function1(); Function2(); var += 1; }


// Good...
// Good...
Line 60: Line 60:
'''<code>inline_always</code>''' this attribute force inlines a function even in debug builds. It is the functional equivalent of C#'s "skipover" attribute, and should generally be applied only to very simple accessor operations. It acts as both a speedup of debug build performance and as a convenience tool, allowing debuggers to trace through code without having to manually trace into every basic object constructor or property accessor.
'''<code>inline_always</code>''' this attribute force inlines a function even in debug builds. It is the functional equivalent of C#'s "skipover" attribute, and should generally be applied only to very simple accessor operations. It acts as both a speedup of debug build performance and as a convenience tool, allowing debuggers to trace through code without having to manually trace into every basic object constructor or property accessor.


'''<code>inline_devel</code>''' this attribute enables inlining in both devel and release builds, and should be used on almost any function for which the programmer knows that inlining is in the best interest of the code performance. Keep in mind, however, that devel builds are used as debugging and stack tracing tools by programmers and testers, and that means some types of functions are not well suited to being inlined. These namely include very long/complicated functions, which should bear the `inline_release` attribute instead.
'''<code>inline_devel</code>''' this attribute enables inlining in both devel and release builds, and should be used on almost any function for which the programmer knows that inlining is in the best interest of the code performance. Keep in mind, however, that devel builds are used as debugging and stack tracing tools by programmers and testers, and that means some types of functions are not well suited to being inlined. These namely include very long/complicated functions, which should bear the <code>inline_release</code> attribute instead.


'''<code>inline_release</code>''' this attribute enables inlining in public release builds only. This attribute should generally be used on functions that are very long and involved, and only called from one to three locations, thus making them good candidiates for inlining (these are cases the compiler's optimizer should be smart enough to inline itself in release builds, but generally fails to inline).
'''<code>inline_release</code>''' this attribute enables inlining in public release builds only. This attribute should generally be used on functions that are very long and involved, and only called from one to three locations, thus making them good candidiates for inlining (these are cases the compiler's optimizer should be smart enough to inline itself in release builds, but generally fails to inline).
Line 66: Line 66:
'''<code>inline_never</code>''' special attribute which force-disables inlining of a function completely. This attribute is of extremely limited use, usually to combat stupid inlining tricks that some compilers might fall into on special cases of complex function nesting, so you probably won't even need to remember it exists unless you make a habit of writing complex and hard to understand class implementations.
'''<code>inline_never</code>''' special attribute which force-disables inlining of a function completely. This attribute is of extremely limited use, usually to combat stupid inlining tricks that some compilers might fall into on special cases of complex function nesting, so you probably won't even need to remember it exists unless you make a habit of writing complex and hard to understand class implementations.


===Topic Ex.2: Savestate Versioning===
==Topic Ex.2: Savestate Versioning==


While PCSX2 willfully makes no promise to retain backwards support for savestates, it is none the less a convenience for developer, tester, and user alike when we do. So when possible it is recommended that programmers making changes to the savestate code (normally denoted as a Freeze() function) be sure to increment the savestate version in Savestate.h and, if you know how, implement backward support for the old version (if not, then simply increment the savestate version and let someone else fix the backwards compatibility in a later revision). This allows PCSX2 to at the very least fail gracefully when encountering an unknown savestate, and ideally it allows for another coder familiar with the system to properly implement backwards compatibility with the older savestate revision.
While PCSX2 willfully makes no promise to retain backwards support for savestates, it is none the less a convenience for developer, tester, and user alike when we do. So when possible it is recommended that programmers making changes to the savestate code (normally denoted as a Freeze() function) be sure to increment the savestate version in Savestate.h and, if you know how, implement backward support for the old version (if not, then simply increment the savestate version and let someone else fix the backwards compatibility in a later revision). This allows PCSX2 to at the very least fail gracefully when encountering an unknown savestate, and ideally it allows for another coder familiar with the system to properly implement backwards compatibility with the older savestate revision.
{{PCSX2 Documentation Navbox}}