Initial Grease Pencil 3.0 stage #106848
|
@ -222,6 +222,8 @@ class Layer : public ::GreasePencilLayer {
|
|||
*/
|
||||
|
||||
int drawing_index_at(const int frame) const;
|
||||
|
||||
void tag_frames_map_changed();
|
||||
|
||||
/**
|
||||
* Should be called whenever the keys in the frames map have changed. E.g. when new keys were
|
||||
* added, removed or updated.
|
||||
|
|
|
@ -334,6 +334,7 @@ Layer::Layer()
|
|||
this->frames_storage.size = 0;
|
||||
this->frames_storage.keys = nullptr;
|
||||
this->frames_storage.values = nullptr;
|
||||
this->frames_storage.flag = 0;
|
||||
|
||||
BLI_listbase_clear(&this->masks);
|
||||
|
||||
|
@ -398,21 +399,25 @@ bool Layer::is_locked() const
|
|||
|
||||
bool Layer::insert_frame(int frame_number, const GreasePencilFrame &frame)
|
||||
{
|
||||
this->tag_frames_map_changed();
|
||||
return this->frames_for_write().add(frame_number, frame);
|
||||
}
|
||||
|
||||
bool Layer::insert_frame(int frame_number, GreasePencilFrame &&frame)
|
||||
{
|
||||
this->tag_frames_map_changed();
|
||||
return this->frames_for_write().add(frame_number, frame);
|
||||
}
|
||||
|
||||
bool Layer::overwrite_frame(int frame_number, const GreasePencilFrame &frame)
|
||||
{
|
||||
this->tag_frames_map_changed();
|
||||
Hans Goudey
commented
Since this is making a copy of the frame, the argument might as well be a const reference rather than a non-const one. Since this is making a copy of the frame, the argument might as well be a const reference rather than a non-const one.
|
||||
return this->frames_for_write().add_overwrite(frame_number, frame);
|
||||
}
|
||||
|
||||
bool Layer::overwrite_frame(int frame_number, GreasePencilFrame &&frame)
|
||||
{
|
||||
this->tag_frames_map_changed();
|
||||
return this->frames_for_write().add_overwrite(frame_number, std::move(frame));
|
||||
Hans Goudey
commented
Forget if we talked about this already, but without Forget if we talked about this already, but without `std::move` in the function, there doesn't seem to be much of a point to this second override. Usually there is one for a const reference and one for an rvalue, I haven't seen a non-const reference override like this before.
Falk David
commented
Maybe @JacquesLucke can clarify here, but I believe sine Maybe @JacquesLucke can clarify here, but I believe sine `add_overwrite` has an implementation with an r-value reference that does the `std::move` I think this is fine?
Jacques Lucke
commented
I recommend just using a debugger to see if this calls the function you intend to call (the one with an rvalue reference). Haven't tried right now, but it will probably call the const reference version without I recommend just using a debugger to see if this calls the function you intend to call (the one with an rvalue reference). Haven't tried right now, but it will probably call the const reference version without `std::move`.
|
||||
}
|
||||
|
||||
|
@ -452,8 +457,14 @@ int Layer::drawing_index_at(const int frame) const
|
|||
return this->frames().lookup(*std::prev(it)).drawing_index;
|
||||
}
|
||||
|
||||
void Layer::tag_frames_map_changed()
|
||||
{
|
||||
this->frames_storage.flag |= GP_LAYER_FRAMES_STORAGE_DIRTY;
|
||||
}
|
||||
|
||||
void Layer::tag_frames_map_keys_changed()
|
||||
{
|
||||
this->tag_frames_map_changed();
|
||||
this->runtime->sorted_keys_cache_.tag_dirty();
|
||||
}
|
||||
|
||||
|
@ -1193,10 +1204,24 @@ static void write_layer(BlendWriter *writer, GreasePencilLayer *node)
|
|||
BLO_write_struct(writer, GreasePencilLayer, node);
|
||||
BLO_write_string(writer, node->base.name);
|
||||
|
||||
MEM_SAFE_FREE(node->frames_storage.keys);
|
||||
MEM_SAFE_FREE(node->frames_storage.values);
|
||||
/* Re-create the frames storage only if it was tagged dirty. */
|
||||
if ((node->frames_storage.flag & GP_LAYER_FRAMES_STORAGE_DIRTY) != 0) {
|
||||
MEM_SAFE_FREE(node->frames_storage.keys);
|
||||
MEM_SAFE_FREE(node->frames_storage.values);
|
||||
|
||||
const Layer &layer = node->wrap();
|
||||
node->frames_storage.size = layer.frames().size();
|
||||
node->frames_storage.keys = MEM_cnew_array<int>(node->frames_storage.size, __func__);
|
||||
node->frames_storage.values = MEM_cnew_array<GreasePencilFrame>(node->frames_storage.size,
|
||||
__func__);
|
||||
const Span<int> sorted_keys = layer.sorted_keys();
|
||||
for (const int i : sorted_keys.index_range()) {
|
||||
node->frames_storage.keys[i] = sorted_keys[i];
|
||||
node->frames_storage.values[i] = layer.frames().lookup(sorted_keys[i]);
|
||||
}
|
||||
|
||||
/* Reset the flag. */
|
||||
node->frames_storage.flag &= ~GP_LAYER_FRAMES_STORAGE_DIRTY;
|
||||
}
|
||||
|
||||
BLO_write_int32_array(writer, node->frames_storage.size, node->frames_storage.keys);
|
||||
|
|
|
@ -155,6 +155,10 @@ typedef struct GreasePencilFrame {
|
|||
char _pad[3];
|
||||
} GreasePencilFrame;
|
||||
|
||||
typedef enum GreasePencilLayerFramesMapStorageFlag {
|
||||
GP_LAYER_FRAMES_STORAGE_DIRTY = (1 << 0),
|
||||
} GreasePencilLayerFramesMapStorageFlag;
|
||||
|
||||
/**
|
||||
* Storage for the Map in `blender::bke::greasepencil::Layer`.
|
||||
* See the description there for more detail.
|
||||
|
@ -166,7 +170,8 @@ typedef struct GreasePencilLayerFramesMapStorage {
|
|||
GreasePencilFrame *values;
|
||||
/* Size of the map (number of key-value pairs). */
|
||||
int size;
|
||||
char _pad[4];
|
||||
/* Flag for the status of the storage. */
|
||||
int flag;
|
||||
} GreasePencilLayerFramesMapStorage;
|
||||
|
||||
/**
|
||||
|
|
Returning an element added to a vector by reference is quite dangerous since they're invalidated by further additions, we usually don't do that. Either returning an index or not having these wrapper functions seems like the best choices IMO
From quick look it seems that it should actually be
emplace_layer()
or something like this.And for that it is typically very handy to return reference. And not only that, since C++17 it is expected behavior for vector type containers as well.
I think
emplace_layer
would be a better name indeed.