slight refactor of utility types, improve mom-child relationship

This commit is contained in:
jrkb 2023-04-16 17:20:54 +02:00
parent 99f2055553
commit 65ca48275c
11 changed files with 152 additions and 50 deletions

View file

@ -22,16 +22,6 @@ namespace ofxVariableLab {
struct AtlasLayerComboSettings {
};
struct ComboIdentifier {
std::string fontPath = "data/celines-fonts/Version-2-var.ttf";
Layer::Type type = Layer::MSDFGEN;
bool operator==(const ComboIdentifier & other) const {
return (this->fontPath == other.fontPath
&& this->type == other.type);
}
};
class AtlasLayerCombo {
public:
virtual void setup(const ComboIdentifier & identifier,

View file

@ -96,9 +96,11 @@ void GPUFontAtlasLayerCombo::update(){
}
}
void GPUFontAtlasLayerCombo::careForChild(shared_ptr <Layer> layer){
if(layer->getType() == Layer::GPUFONT){
if(layer->getType() == LayerType::GPUFONT){
shared_ptr <GPUFontLayer> gpuFontLayer = static_pointer_cast <GPUFontLayer>(layer);
layers.push_back(gpuFontLayer);
gpuFontLayer->setMomsComboIdentifier(identifier);
gpuFontLayer->isWithNewMom();
gpuFontLayer->setDirtyDirty(true);
std::string oldText = mainText;
std::string layerText = gpuFontLayer->getProps().text;
std::string text = oldText + layerText;
@ -110,6 +112,7 @@ void GPUFontAtlasLayerCombo::careForChild(shared_ptr <Layer> layer){
mainText = text;
isDirty = true;
}
layers.push_back(std::move(gpuFontLayer));
}else{
ofLogError("GPUFontAtlasLayerCombo::careForChild()") << __LINE__ << ": child is not recognized as Layer::GPUFONT";
}
@ -126,18 +129,19 @@ void GPUFontAtlasLayerCombo::abandonChild(shared_ptr <Layer> layer){
return l == gpuFontLayer;
}), layers.end());
isDirty = true;
// update the text
// this doesn't happen very often, so let's just
// iterate over all layers and calculate fresh
std::string text = "";
totalCharacters = 0;
for(const auto & layer : layers){
std::string layerText = layer->getProps().text;
totalCharacters += layerText.length();
text += layerText;
}
removeDuplicateCharacters(text);
mainText = text;
//std::string text = "";
//totalCharacters = 0;
//for(const auto & layer : layers){
// std::string layerText = layer->getProps().text;
// totalCharacters += layerText.length();
// text += layerText;
//}
//removeDuplicateCharacters(text);
//mainText = text;
// NOTE: we do not want to update buffers now,
// as it's probably more costly than just keeping
// the old glyphs around...

View file

@ -1,5 +1,6 @@
#include "GPUFontLayer.h"
#include "Atlas.h"
#include "AtlasLayerCombo.h"
#include "Utils.h"
#include "font.hpp"
#include "fwd.hpp"
@ -28,7 +29,7 @@ void GPUFontLayer::drawCharacter(const char character,
float scale,
ofxVariableLab::FontVariation fontVariation){
}
const Layer::Type & GPUFontLayer::getType() const {
const LayerType & GPUFontLayer::getType() const {
return type;
}
void GPUFontLayer::setVFlip(const VFlipState vFlip){
@ -43,6 +44,19 @@ void GPUFontLayer::setDirtyDirty(bool dirtyDirty){
isDirty = dirtyDirty;
}
bool GPUFontLayer::wantsNewMom(){
return notHappyWithMom;
}
void GPUFontLayer::isWithNewMom(){
notHappyWithMom = false;
}
const ComboIdentifier & GPUFontLayer::getMomsComboIdentifier() const {
return momsComboIdentifier;
}
void GPUFontLayer::setMomsComboIdentifier(const ComboIdentifier & identifier){
momsComboIdentifier = identifier;
}
void GPUFontLayer::setProps(const Props & props){
if(propsBuffer.size() == 0 || props.text != propsBuffer[0].text
|| propsBuffer[0].fontVariations != props.fontVariations){
@ -64,6 +78,9 @@ void GPUFontLayer::setProps(const Props & props){
i++;
}
}
if(props.fontPath != propsBuffer[0].fontPath){
notHappyWithMom = true;
}
while(propsBuffer.size() > max(0, int(settings.maxBufferSize - 1))){
propsBuffer.pop_back();

View file

@ -1,5 +1,6 @@
#pragma once
#include "AtlasLayerCombo.h"
#include "font.hpp"
#include "ofMain.h"
#include "ofxGPUFont.h"
@ -33,10 +34,14 @@ class GPUFontLayer : public Layer {
return NULL; // evil?
}
const Type & getType() const override;
const LayerType & getType() const override;
void setVFlip(const VFlipState vFlip) override;
bool isDirtyDirty() const override;
void setDirtyDirty(bool dirtyDirty) override;
bool wantsNewMom() override;
void isWithNewMom() override;
const ComboIdentifier & getMomsComboIdentifier() const override;
void setMomsComboIdentifier(const ComboIdentifier & identifier) override;
const vector <ofxGPUFont::GlyphIdentity> & getVariationText();
@ -55,6 +60,8 @@ class GPUFontLayer : public Layer {
vector <ofxGPUFont::GlyphIdentity> variationText;
private:
Layer::Type type = GPUFONT;
ComboIdentifier momsComboIdentifier;
bool notHappyWithMom = false;
LayerType type = GPUFONT;
};
}

View file

@ -11,10 +11,6 @@
namespace ofxVariableLab {
// TODO: proper ID management and generation
// what do we have this fancy random_id for?
using LayerID = string;
struct LayerSettings {
uint32_t maxBufferSize = 100;
VFlipBehaviour vFlipBehaviour = V_FLIP_ONCE_AUTO;
@ -22,10 +18,6 @@ struct LayerSettings {
class Layer {
public:
enum Type {
MSDFGEN = 0,
GPUFONT
};
struct Props {
float x = 200;
float y = 200;
@ -72,10 +64,14 @@ class Layer {
virtual const LayerID & getId() = 0;
virtual void setShader(shared_ptr <ofShader> _shader) = 0;
virtual shared_ptr <ofShader> getShader() const = 0;
virtual const Type & getType() const = 0;
virtual const LayerType & getType() const = 0;
virtual void setVFlip(const VFlipState vFlip) = 0;
virtual bool isDirtyDirty() const = 0;
virtual void setDirtyDirty(bool dirtyDirty) = 0;
virtual bool wantsNewMom() = 0;
virtual void isWithNewMom() = 0;
virtual const ComboIdentifier & getMomsComboIdentifier() const = 0;
virtual void setMomsComboIdentifier(const ComboIdentifier & identifier) = 0;
static int n_layers;
};
}

View file

@ -16,23 +16,65 @@ void LayerComposition::setup(){
}
void LayerComposition::update(){
for(auto & l: layers){
if(l.second->wantsNewMom()){
const auto momIdentifier = l.second->getMomsComboIdentifier();
atlasLayerCombos[momIdentifier]->abandonChild(l.second);
ComboIdentifier idealMom{
l.second->getProps().fontPath,
momIdentifier.type
};
cout << "ideal mom looks like this: " << l.second->getProps().fontPath
<< (momIdentifier.type == LayerType::GPUFONT ? "gpufont" : "msdfgen")
<< endl;
findOrCreateNewMomForLayer(l.second, idealMom);
}
}
for(const auto & atlasLayerCombo : atlasLayerCombos){
atlasLayerCombo.second->update();
}
}
void LayerComposition::findOrCreateNewMomForLayer(shared_ptr <Layer> layer,
ComboIdentifier idealMom){
auto comboIterator = atlasLayerCombos.find(idealMom);
if(comboIterator != atlasLayerCombos.end()){
comboIterator->second->careForChild(layer);
}else{
switch(idealMom.type){
case LayerType::GPUFONT: {
auto combo = make_shared <GPUFontAtlasLayerCombo>();
GPUFontAtlasLayerComboSettings settings;
settings.gpuTextureOffset = nextGpuTextureOffset;
combo->setup(idealMom, settings);
nextGpuTextureOffset++;
combo->careForChild(layer);
atlasLayerCombos[idealMom] = std::move(combo);
break;
}
default:
case LayerType::MSDFGEN: {
auto combo = make_shared <MsdfAtlasLayerCombo>();
combo->setup(idealMom);
std::vector <ofxMsdfgen::FontVariation> msdfVariations;
for(const auto & v : layer->getProps().fontVariations){
msdfVariations.push_back({v.name, v.value});
}
combo->atlas->addVariations(msdfVariations);
combo->careForChild(layer);
atlasLayerCombos[idealMom] = std::move(combo);
}
}
}
}
LayerID LayerComposition::addLayer(const Layer::Props & props,
LayerID layerID){
ComboIdentifier identifier;
identifier.fontPath = props.fontPath;
identifier.type = Layer::GPUFONT;
string text = props.text;
std::vector <FontVariation> variations = {
{"Weight", 100.0},
{"Weight", 700.0}
};
identifier.type = LayerType::GPUFONT;
return addLayer(identifier,
text,
variations,
props,
props.fontVariations,
layerID);
}
@ -46,7 +88,8 @@ LayerID LayerComposition::addLayer(const ComboIdentifier & identifier,
props.fontPath = identifier.fontPath;
return addLayer(identifier,
props,
variations);
variations,
layerID);
}
LayerID LayerComposition::addLayer(const ComboIdentifier & identifier,
@ -54,7 +97,7 @@ LayerID LayerComposition::addLayer(const ComboIdentifier & identifier,
const std::vector <FontVariation> & variations,
LayerID layerID){
switch(identifier.type){
case Layer::GPUFONT: {
case LayerType::GPUFONT: {
shared_ptr <GPUFontAtlasLayerCombo> combo;
auto comboIterator = atlasLayerCombos.find(identifier);
if(comboIterator == atlasLayerCombos.end()){
@ -88,7 +131,7 @@ LayerID LayerComposition::addLayer(const ComboIdentifier & identifier,
}
default:
case Layer::MSDFGEN: {
case LayerType::MSDFGEN: {
// TODO: put most stuff in combo setup
auto combo = make_shared <MsdfAtlasLayerCombo>();
combo->setup(identifier); // TODO: add here text and variations
@ -131,12 +174,12 @@ shared_ptr <Layer> LayerComposition::getLayer(const LayerID & layerID){
void LayerComposition::draw() const {
for(const auto & layer_it : layers){
if(layer_it.second->getType() == Layer::MSDFGEN){
if(layer_it.second->getType() == LayerType::MSDFGEN){
layer_it.second->draw(glm::vec3(200, 200, 0));
}
}
for(const auto & combo_it : atlasLayerCombos){
if(combo_it.first.type == Layer::GPUFONT){
if(combo_it.first.type == LayerType::GPUFONT){
auto combo =
static_pointer_cast <GPUFontAtlasLayerCombo>(combo_it.second);
combo->draw();

View file

@ -25,6 +25,8 @@ class LayerComposition {
const Layer::Props & props,
const std::vector <FontVariation> & variations,
LayerID layerID = "");
void findOrCreateNewMomForLayer(shared_ptr <Layer> layer,
ComboIdentifier idealMom);
void removeLayer(const LayerID & id); // TODO: make bool, to catch nonexisting
shared_ptr <Layer> getLayer(const LayerID & layerID);
const unordered_map <ComboIdentifier, shared_ptr <AtlasLayerCombo> > & getAtlasLayerCombos() const;

View file

@ -36,6 +36,9 @@ void MsdfAtlasLayerCombo::update(){
void MsdfAtlasLayerCombo::careForChild(shared_ptr <Layer> layer){
shared_ptr <MsdfLayer> msdfLayer = dynamic_pointer_cast <MsdfLayer>(layer);
msdfLayer->setMomsComboIdentifier(identifier);
msdfLayer->isWithNewMom();
msdfLayer->setDirtyDirty(true);
msdfLayer->setAtlas(this->atlas);
msdfLayer->setShader(msdfShader);
auto & as = atlas->settings;
@ -46,7 +49,7 @@ void MsdfAtlasLayerCombo::careForChild(shared_ptr <Layer> layer){
isDirty = true;
}
}
layers.push_back(msdfLayer);
layers.push_back(std::move(msdfLayer));
}
void MsdfAtlasLayerCombo::abandonChild(shared_ptr <Layer> layer){
shared_ptr <MsdfLayer> msdfLayer = dynamic_pointer_cast <MsdfLayer>(layer);

View file

@ -268,7 +268,7 @@ void MsdfLayer::setShader(shared_ptr <ofShader> _shader){
shared_ptr <ofShader> MsdfLayer::getShader() const {
return shader;
}
const Layer::Type & MsdfLayer::getType() const {
const LayerType & MsdfLayer::getType() const {
return type;
}
void MsdfLayer::setVFlip(const VFlipState vFlip){
@ -280,6 +280,18 @@ bool MsdfLayer::isDirtyDirty() const {
void MsdfLayer::setDirtyDirty(bool dirtyDirty){
isDirty = dirtyDirty;
}
bool MsdfLayer::wantsNewMom(){
return notHappyWithMom;
}
void MsdfLayer::isWithNewMom(){
notHappyWithMom = false;
}
const ComboIdentifier & MsdfLayer::getMomsComboIdentifier() const {
return momsComboIdentifier;
}
void MsdfLayer::setMomsComboIdentifier(const ComboIdentifier & identifier){
momsComboIdentifier = identifier;
}
void MsdfLayer::setAtlas(shared_ptr <ofxMsdfgen::Atlas> _atlas){
atlas = _atlas;
// TODO: this does not seem proper

View file

@ -1,5 +1,6 @@
#pragma once
#include "AtlasLayerCombo.h"
#include "ofMain.h"
#include "ofxMsdfgen.h"
#include "Atlas.h"
@ -26,10 +27,14 @@ class MsdfLayer : public Layer {
const LayerID & getId() override;
void setShader(shared_ptr <ofShader> _shader) override;
shared_ptr <ofShader> getShader() const override;
const Type & getType() const override;
const LayerType & getType() const override;
void setVFlip(const VFlipState vFlip) override;
bool isDirtyDirty() const override;
void setDirtyDirty(bool dirtyDirty) override;
bool wantsNewMom() override;
void isWithNewMom() override;
const ComboIdentifier & getMomsComboIdentifier() const override;
void setMomsComboIdentifier(const ComboIdentifier & identifier) override;
void setAtlas(shared_ptr <ofxMsdfgen::Atlas> _atlas);
shared_ptr <ofxMsdfgen::Atlas> getAtlas() const;
@ -46,6 +51,8 @@ class MsdfLayer : public Layer {
VFlipState vFlip = V_FLIP_UNKNOWN;
private:
Layer::Type type = MSDFGEN;
bool notHappyWithMom = false;
ComboIdentifier momsComboIdentifier;
LayerType type = MSDFGEN;
};
}

View file

@ -27,6 +27,27 @@ struct FontVariation {
}
};
// TODO: proper ID management and generation
// what do we have this fancy random_id for?
using LayerID = std::string;
enum LayerType {
MSDFGEN = 0,
GPUFONT
};
struct ComboIdentifier {
std::string fontPath = "data/celines-fonts/Version-2-var.ttf";
LayerType type = LayerType::MSDFGEN;
public:
bool operator==(const ComboIdentifier & other) const {
return (this->fontPath == other.fontPath
&& this->type == other.type);
}
};
#ifndef F26DOT6_TO_DOUBLE
#define F26DOT6_TO_DOUBLE(x) (1 / 64. * double(x))
#endif