You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

67 lines
2.9 KiB

namespace Magnum {
/** @page method-chaining Method chaining
@brief Little feature helping to reduce typing and encourage best practices.
Method chaining ([Wikipedia](http://en.wikipedia.org/wiki/Method_chaining)) is a
feature which allows you to chain method calls one after another without
repeatedly specifying variable the method is called on. Its primary goal is to
reduce unnecessary repeated names, improving code readability.
%Magnum uses this feature for configuring OpenGL objects (such as various mesh
and framebuffer options, shader uniforms etc.). Because OpenGL was designed with
"bind-to-modify" approach, most configuration calls need to bind the object
first and only after that change the parameters (unless @extension{EXT,direct_state_access}
extension is available to avoid this). To reduce unneeded bind calls, %Magnum
binds the object only if it is not already bound somewhere. Method chaining
encourages you to configure whole object in one run, effectively reducing the
number of needed bindings. Consider the following example:
@code
Texture2D *carDiffuseTexture, *carSpecularTexture, *carBumpTexture;
carDiffuseTexture->setStorage(5, Texture2D::InternalFormat::SRGB8);
carSpecularTexture->setStorage(3, Texture2D::InternalFormat::R8);
carBumpTexture->setStorage(5, Texture2D::InternalFormat::RGB8);
carDiffuseTexture->setSubImage(0, {}, diffuse);
carSpecularTexture->setSubImage(0, {}, specular;
carBumpTexture->setSubImage(0, {}, bump);
carDiffuseTexture->generateMipmap();
carSpecularTexture->generateMipmap();
carBumpTexture->generateMipmap();
@endcode
This code is written that similar configuration steps are grouped together,
which might be good when somebody needs to change something for all three
textures at once, but on the other hand the code is cluttered with repeated
names and after each configuration step the texture must be rebound to another.
With method chaining used the code looks much lighter and each object is
configured in one run, reducing count of bind calls from 9 to 3.
@code
carDiffuseTexture->setStorage(5, Texture2D::InternalFormat::SRGB8)
->setSubImage(0, {}, diffuse)
->generateMipmap();
carSpecularTexture->setStorage(3, Texture2D::InternalFormat::R8)
->setSubImage(0, {}, diffuse)
->generateMipmap();
carBumpTexture->setStorage(5, Texture2D::InternalFormat::RGB8)
->setSubImage(0, {}, bump)
->generateMipmap();
@endcode
Method chaining is not used on non-configuring functions, such as Framebuffer::clear()
or Mesh::draw(), as these won't be commonly used in conjunction with other
functions anyway.
Method chaining is also used in SceneGraph and other libraries and in some cases
it allows you to just "configure and forget" without even saving the created
object to some variable, for example when adding static object to an scene:
@code
Scene3D scene;
(new MyObject(&scene))
->rotateX(90.0_degf)
->translate({-1.5f, 0.5f, 7.0f});
@endcode
*/
}