Make RefCnt templated

Saves a virtual destructor when otherwise not needed.

Diffs=
2ad434e80 Make RefCnt templated
diff --git a/.rive_head b/.rive_head
index c0507df..0d39faa 100644
--- a/.rive_head
+++ b/.rive_head
@@ -1 +1 @@
-fffc91e00e4a2ccd88664813a6941620746567e2
+2ad434e801bb43922a15c4313df3bf6c0c9efcf8
diff --git a/include/rive/math/contour_measure.hpp b/include/rive/math/contour_measure.hpp
index 1f51b5e..88d6388 100644
--- a/include/rive/math/contour_measure.hpp
+++ b/include/rive/math/contour_measure.hpp
@@ -12,7 +12,7 @@
 
 namespace rive {
 
-class ContourMeasure : public RefCnt {
+class ContourMeasure : public RefCnt<ContourMeasure> {
 public:
     static constexpr unsigned kMaxDot30 = (1 << 30) - 1;
     static constexpr float kInvScaleD30 = 1.0f / (float)kMaxDot30;
diff --git a/include/rive/refcnt.hpp b/include/rive/refcnt.hpp
index d8babc0..e4b1509 100644
--- a/include/rive/refcnt.hpp
+++ b/include/rive/refcnt.hpp
@@ -15,9 +15,11 @@
 /*
  *  RefCnt : Threadsafe shared pointer baseclass.
  *
- *  The reference count is set to one in the constructor, and goes up on every call to ref(),
- *  and down on every call to unref(). When a call to unref() brings the counter to 0,
- *  delete is called on the object.
+ *  The reference count is set to one in the constructor, and goes up on every call to ref(), and
+ *  down on every call to unref(). When a call to unref() brings the counter to 0, the object is
+ *  casted to class "const T*" and deleted. Usage:
+ *
+ *    class MyClass : public RefCnt<MyClass>
  *
  *  rcp : template wrapper for subclasses of RefCnt, to manage assignment and parameter passing
  *  to safely keep track of shared ownership.
@@ -27,11 +29,11 @@
 
 namespace rive {
 
-class RefCnt {
+template <typename T> class RefCnt {
 public:
     RefCnt() : m_refcnt(1) {}
 
-    virtual ~RefCnt() { assert(this->debugging_refcnt() == 1); }
+    ~RefCnt() { assert(this->debugging_refcnt() == 1); }
 
     void ref() const { (void)m_refcnt.fetch_add(+1, std::memory_order_relaxed); }
 
@@ -41,7 +43,7 @@
             // we restore the "1" in debug builds just to make our destructor happy
             (void)m_refcnt.fetch_add(+1, std::memory_order_relaxed);
 #endif
-            delete this;
+            delete static_cast<const T*>(this);
         }
     }
 
diff --git a/include/rive/render_text.hpp b/include/rive/render_text.hpp
index b721dd8..202582c 100644
--- a/include/rive/render_text.hpp
+++ b/include/rive/render_text.hpp
@@ -17,8 +17,10 @@
 struct RenderTextRun;
 struct RenderGlyphRun;
 
-class RenderFont : public RefCnt {
+class RenderFont : public RefCnt<RenderFont> {
 public:
+    virtual ~RenderFont() {}
+
     struct LineMetrics {
         float ascent, descent;
     };
diff --git a/include/rive/renderer.hpp b/include/rive/renderer.hpp
index 75b3a1b..b4a72eb 100644
--- a/include/rive/renderer.hpp
+++ b/include/rive/renderer.hpp
@@ -27,12 +27,12 @@
 Mat2D computeAlignment(Fit, Alignment, const AABB& frame, const AABB& content);
 
 // A render buffer holds an immutable array of values
-class RenderBuffer : public RefCnt {
+class RenderBuffer : public RefCnt<RenderBuffer> {
     const size_t m_Count;
 
 public:
     RenderBuffer(size_t count);
-    ~RenderBuffer() override;
+    virtual ~RenderBuffer();
 
     size_t count() const { return m_Count; }
 };
@@ -47,10 +47,10 @@
  *  It is common that a shader may be created with a 'localMatrix'. If this is
  *  not null, then it is applied to the shader's domain before the Renderer's CTM.
  */
-class RenderShader : public RefCnt {
+class RenderShader : public RefCnt<RenderShader> {
 public:
     RenderShader();
-    ~RenderShader() override;
+    virtual ~RenderShader();
 };
 
 class RenderPaint {
diff --git a/include/rive/shapes/mesh.hpp b/include/rive/shapes/mesh.hpp
index 473bce7..c7a0872 100644
--- a/include/rive/shapes/mesh.hpp
+++ b/include/rive/shapes/mesh.hpp
@@ -12,7 +12,7 @@
 class Mesh : public MeshBase, public Skinnable {
 
 protected:
-    class IndexBuffer : public std::vector<uint16_t>, public RefCnt {};
+    class IndexBuffer : public std::vector<uint16_t>, public RefCnt<IndexBuffer> {};
     std::vector<MeshVertex*> m_Vertices;
     rcp<IndexBuffer> m_IndexBuffer;
 
@@ -46,4 +46,4 @@
 };
 } // namespace rive
 
-#endif
\ No newline at end of file
+#endif
diff --git a/tess/include/rive/tess/sokol/sokol_tess_renderer.hpp b/tess/include/rive/tess/sokol/sokol_tess_renderer.hpp
index 9ee0a73..eddf07c 100644
--- a/tess/include/rive/tess/sokol/sokol_tess_renderer.hpp
+++ b/tess/include/rive/tess/sokol/sokol_tess_renderer.hpp
@@ -11,7 +11,7 @@
 namespace rive {
 
 // The actual graphics device image.
-class SokolRenderImageResource : public RefCnt {
+class SokolRenderImageResource : public RefCnt<SokolRenderImageResource> {
 private:
     sg_image m_gpuResource;
 
diff --git a/test/refcnt_test.cpp b/test/refcnt_test.cpp
index ee3788b..676617a 100644
--- a/test/refcnt_test.cpp
+++ b/test/refcnt_test.cpp
@@ -8,7 +8,7 @@
 
 using namespace rive;
 
-class MyRefCnt : public RefCnt {
+class MyRefCnt : public RefCnt<MyRefCnt> {
 public:
     MyRefCnt() {}