// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef FLUTTER_DISPLAY_LIST_DISPLAY_LIST_ATTRIBUTES_H_
#define FLUTTER_DISPLAY_LIST_DISPLAY_LIST_ATTRIBUTES_H_

#include "flutter/display_list/types.h"

namespace flutter {

// ===========================================================================

// The base class for a family of DisplayList attribute classes.
//
// This class is designed to support the following properties for any
// attribute to facilitate the storage of the attribute in a DisplayList
// and for use in code that inspects or creates DisplayList objects:
//
// - Typed:
//     Even though most references and pointers are passed around as the
//     attribute's base class, a Type property can be queried using the |type|
//     method to determine which type of the attribute is being used. For
//     example, the Blend type of ColorFilter will return DlColorFilter::kBlend
//     from its type method.
//
// - Inspectable:
//     Any parameters required to full specify the action of the attribute are
//     provided on the type-specific classes.
//
// - Safely Downcast:
//     For the subclasses that have specific data to query, methods are
//     provided to safely downcast the reference for inspection. The down
//     casting method will either return a pointer to the instance with
//     its type-specific class type, or nullptr if it is executed on the
//     wrong type of instance.
//     (eg. DlColorFilter::asBlend() or DlMaskFilter::asBlur())
//
// - Skiafiable:
//     The classes override an |skia_object| method to easily obtain a Skia
//     version of the attribute on demand.
//
// - Immutable:
//     Neither the base class or any of the subclasses specify any mutation
//     methods. Instances are often passed around as const as a reminder,
//     but the classes have no mutation methods anyway.
//
// - Flat and Embeddable:
//     Bulk freed + bulk compared + zero memory fragmentation.
//
//     All of these classes are designed to be stored in the DisplayList
//     buffer allocated in-line with the rest of the data to avoid dangling
//     pointers that require explicit freeing when the DisplayList goes
//     away, or that fragment the memory needed to read the operations in
//     the DisplayList. Furthermore, the data in the classes can be bulk
//     compared using a |memcmp| when performing a |DisplayList::Equals|.
//
// - Passed by Pointer:
//     The data shared via the |Dispatcher::set<Attribute>| calls are stored
//     in the buffer itself and so their lifetime is controlled by the
//     DisplayList. That memory cannot be shared as by a |shared_ptr|
//     because the memory may be freed outside the control of the shared
//     pointer. Creating a shared version of the object would require a
//     new instantiation which we'd like to avoid on every dispatch call,
//     so a raw (const) pointer is shared in those dispatch calls instead,
//     with all of the responsibilities of non-ownership in the called method.
//
//     But, for methods that need to keep a copy of the data...
//
// - Shared_Ptr-able:
//     The classes support a method to return a |std::shared_ptr| version of
//     themselves, safely instantiating a new copy of the object into a
//     shared_ptr using |std::make_shared|. For those dispatcher objects
//     that may want to hold on to the contents of the object (typically
//     in a |current_attribute_| field), they can obtain a shared_ptr
//     copy safely and easily using the |shared| method.

// ===========================================================================

// |D| is the base type for the attribute
//     (i.e. DlColorFilter, etc.)
// |S| is the base type for the Skia version of the attribute
//     (i.e. SkColorFilter, etc.)
// |T| is the enum that describes the specific subclasses
//     (i.e DlColorFilterType, etc.)
template <class D, class S, typename T>
class DlAttribute {
 public:
  // Return the recognized specific type of the attribute.
  virtual T type() const = 0;

  // Return the size of the instantiated data (typically used to allocate)
  // storage in the DisplayList buffer.
  virtual size_t size() const = 0;

  // Return a shared version of |this| attribute. The |shared_ptr| returned
  // will reference a copy of this object so that the lifetime of the shared
  // version is not tied to the storage of this particular instance.
  virtual std::shared_ptr<D> shared() const = 0;

  // Return an equivalent sk_sp<Skia> version of this object.
  virtual sk_sp<S> skia_object() const = 0;

  // Perform a content aware |==| comparison of the Attribute.
  bool operator==(D const& other) const {
    return type() == other.type() && equals_(other);
  }
  // Perform a content aware |!=| comparison of the Attribute.
  bool operator!=(D const& other) const { return !(*this == other); }

  virtual ~DlAttribute() = default;

 protected:
  // Virtual comparison method to support |==| and |!=|.
  virtual bool equals_(D const& other) const = 0;
};

}  // namespace flutter

#endif  // FLUTTER_DISPLAY_LIST_DISPLAY_LIST_ATTRIBUTES_H_
