]> git.tdb.fi Git - libs/gl.git/commitdiff
Add correct copy and move semantics to most classes
authorMikko Rasa <tdb@tdb.fi>
Sat, 13 Nov 2021 14:54:53 +0000 (16:54 +0200)
committerMikko Rasa <tdb@tdb.fi>
Sun, 14 Nov 2021 09:47:47 +0000 (11:47 +0200)
43 files changed:
source/backends/opengl/buffer_backend.cpp
source/backends/opengl/buffer_backend.h
source/backends/opengl/framebuffer_backend.cpp
source/backends/opengl/framebuffer_backend.h
source/backends/opengl/pipelinestate_backend.h
source/backends/opengl/program_backend.cpp
source/backends/opengl/program_backend.h
source/backends/opengl/query_backend.cpp
source/backends/opengl/query_backend.h
source/backends/opengl/renderer_backend.h
source/backends/opengl/sampler_backend.cpp
source/backends/opengl/sampler_backend.h
source/backends/opengl/texture_backend.cpp
source/backends/opengl/texture_backend.h
source/backends/opengl/vertexsetup_backend.cpp
source/backends/opengl/vertexsetup_backend.h
source/builders/meshbuilder.cpp
source/core/batch.cpp
source/core/batch.h
source/core/bufferable.cpp
source/core/bufferable.h
source/core/mesh.cpp
source/core/mesh.h
source/core/query.h
source/core/texture2d.h
source/core/uniformblock.h
source/core/vertexarray.h
source/render/instancearray.h
source/render/object.cpp
source/render/object.h
source/render/programdata.cpp
source/render/programdata.h
source/render/renderer.cpp
source/render/renderer.h
source/render/rendertarget.h
source/render/scene.h
source/render/sequence.h
source/render/view.cpp
source/render/view.h
source/resources/resource.cpp
source/resources/resource.h
source/resources/resourcemanager.cpp
source/resources/resourcemanager.h

index a0404e7b143066a479efe1c67f33adb117aa0676..ab78b1b5c3bd0b3b7fa63cb90e14d19ffc9de2f6 100644 (file)
@@ -24,11 +24,18 @@ OpenGLBuffer::OpenGLBuffer()
                glGenBuffers(1, &id);
 }
 
                glGenBuffers(1, &id);
 }
 
+OpenGLBuffer::OpenGLBuffer(OpenGLBuffer &&other):
+       id(other.id)
+{
+       other.id = 0;
+}
+
 OpenGLBuffer::~OpenGLBuffer()
 {
        if(this==scratch_binding)
                unbind_scratch();
 OpenGLBuffer::~OpenGLBuffer()
 {
        if(this==scratch_binding)
                unbind_scratch();
-       glDeleteBuffers(1, &id);
+       if(id)
+               glDeleteBuffers(1, &id);
 }
 
 void OpenGLBuffer::allocate()
 }
 
 void OpenGLBuffer::allocate()
index f435e868f7c929aac6af96d71302a0c8a79b7cfa..1e5106a50095b838488fd3c2a95980b5aba8b302 100644 (file)
@@ -18,6 +18,7 @@ protected:
        static OpenGLBuffer *scratch_binding;
 
        OpenGLBuffer();
        static OpenGLBuffer *scratch_binding;
 
        OpenGLBuffer();
+       OpenGLBuffer(OpenGLBuffer &&);
        ~OpenGLBuffer();
 
        void allocate();
        ~OpenGLBuffer();
 
        void allocate();
index db1905d23394c50a2ffad1ebad7099fc8a9ea65c..de8a9c6eabd2274cceb83b7c087b570b06149d16 100644 (file)
@@ -32,6 +32,13 @@ OpenGLFramebuffer::OpenGLFramebuffer(bool is_system):
        }
 }
 
        }
 }
 
+OpenGLFramebuffer::OpenGLFramebuffer(OpenGLFramebuffer &&other):
+       id(other.id),
+       status(other.status)
+{
+       other.id = 0;
+}
+
 OpenGLFramebuffer::~OpenGLFramebuffer()
 {
        if(id)
 OpenGLFramebuffer::~OpenGLFramebuffer()
 {
        if(id)
index 7a7ebfbe82d3da5a8fa577ab3cb0c67b59d6faf9..24f43441b3aacb333821cb7d7823edf81b318153 100644 (file)
@@ -2,12 +2,13 @@
 #define MSP_GL_FRAMEBUFFER_BACKEND_H_
 
 #include <string>
 #define MSP_GL_FRAMEBUFFER_BACKEND_H_
 
 #include <string>
+#include <msp/core/noncopyable.h>
 #include "frameformat.h"
 
 namespace Msp {
 namespace GL {
 
 #include "frameformat.h"
 
 namespace Msp {
 namespace GL {
 
-class OpenGLFramebuffer
+class OpenGLFramebuffer: public NonCopyable
 {
        friend class OpenGLCommands;
        friend class OpenGLPipelineState;
 {
        friend class OpenGLCommands;
        friend class OpenGLPipelineState;
@@ -17,6 +18,7 @@ protected:
        mutable unsigned status;
 
        OpenGLFramebuffer(bool);
        mutable unsigned status;
 
        OpenGLFramebuffer(bool);
+       OpenGLFramebuffer(OpenGLFramebuffer &&);
        ~OpenGLFramebuffer();
 
        void set_system_format(const FrameFormat &);
        ~OpenGLFramebuffer();
 
        void set_system_format(const FrameFormat &);
index 0b1c4a877d056d16cfde9946de07dc9fdc0fde1b..566b819c086cbadf120ef232dddd662cabd61a26 100644 (file)
@@ -19,6 +19,7 @@ protected:
        static unsigned n_clip_distances;
 
        OpenGLPipelineState();
        static unsigned n_clip_distances;
 
        OpenGLPipelineState();
+       OpenGLPipelineState(OpenGLPipelineState &&) { }
        ~OpenGLPipelineState();
 
        void apply() const;
        ~OpenGLPipelineState();
 
        void apply() const;
index 132ad1c05e823e5fd0da09887a9d54af82044638..685f15421d6d726f34f6b73840a5f7ac96eb3e3f 100644 (file)
@@ -46,6 +46,17 @@ OpenGLProgram::OpenGLProgram()
        id = glCreateProgram();
 }
 
        id = glCreateProgram();
 }
 
+OpenGLProgram::OpenGLProgram(OpenGLProgram &&other):
+       id(other.id),
+       linked(other.linked),
+       uniform_calls(move(other.uniform_calls)),
+       debug_name(move(other.debug_name))
+{
+       move(other.stage_ids, other.stage_ids+MAX_STAGES, stage_ids);
+       other.id = 0;
+       fill(other.stage_ids, other.stage_ids+MAX_STAGES, 0);
+}
+
 OpenGLProgram::~OpenGLProgram()
 {
        for(unsigned i=0; i<MAX_STAGES; ++i)
 OpenGLProgram::~OpenGLProgram()
 {
        for(unsigned i=0; i<MAX_STAGES; ++i)
index b08b70fae968e5992e1e7e026aaa5f7004c78430..2a223ff5ae1b50ffc46fc343c4a45996a04208cc 100644 (file)
@@ -4,12 +4,13 @@
 #include <map>
 #include <string>
 #include <vector>
 #include <map>
 #include <string>
 #include <vector>
+#include <msp/core/noncopyable.h>
 #include "reflectdata.h"
 
 namespace Msp {
 namespace GL {
 
 #include "reflectdata.h"
 
 namespace Msp {
 namespace GL {
 
-class OpenGLProgram
+class OpenGLProgram: public NonCopyable
 {
        friend class OpenGLPipelineState;
 
 {
        friend class OpenGLPipelineState;
 
@@ -46,6 +47,7 @@ protected:
        std::string debug_name;
 
        OpenGLProgram();
        std::string debug_name;
 
        OpenGLProgram();
+       OpenGLProgram(OpenGLProgram &&);
        ~OpenGLProgram();
 
        bool has_stages() const;
        ~OpenGLProgram();
 
        bool has_stages() const;
index 07360ba50da030fcc075a164d36b7ba20ce5d78b..877e888fad76fb4df8c2d4ae15cc3baa5b8f20e0 100644 (file)
@@ -19,6 +19,13 @@ OpenGLQueryPool::OpenGLQueryPool(unsigned t):
        }
 }
 
        }
 }
 
+OpenGLQueryPool::OpenGLQueryPool(OpenGLQueryPool &&other):
+       gl_type(other.gl_type),
+       queries(move(other.queries))
+{
+       other.queries.clear();
+}
+
 OpenGLQueryPool::~OpenGLQueryPool()
 {
        glDeleteQueries(queries.size(), queries.data());
 OpenGLQueryPool::~OpenGLQueryPool()
 {
        glDeleteQueries(queries.size(), queries.data());
index 7bbbeb66a24037acf82894622c6d6882cba31407..ccda73b0b9e57cebf7ab31540aa898b501d2badb 100644 (file)
@@ -1,12 +1,13 @@
 #ifndef MSP_GL_QUERY_BACKEND_H_
 #define MSP_GL_QUERY_BACKEND_H_
 
 #ifndef MSP_GL_QUERY_BACKEND_H_
 #define MSP_GL_QUERY_BACKEND_H_
 
+#include <msp/core/noncopyable.h>
 #include <vector>
 
 namespace Msp {
 namespace GL {
 
 #include <vector>
 
 namespace Msp {
 namespace GL {
 
-class OpenGLQueryPool
+class OpenGLQueryPool: public NonCopyable
 {
        friend class OpenGLCommands;
 
 {
        friend class OpenGLCommands;
 
@@ -15,6 +16,7 @@ protected:
        std::vector<unsigned> queries;
 
        OpenGLQueryPool(unsigned);
        std::vector<unsigned> queries;
 
        OpenGLQueryPool(unsigned);
+       OpenGLQueryPool(OpenGLQueryPool &&);
        ~OpenGLQueryPool();
 
        void resize();
        ~OpenGLQueryPool();
 
        void resize();
index f6f7334b39f6750fd5337584a7ba7ea04af78d4a..4adcce3a3b14579f1e5e24f175878d66ecd190f8 100644 (file)
@@ -1,12 +1,13 @@
 #ifndef MSP_GL_RENDERER_BACKEND_H_
 #define MSP_GL_RENDERER_BACKEND_H_
 
 #ifndef MSP_GL_RENDERER_BACKEND_H_
 #define MSP_GL_RENDERER_BACKEND_H_
 
+#include <msp/core/noncopyable.h>
 #include "pipelinestate.h"
 
 namespace Msp {
 namespace GL {
 
 #include "pipelinestate.h"
 
 namespace Msp {
 namespace GL {
 
-class OpenGLRenderer
+class OpenGLRenderer: public NonCopyable
 {
 protected:
        PipelineState pipeline_state;
 {
 protected:
        PipelineState pipeline_state;
index be3f67cbc37ae688bbf5cd776ae8642c1e11a40c..8198e40feba4c20f5966c4e3a1d194611596587f 100644 (file)
@@ -25,6 +25,12 @@ OpenGLSampler::OpenGLSampler()
                glGenSamplers(1, &id);
 }
 
                glGenSamplers(1, &id);
 }
 
+OpenGLSampler::OpenGLSampler(OpenGLSampler &&other):
+       id(other.id)
+{
+       other.id = 0;
+}
+
 OpenGLSampler::~OpenGLSampler()
 {
        if(id)
 OpenGLSampler::~OpenGLSampler()
 {
        if(id)
index 2f644431c39983894d00207cd8b10e2ca4ede1e4..f90fbb22e298fd4b86f37b5b2e5bf6b97b57321b 100644 (file)
@@ -1,10 +1,12 @@
 #ifndef MSP_GL_SAMPLER_BACKEND_H_
 #define MSP_GL_SAMPLER_BACKEND_H_
 
 #ifndef MSP_GL_SAMPLER_BACKEND_H_
 #define MSP_GL_SAMPLER_BACKEND_H_
 
+#include <msp/core/noncopyable.h>
+
 namespace Msp {
 namespace GL {
 
 namespace Msp {
 namespace GL {
 
-class OpenGLSampler
+class OpenGLSampler: public NonCopyable
 {
        friend class OpenGLPipelineState;
 
 {
        friend class OpenGLPipelineState;
 
@@ -12,6 +14,7 @@ protected:
        unsigned id = 0;
 
        OpenGLSampler();
        unsigned id = 0;
 
        OpenGLSampler();
+       OpenGLSampler(OpenGLSampler &&);
        ~OpenGLSampler();
 
        static bool check_anisotropic(bool);
        ~OpenGLSampler();
 
        static bool check_anisotropic(bool);
index ba6486778ac04b67504360e136f4774353b50ff3..ebfeb0255b2083d8a04b8b49ff0503302e361333 100644 (file)
@@ -25,6 +25,14 @@ OpenGLTexture::OpenGLTexture(unsigned t):
        }
 }
 
        }
 }
 
+OpenGLTexture::OpenGLTexture(OpenGLTexture &&other):
+       id(other.id),
+       target(other.target),
+       debug_name(move(other.debug_name))
+{
+       other.id = 0;
+}
+
 OpenGLTexture::~OpenGLTexture()
 {
        if(this==scratch_binding)
 OpenGLTexture::~OpenGLTexture()
 {
        if(this==scratch_binding)
index 69756206ac9aa3f4966e9d13f27bede59d02ea56..ecb3056fd2ead2cd0f7bcf86fd568a7aa61b502a 100644 (file)
@@ -19,6 +19,7 @@ protected:
        static OpenGLTexture *scratch_binding;
 
        OpenGLTexture(unsigned);
        static OpenGLTexture *scratch_binding;
 
        OpenGLTexture(unsigned);
+       OpenGLTexture(OpenGLTexture &&);
        ~OpenGLTexture();
 
        void create();
        ~OpenGLTexture();
 
        void create();
index 90189db7227eba94575f99a27fc98ab39e234843..acd14f48b70c42fd539f85c277c09e06ac3a94e7 100644 (file)
@@ -27,9 +27,16 @@ OpenGLVertexSetup::OpenGLVertexSetup()
                glGenVertexArrays(1, &id);
 }
 
                glGenVertexArrays(1, &id);
 }
 
+OpenGLVertexSetup::OpenGLVertexSetup(OpenGLVertexSetup &&other):
+       id(other.id)
+{
+       other.id = 0;
+}
+
 OpenGLVertexSetup::~OpenGLVertexSetup()
 {
 OpenGLVertexSetup::~OpenGLVertexSetup()
 {
-       glDeleteVertexArrays(1, &id);
+       if(id)
+               glDeleteVertexArrays(1, &id);
 }
 
 void OpenGLVertexSetup::require_format(const VertexFormat &fmt, bool instanced)
 }
 
 void OpenGLVertexSetup::require_format(const VertexFormat &fmt, bool instanced)
index 954dcc7f8fe3c5ca029303194f44266ec5ffb641..e0dae1bc970e4c871ad5e1b7f2f65668cfa02965 100644 (file)
@@ -1,13 +1,15 @@
 #ifndef MSP_GL_VERTEXSETUP_BACKEND_H_
 #define MSP_GL_VERTEXSETUP_BACKEND_H_
 
 #ifndef MSP_GL_VERTEXSETUP_BACKEND_H_
 #define MSP_GL_VERTEXSETUP_BACKEND_H_
 
+#include <msp/core/noncopyable.h>
+
 namespace Msp {
 namespace GL {
 
 class VertexArray;
 class VertexFormat;
 
 namespace Msp {
 namespace GL {
 
 class VertexArray;
 class VertexFormat;
 
-class OpenGLVertexSetup
+class OpenGLVertexSetup: public NonCopyable
 {
        friend class OpenGLPipelineState;
 
 {
        friend class OpenGLPipelineState;
 
@@ -15,6 +17,7 @@ protected:
        unsigned id;
 
        OpenGLVertexSetup();
        unsigned id;
 
        OpenGLVertexSetup();
+       OpenGLVertexSetup(OpenGLVertexSetup &&);
        ~OpenGLVertexSetup();
 
        static void require_format(const VertexFormat &, bool);
        ~OpenGLVertexSetup();
 
        static void require_format(const VertexFormat &, bool);
index 92e2ee06ce5bfb3f1922eb8ad9e4cb41f8982bbb..79770725c62ceb910947fef247634733ba7be018 100644 (file)
@@ -1,6 +1,8 @@
 #include "mesh.h"
 #include "meshbuilder.h"
 
 #include "mesh.h"
 #include "meshbuilder.h"
 
+using namespace std;
+
 namespace Msp {
 namespace GL {
 
 namespace Msp {
 namespace GL {
 
@@ -27,7 +29,7 @@ void MeshBuilder::begin_()
 
 void MeshBuilder::end_()
 {
 
 void MeshBuilder::end_()
 {
-       mesh.add_batch(*batch);
+       mesh.add_batch(move(*batch));
        delete batch;
        batch = 0;
 }
        delete batch;
        batch = 0;
 }
index 9639a3207e4b71bc265520fd9a5f096357d8361c..382cfbdb5df1ab6526df9e6c6c96e0004d620612 100644 (file)
@@ -53,10 +53,6 @@ Batch::Batch(PrimitiveType t):
        set_index_type(UNSIGNED_SHORT);
 }
 
        set_index_type(UNSIGNED_SHORT);
 }
 
-Batch::~Batch()
-{
-}
-
 void Batch::set_index_type(DataType t)
 {
        if(t==index_type)
 void Batch::set_index_type(DataType t)
 {
        if(t==index_type)
index 45101d4356672950dc9439a5401ed1a3311bc307..dd07adb58b632941d0264350b783b386efd97fdc 100644 (file)
@@ -40,7 +40,6 @@ private:
 
 public:
        Batch(PrimitiveType);
 
 public:
        Batch(PrimitiveType);
-       ~Batch();
 
        PrimitiveType get_type() const { return prim_type; }
 
 
        PrimitiveType get_type() const { return prim_type; }
 
index c312a4339a876f8436877842f44e689aa3f32b7a..374c4eeb3b83ee5d1617b9249383696a9f7aa15f 100644 (file)
@@ -8,6 +8,23 @@ using namespace std;
 namespace Msp {
 namespace GL {
 
 namespace Msp {
 namespace GL {
 
+Bufferable::Bufferable(Bufferable &&other):
+       buffer(other.buffer),
+       offset(other.offset),
+       next_in_buffer(other.next_in_buffer),
+       prev_in_buffer(other.prev_in_buffer),
+       location_dirty(other.location_dirty),
+       dirty(other.dirty)
+{
+       other.buffer = 0;
+       other.next_in_buffer = 0;
+       other.prev_in_buffer = 0;
+       if(next_in_buffer)
+               next_in_buffer->prev_in_buffer = this;
+       if(prev_in_buffer)
+               prev_in_buffer->next_in_buffer = this;
+}
+
 Bufferable::~Bufferable()
 {
        unlink_from_buffer();
 Bufferable::~Bufferable()
 {
        unlink_from_buffer();
index 4a4114d0ce683483717eee9baf0770e3b7ab7c4b..8bd3f77f021d39e2722f0b8d7e13e5f60ae2a353 100644 (file)
@@ -1,6 +1,8 @@
 #ifndef MSP_GL_BUFFERABLE_H_
 #define MSP_GL_BUFFERABLE_H_
 
 #ifndef MSP_GL_BUFFERABLE_H_
 #define MSP_GL_BUFFERABLE_H_
 
+#include <msp/core/noncopyable.h>
+
 namespace Msp {
 namespace GL {
 
 namespace Msp {
 namespace GL {
 
@@ -14,7 +16,7 @@ A dirty flag is provided for derived classes.  It should be set when the data
 in the buffer is considered out of date, and is cleared by Bufferable after
 uploading fresh data to the buffer.
 */
 in the buffer is considered out of date, and is cleared by Bufferable after
 uploading fresh data to the buffer.
 */
-class Bufferable
+class Bufferable: public NonCopyable
 {
 public:
        /**
 {
 public:
        /**
@@ -45,6 +47,7 @@ protected:
        mutable bool dirty = false;
 
        Bufferable() = default;
        mutable bool dirty = false;
 
        Bufferable() = default;
+       Bufferable(Bufferable &&);
 public:
        virtual ~Bufferable();
 
 public:
        virtual ~Bufferable();
 
index b5628eb10c860bbc758b17e08b7db045bea7b65c..208126ef26c477ed5adf8ca61f357400ca44ee73 100644 (file)
@@ -14,6 +14,22 @@ Mesh::Mesh(const VertexFormat &f)
        storage(f);
 }
 
        storage(f);
 }
 
+Mesh::Mesh(Mesh &&other):
+       Resource(move(other)),
+       vertices(move(other.vertices)),
+       batches(move(other.batches)),
+       vbuf(other.vbuf),
+       ibuf(other.ibuf),
+       vtx_setup(move(other.vtx_setup)),
+       dirty(other.dirty),
+       disallow_rendering(other.disallow_rendering),
+       face_winding(other.face_winding),
+       debug_name(move(other.debug_name))
+{
+       other.vbuf = 0;
+       other.ibuf = 0;
+}
+
 Mesh::~Mesh()
 {
        set_manager(0);
 Mesh::~Mesh()
 {
        set_manager(0);
@@ -94,11 +110,11 @@ char *Mesh::modify_vertex(size_t i)
        return vertices.modify(i);
 }
 
        return vertices.modify(i);
 }
 
-void Mesh::add_batch(const Batch &b)
+void Mesh::add_batch(Batch &&b)
 {
        if(batches.empty())
        {
 {
        if(batches.empty())
        {
-               batches.push_back(b);
+               batches.emplace_back(move(b));
                if(ibuf)
                        batches.back().use_buffer(ibuf);
        }
                if(ibuf)
                        batches.back().use_buffer(ibuf);
        }
@@ -114,7 +130,7 @@ void Mesh::add_batch(const Batch &b)
                }
 
                Batch *prev = &batches.back();
                }
 
                Batch *prev = &batches.back();
-               batches.push_back(b);
+               batches.emplace_back(move(b));
                if(reallocate)
                {
                        prev = 0;
                if(reallocate)
                {
                        prev = 0;
@@ -281,7 +297,7 @@ void Mesh::Loader::batch(PrimitiveType p)
 {
        Batch btc(p);
        load_sub(btc);
 {
        Batch btc(p);
        load_sub(btc);
-       obj.add_batch(btc);
+       obj.add_batch(move(btc));
 }
 
 
 }
 
 
index f8e1b6c1fa20f2148e582976b817109ca8e4f86c..ba2aebc76c1fd35254f66429f5035e4370d587b5 100644 (file)
@@ -83,6 +83,7 @@ private:
 public:
        Mesh() = default;
        Mesh(const VertexFormat &);
 public:
        Mesh() = default;
        Mesh(const VertexFormat &);
+       Mesh(Mesh &&);
        ~Mesh();
 
        /** Sets the vertex format for the mesh.  It cannot be changed once set. */
        ~Mesh();
 
        /** Sets the vertex format for the mesh.  It cannot be changed once set. */
@@ -105,7 +106,7 @@ public:
 
        /** Adds a batch to the mesh.  It may be combined with the last existing
        batch if the primitive types are compatible. */
 
        /** Adds a batch to the mesh.  It may be combined with the last existing
        batch if the primitive types are compatible. */
-       void add_batch(const Batch &b);
+       void add_batch(Batch &&b);
 
        const std::vector<Batch> &get_batches() const { return batches; }
 
 
        const std::vector<Batch> &get_batches() const { return batches; }
 
index d5b83b960569911b5dd342351ec48567a0d98a1f..8f9b17e8e398176032a0691d9566a5f94d802e51 100644 (file)
@@ -1,7 +1,6 @@
 #ifndef MSP_GL_QUERY_H_
 #define MSP_GL_QUERY_H_
 
 #ifndef MSP_GL_QUERY_H_
 #define MSP_GL_QUERY_H_
 
-#include <msp/core/noncopyable.h>
 #include "query_backend.h"
 
 namespace Msp {
 #include "query_backend.h"
 
 namespace Msp {
@@ -20,7 +19,7 @@ enum QueryType
 A collection of query objects, which can be used to gather feedback from the
 GPU.  Semantics of the queries depend on the query type.
 */
 A collection of query objects, which can be used to gather feedback from the
 GPU.  Semantics of the queries depend on the query type.
 */
-class QueryPool: public QueryPoolBackend, public Msp::NonCopyable
+class QueryPool: public QueryPoolBackend
 {
        friend QueryPoolBackend;
 
 {
        friend QueryPoolBackend;
 
index 3a9edae11721c6b626927fed4c5a62e0ab4a72cc..fbcee696686d0dbb93e067341badb2af2b809849 100644 (file)
@@ -34,6 +34,8 @@ private:
        unsigned levels = 0;
 
 public:
        unsigned levels = 0;
 
 public:
+       Texture2D() = default;
+       Texture2D(Texture2D &&) = default;
        virtual ~Texture2D();
 
        /** Sets storage format and dimensions and allocates memory for the texture.
        virtual ~Texture2D();
 
        /** Sets storage format and dimensions and allocates memory for the texture.
index 810afd7758525455afdaaf8c90e16b78ea318cd8..1144158d2ee3ae760bb994be535b8657c9650faa 100644 (file)
@@ -21,7 +21,7 @@ Applications normally don't need to deal with UniformBlocks directly.  They're
 managed by the ProgramData class, which provides a higher-level interface for
 setting uniform values.
 */
 managed by the ProgramData class, which provides a higher-level interface for
 setting uniform values.
 */
-class UniformBlock: public UniformBlockBackend, public NonCopyable, public Bufferable
+class UniformBlock: public UniformBlockBackend, public Bufferable
 {
 private:
        std::vector<char> data;
 {
 private:
        std::vector<char> data;
index 8e56ee226b599254f0876942322ee2a4dc1d6ee5..575a716e86f42a125a81b976d8965085b61a936f 100644 (file)
@@ -37,8 +37,6 @@ private:
        std::vector<char> data;
        unsigned stride = 0;
 
        std::vector<char> data;
        unsigned stride = 0;
 
-       VertexArray(const VertexArray &);
-       VertexArray &operator=(const VertexArray &);
 public:
        VertexArray() = default;
 
 public:
        VertexArray() = default;
 
index d793ce2ed229cd8159ac9fc2504c9c1d0472a854..e6f8690c68cd5b2000d25f9bb7d770f063fcc1f4 100644 (file)
@@ -2,6 +2,7 @@
 #define MSP_GL_INSTANCEARRAY_H_
 
 #include <vector>
 #define MSP_GL_INSTANCEARRAY_H_
 
 #include <vector>
+#include <msp/core/noncopyable.h>
 #include "programdata.h"
 #include "renderable.h"
 #include "vertexarray.h"
 #include "programdata.h"
 #include "renderable.h"
 #include "vertexarray.h"
@@ -24,7 +25,7 @@ elements of the array corresponds to a row of the transform matrix.
 If the Mesh or Technique of the Object is changed during the lifetime of the
 InstanceArray, behaviour is undefined.
 */
 If the Mesh or Technique of the Object is changed during the lifetime of the
 InstanceArray, behaviour is undefined.
 */
-class InstanceArray: public Renderable
+class InstanceArray: public Renderable, public NonCopyable
 {
 public:
        template<typename T>
 {
 public:
        template<typename T>
index 9a9f759ccf4b53a2c255617b01ade7e12cbc0b42..e2e95a9b024d25b610d256ef8c6678d7bb53ff89 100644 (file)
@@ -27,7 +27,21 @@ Object::Object(const Mesh *m, const Technique *t):
        set_technique(t);
 }
 
        set_technique(t);
 }
 
-// TODO should have copy-c'tor to set watch on lod0 mesh if necessary
+Object::Object(const Object &other):
+       lods(other.lods),
+       bounding_sphere(other.bounding_sphere)
+{
+       if(other.lod0_watched)
+               watch_lod0();
+}
+
+Object::Object(Object &&other):
+       lods(move(other.lods)),
+       bounding_sphere(move(other.bounding_sphere))
+{
+       if(other.lod0_watched)
+               watch_lod0();
+}
 
 Object::~Object()
 {
 
 Object::~Object()
 {
@@ -59,15 +73,20 @@ void Object::set_mesh(unsigned i, const Mesh *m)
        lod0_watched = false;
 
        if(i==0 && m)
        lod0_watched = false;
 
        if(i==0 && m)
-               if(ResourceManager *rm = m->get_manager())
-               {
-                       rm->observe_resource(*m, *this);
-                       lod0_watched = true;
-               }
+               watch_lod0();
 
        update_bounding_sphere();
 }
 
 
        update_bounding_sphere();
 }
 
+void Object::watch_lod0()
+{
+       if(ResourceManager *rm = lods[0].mesh->get_manager())
+       {
+               rm->observe_resource(*lods[0].mesh, *this);
+               lod0_watched = true;
+       }
+}
+
 void Object::update_bounding_sphere()
 {
        vector<Vector3> points;
 void Object::update_bounding_sphere()
 {
        vector<Vector3> points;
index 7d9f1619d58e5846759a68cc753f9951ad3808b6..dc92326730c4f25a8abf8ec7d479a0d7966ca7f4 100644 (file)
@@ -77,10 +77,13 @@ private:
 public:
        Object();
        Object(const Mesh *, const Technique *);
 public:
        Object();
        Object(const Mesh *, const Technique *);
+       Object(const Object &);
+       Object(Object &&);
        ~Object();
 
 private:
        LevelOfDetail &get_lod(unsigned, const char *);
        ~Object();
 
 private:
        LevelOfDetail &get_lod(unsigned, const char *);
+       void watch_lod0();
 
 public:
        /** Sets the mesh for the highest level of detail (index 0). */
 
 public:
        /** Sets the mesh for the highest level of detail (index 0). */
index 40eba5e5d6840a4580c1d311c67da732231253ab..cfd2c0f5257b0d45d341ff15119805ea96038474 100644 (file)
@@ -60,6 +60,22 @@ ProgramData &ProgramData::operator=(const ProgramData &other)
        return *this;
 }
 
        return *this;
 }
 
+ProgramData::ProgramData(ProgramData &&other):
+       tied_program(other.tied_program),
+       uniforms(move(other.uniforms)),
+       uniform_data(move(other.uniform_data)),
+       generation(other.generation),
+       blocks(move(other.blocks)),
+       programs(move(other.programs)),
+       last_buffer_block(other.last_buffer_block),
+       buffer(other.buffer),
+       dirty(other.dirty),
+       debug_name(move(other.debug_name))
+{
+       other.blocks.clear();
+       other.buffer = 0;
+}
+
 ProgramData::~ProgramData()
 {
        for(SharedBlock &b: blocks)
 ProgramData::~ProgramData()
 {
        for(SharedBlock &b: blocks)
index 9b8a25cb15be498a916bf0ffcf28c868ea56bb02..53f48a6be5cefe14f5a316a78177daff6de54d4b 100644 (file)
@@ -165,6 +165,7 @@ public:
        ProgramData(const ProgramData &);
        ProgramData(const ProgramData &, const Program *);
        ProgramData &operator=(const ProgramData &);
        ProgramData(const ProgramData &);
        ProgramData(const ProgramData &, const Program *);
        ProgramData &operator=(const ProgramData &);
+       ProgramData(ProgramData &&);
        ~ProgramData();
 
 private:
        ~ProgramData();
 
 private:
index 6c8f1b67b29c0deb30161db2acfb19f6cffb2b79..58a56ff2f2d105e5213e9b6a6cd837ea68f06e0e 100644 (file)
@@ -27,10 +27,6 @@ Renderer::Renderer()
        texture_stack.reserve(32);
 }
 
        texture_stack.reserve(32);
 }
 
-Renderer::~Renderer()
-{
-}
-
 void Renderer::begin()
 {
        if(current_state)
 void Renderer::begin()
 {
        if(current_state)
index a0b4e75fdf2ece24b7e082787258b63238080762..b9e795dee19e4fd1f2b23713e2c40fda30021c67 100644 (file)
@@ -110,7 +110,6 @@ private:
 
 public:
        Renderer();
 
 public:
        Renderer();
-       ~Renderer();
 
        /** Begins rendering, allowing commands to be issued. */
        void begin();
 
        /** Begins rendering, allowing commands to be issued. */
        void begin();
index 98189e78d17731215b096be9513846e1caa9a733..b7d4af03840f4e81196fad3222255b74be345732 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef RENDERTARGET_H_
 #define RENDERTARGET_H_
 
 #ifndef RENDERTARGET_H_
 #define RENDERTARGET_H_
 
+#include <msp/core/noncopyable.h>
 #include "framebuffer.h"
 
 namespace Msp {
 #include "framebuffer.h"
 
 namespace Msp {
@@ -15,7 +16,7 @@ Wraps a Framebuffer and its attachments for easier management.
 All attachments will be created as 2D or 2D multisample textures, depending on
 the sample count of the format.
 */
 All attachments will be created as 2D or 2D multisample textures, depending on
 the sample count of the format.
 */
-class RenderTarget
+class RenderTarget: public NonCopyable
 {
 private:
        unsigned width;
 {
 private:
        unsigned width;
@@ -25,10 +26,7 @@ private:
 
 public:
        RenderTarget(unsigned, unsigned, const FrameFormat & = (COLOR_ATTACHMENT, DEPTH_ATTACHMENT));
 
 public:
        RenderTarget(unsigned, unsigned, const FrameFormat & = (COLOR_ATTACHMENT, DEPTH_ATTACHMENT));
-private:
-       RenderTarget(const RenderTarget &);
-       RenderTarget &operator=(const RenderTarget &);
-public:
+       RenderTarget(RenderTarget &&) = default;
        ~RenderTarget();
 
        unsigned get_width() const { return width; }
        ~RenderTarget();
 
        unsigned get_width() const { return width; }
index 692dcd0dfc6c7ebf88e0e8c7f0b26d7c0aae4b33..d07a81da80b82fef2998eed732c4d3aca8bef8b3 100644 (file)
@@ -63,9 +63,6 @@ protected:
        mutable Vector4 frustum_edges[6];
 
        Scene() = default;
        mutable Vector4 frustum_edges[6];
 
        Scene() = default;
-private:
-       Scene(const Scene &);
-       Scene &operator=(const Scene &);
 public:
        virtual ~Scene() = default;
 
 public:
        virtual ~Scene() = default;
 
index b6a8cb34a158271468e3b9195b10709a93728b93..6ee74986d5ac412d8dc7642981f1d0004354c8d3 100644 (file)
@@ -34,7 +34,7 @@ format.
 A Sequence itself is normally rendered with an empty tag.  A special "noclear"
 tag can be used to suppress clearing.
 */
 A Sequence itself is normally rendered with an empty tag.  A special "noclear"
 tag can be used to suppress clearing.
 */
-class Sequence: public Renderable
+class Sequence: public Renderable, public NonCopyable
 {
 public:
        class Step
 {
 public:
        class Step
index 411c277485453c18a6b7fd5342ca63274b13cb7c..cac82d5d309815bb044b9fbc64b2f07b64b0ab5b 100644 (file)
@@ -11,6 +11,14 @@ View::~View()
        delete internal_renderer;
 }
 
        delete internal_renderer;
 }
 
+View::View(View &&other):
+       camera(other.camera),
+       content(other.content),
+       internal_renderer(other.internal_renderer)
+{
+       other.internal_renderer = 0;
+}
+
 void View::set_camera(Camera *c)
 {
        camera = c;
 void View::set_camera(Camera *c)
 {
        camera = c;
index bdddb65d31b977cf896cdd3dacc1d89c470cfbd8..b8a116a65e3b80435a4aa4cdae39020dffad6252 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef MSP_GL_VIEW_H_
 #define MSP_GL_VIEW_H_
 
 #ifndef MSP_GL_VIEW_H_
 #define MSP_GL_VIEW_H_
 
+#include <msp/core/noncopyable.h>
 #include "framebuffer.h"
 
 namespace Msp {
 #include "framebuffer.h"
 
 namespace Msp {
@@ -17,7 +18,7 @@ application in some way.
 The content renderable's render() function is called with an empty tag.  A
 Sequence can be used to specify other tags and add post-processing.
 */
 The content renderable's render() function is called with an empty tag.  A
 Sequence can be used to specify other tags and add post-processing.
 */
-class View
+class View: public NonCopyable
 {
 protected:
        Camera *camera = 0;
 {
 protected:
        Camera *camera = 0;
@@ -26,6 +27,7 @@ protected:
 
        View() = default;
 public:
 
        View() = default;
 public:
+       View(View &&);
        virtual ~View();
 
        virtual unsigned get_width() const { return get_target().get_width(); }
        virtual ~View();
 
        virtual unsigned get_width() const { return get_target().get_width(); }
index 644c55bb0ca198c167655249406e5f540e3b26b4..60d611f8ace7a20386a9232497e2f2f0dfb42e1a 100644 (file)
@@ -10,6 +10,19 @@ Resource::~Resource()
                manager->remove_resource(*this);
 }
 
                manager->remove_resource(*this);
 }
 
+Resource::Resource(Resource &&other):
+       manager(other.manager),
+       manager_data(other.manager_data)
+{
+       if(manager)
+       {
+               manager->move_resource(other, *this);
+               manager_data = manager->get_data_for_resource(*this);
+       }
+       other.manager = 0;
+       other.manager_data = 0;
+}
+
 void Resource::set_manager(ResourceManager *m)
 {
        if(manager)
 void Resource::set_manager(ResourceManager *m)
 {
        if(manager)
index d763ac442bb528ea9e0af84e9acd056bb7673832..2a312e960acd8b1595dc5a93fe03a5b8ed54cff7 100644 (file)
@@ -2,6 +2,7 @@
 #define MSP_GL_RESOURCE_H_
 
 #include <cstdint>
 #define MSP_GL_RESOURCE_H_
 
 #include <cstdint>
+#include <msp/core/noncopyable.h>
 #include <msp/io/seekable.h>
 
 namespace Msp {
 #include <msp/io/seekable.h>
 
 namespace Msp {
@@ -10,7 +11,7 @@ namespace GL {
 class ResourceManager;
 class Resources;
 
 class ResourceManager;
 class Resources;
 
-class Resource
+class Resource: public NonCopyable
 {
 public:
        class AsyncLoader
 {
 public:
        class AsyncLoader
@@ -29,6 +30,7 @@ protected:
        void *manager_data = 0;
 
        Resource() = default;
        void *manager_data = 0;
 
        Resource() = default;
+       Resource(Resource &&);
 public:
        virtual ~Resource();
 
 public:
        virtual ~Resource();
 
index 02a93d949997c3aae421b3f4322e3bfb0881a855..c72b361ce1f41ae9ec69d73d69a7d0e7307fcb21 100644 (file)
@@ -63,6 +63,16 @@ void ResourceManager::add_resource(Resource &r)
        insert_unique(resources, &r, ManagedResource(r));
 }
 
        insert_unique(resources, &r, ManagedResource(r));
 }
 
+void ResourceManager::move_resource(Resource &from, Resource &to)
+{
+       if(to.get_manager()!=this || from.get_manager_data()!=to.get_manager_data())
+               throw invalid_operation("ResourceManager::move_resource");
+       ManagedResource *managed = reinterpret_cast<ManagedResource *>(to.get_manager_data());
+       MutexLock lock(map_mutex);
+       insert_unique(resources, &to, *managed);
+       resources.erase(&from);
+}
+
 const ResourceManager::ManagedResource &ResourceManager::get_managed_resource(const Resource &r) const
 {
        MutexLock lock(map_mutex);
 const ResourceManager::ManagedResource &ResourceManager::get_managed_resource(const Resource &r) const
 {
        MutexLock lock(map_mutex);
index bd87de8929ad92fc38b2703313168d2df1d75628..ec1bb3f01c00fba560693b04820727b063101170 100644 (file)
@@ -4,6 +4,7 @@
 #include <deque>
 #include <cstdint>
 #include <msp/core/mutex.h>
 #include <deque>
 #include <cstdint>
 #include <msp/core/mutex.h>
+#include <msp/core/noncopyable.h>
 #include <msp/core/semaphore.h>
 #include <msp/core/thread.h>
 #include <msp/datafile/collection.h>
 #include <msp/core/semaphore.h>
 #include <msp/core/thread.h>
 #include <msp/datafile/collection.h>
@@ -23,7 +24,7 @@ public:
 };
 
 
 };
 
 
-class ResourceManager
+class ResourceManager: public NonCopyable
 {
 public:
        enum LoadingPolicy
 {
 public:
        enum LoadingPolicy
@@ -135,6 +136,7 @@ public:
        void set_max_retain_frames(unsigned);
 
        void add_resource(Resource &);
        void set_max_retain_frames(unsigned);
 
        void add_resource(Resource &);
+       void move_resource(Resource &, Resource &);
 private:
        const ManagedResource &get_managed_resource(const Resource &) const;
        ManagedResource &get_managed_resource(const Resource &);
 private:
        const ManagedResource &get_managed_resource(const Resource &) const;
        ManagedResource &get_managed_resource(const Resource &);