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 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 { class AtlasLayerCombo {
public: public:
virtual void setup(const ComboIdentifier & identifier, virtual void setup(const ComboIdentifier & identifier,

View file

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

View file

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

View file

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

View file

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

View file

@ -16,23 +16,65 @@ void LayerComposition::setup(){
} }
void LayerComposition::update(){ 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){ for(const auto & atlasLayerCombo : atlasLayerCombos){
atlasLayerCombo.second->update(); 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 LayerComposition::addLayer(const Layer::Props & props,
LayerID layerID){ LayerID layerID){
ComboIdentifier identifier; ComboIdentifier identifier;
identifier.fontPath = props.fontPath; identifier.fontPath = props.fontPath;
identifier.type = Layer::GPUFONT; identifier.type = LayerType::GPUFONT;
string text = props.text;
std::vector <FontVariation> variations = {
{"Weight", 100.0},
{"Weight", 700.0}
};
return addLayer(identifier, return addLayer(identifier,
text, props,
variations, props.fontVariations,
layerID); layerID);
} }
@ -46,7 +88,8 @@ LayerID LayerComposition::addLayer(const ComboIdentifier & identifier,
props.fontPath = identifier.fontPath; props.fontPath = identifier.fontPath;
return addLayer(identifier, return addLayer(identifier,
props, props,
variations); variations,
layerID);
} }
LayerID LayerComposition::addLayer(const ComboIdentifier & identifier, LayerID LayerComposition::addLayer(const ComboIdentifier & identifier,
@ -54,7 +97,7 @@ LayerID LayerComposition::addLayer(const ComboIdentifier & identifier,
const std::vector <FontVariation> & variations, const std::vector <FontVariation> & variations,
LayerID layerID){ LayerID layerID){
switch(identifier.type){ switch(identifier.type){
case Layer::GPUFONT: { case LayerType::GPUFONT: {
shared_ptr <GPUFontAtlasLayerCombo> combo; shared_ptr <GPUFontAtlasLayerCombo> combo;
auto comboIterator = atlasLayerCombos.find(identifier); auto comboIterator = atlasLayerCombos.find(identifier);
if(comboIterator == atlasLayerCombos.end()){ if(comboIterator == atlasLayerCombos.end()){
@ -88,7 +131,7 @@ LayerID LayerComposition::addLayer(const ComboIdentifier & identifier,
} }
default: default:
case Layer::MSDFGEN: { case LayerType::MSDFGEN: {
// TODO: put most stuff in combo setup // TODO: put most stuff in combo setup
auto combo = make_shared <MsdfAtlasLayerCombo>(); auto combo = make_shared <MsdfAtlasLayerCombo>();
combo->setup(identifier); // TODO: add here text and variations 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 { void LayerComposition::draw() const {
for(const auto & layer_it : layers){ 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)); layer_it.second->draw(glm::vec3(200, 200, 0));
} }
} }
for(const auto & combo_it : atlasLayerCombos){ for(const auto & combo_it : atlasLayerCombos){
if(combo_it.first.type == Layer::GPUFONT){ if(combo_it.first.type == LayerType::GPUFONT){
auto combo = auto combo =
static_pointer_cast <GPUFontAtlasLayerCombo>(combo_it.second); static_pointer_cast <GPUFontAtlasLayerCombo>(combo_it.second);
combo->draw(); combo->draw();

View file

@ -25,6 +25,8 @@ class LayerComposition {
const Layer::Props & props, const Layer::Props & props,
const std::vector <FontVariation> & variations, const std::vector <FontVariation> & variations,
LayerID layerID = ""); LayerID layerID = "");
void findOrCreateNewMomForLayer(shared_ptr <Layer> layer,
ComboIdentifier idealMom);
void removeLayer(const LayerID & id); // TODO: make bool, to catch nonexisting void removeLayer(const LayerID & id); // TODO: make bool, to catch nonexisting
shared_ptr <Layer> getLayer(const LayerID & layerID); shared_ptr <Layer> getLayer(const LayerID & layerID);
const unordered_map <ComboIdentifier, shared_ptr <AtlasLayerCombo> > & getAtlasLayerCombos() const; 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){ void MsdfAtlasLayerCombo::careForChild(shared_ptr <Layer> layer){
shared_ptr <MsdfLayer> msdfLayer = dynamic_pointer_cast <MsdfLayer>(layer); shared_ptr <MsdfLayer> msdfLayer = dynamic_pointer_cast <MsdfLayer>(layer);
msdfLayer->setMomsComboIdentifier(identifier);
msdfLayer->isWithNewMom();
msdfLayer->setDirtyDirty(true);
msdfLayer->setAtlas(this->atlas); msdfLayer->setAtlas(this->atlas);
msdfLayer->setShader(msdfShader); msdfLayer->setShader(msdfShader);
auto & as = atlas->settings; auto & as = atlas->settings;
@ -46,7 +49,7 @@ void MsdfAtlasLayerCombo::careForChild(shared_ptr <Layer> layer){
isDirty = true; isDirty = true;
} }
} }
layers.push_back(msdfLayer); layers.push_back(std::move(msdfLayer));
} }
void MsdfAtlasLayerCombo::abandonChild(shared_ptr <Layer> layer){ void MsdfAtlasLayerCombo::abandonChild(shared_ptr <Layer> layer){
shared_ptr <MsdfLayer> msdfLayer = dynamic_pointer_cast <MsdfLayer>(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 { shared_ptr <ofShader> MsdfLayer::getShader() const {
return shader; return shader;
} }
const Layer::Type & MsdfLayer::getType() const { const LayerType & MsdfLayer::getType() const {
return type; return type;
} }
void MsdfLayer::setVFlip(const VFlipState vFlip){ void MsdfLayer::setVFlip(const VFlipState vFlip){
@ -280,6 +280,18 @@ bool MsdfLayer::isDirtyDirty() const {
void MsdfLayer::setDirtyDirty(bool dirtyDirty){ void MsdfLayer::setDirtyDirty(bool dirtyDirty){
isDirty = 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){ void MsdfLayer::setAtlas(shared_ptr <ofxMsdfgen::Atlas> _atlas){
atlas = _atlas; atlas = _atlas;
// TODO: this does not seem proper // TODO: this does not seem proper

View file

@ -1,5 +1,6 @@
#pragma once #pragma once
#include "AtlasLayerCombo.h"
#include "ofMain.h" #include "ofMain.h"
#include "ofxMsdfgen.h" #include "ofxMsdfgen.h"
#include "Atlas.h" #include "Atlas.h"
@ -26,10 +27,14 @@ class MsdfLayer : public Layer {
const LayerID & getId() override; const LayerID & getId() override;
void setShader(shared_ptr <ofShader> _shader) override; void setShader(shared_ptr <ofShader> _shader) override;
shared_ptr <ofShader> getShader() const override; shared_ptr <ofShader> getShader() const override;
const Type & getType() const override; const LayerType & getType() const override;
void setVFlip(const VFlipState vFlip) override; void setVFlip(const VFlipState vFlip) override;
bool isDirtyDirty() const override; bool isDirtyDirty() const override;
void setDirtyDirty(bool dirtyDirty) 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); void setAtlas(shared_ptr <ofxMsdfgen::Atlas> _atlas);
shared_ptr <ofxMsdfgen::Atlas> getAtlas() const; shared_ptr <ofxMsdfgen::Atlas> getAtlas() const;
@ -46,6 +51,8 @@ class MsdfLayer : public Layer {
VFlipState vFlip = V_FLIP_UNKNOWN; VFlipState vFlip = V_FLIP_UNKNOWN;
private: 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 #ifndef F26DOT6_TO_DOUBLE
#define F26DOT6_TO_DOUBLE(x) (1 / 64. * double(x)) #define F26DOT6_TO_DOUBLE(x) (1 / 64. * double(x))
#endif #endif