diff --git a/Source/Ember/Ember.h b/Source/Ember/Ember.h index 16272be..cc94140 100644 --- a/Source/Ember/Ember.h +++ b/Source/Ember/Ember.h @@ -239,7 +239,7 @@ public: ember.m_FinalXform.m_ColorSpeed = 0; ember.m_FinalXform.m_Motion.clear(); ember.m_FinalXform.ClearAndDeleteVariations(); - ember.m_FinalXform.AddVariation(m_VariationList.GetVariationCopy(eVariationId::VAR_LINEAR, 0));//Do this so it doesn't appear empty. + ember.m_FinalXform.AddVariation(m_VariationList->GetVariationCopy(eVariationId::VAR_LINEAR, 0));//Do this so it doesn't appear empty. } } @@ -1036,7 +1036,7 @@ public: m_Xforms[i].m_Affine.D(0); m_Xforms[i].m_Affine.E(1); m_Xforms[i].m_Affine.F(0); - m_Xforms[i].AddVariation(m_VariationList.GetVariationCopy(eVariationId::VAR_LINEAR)); + m_Xforms[i].AddVariation(m_VariationList->GetVariationCopy(eVariationId::VAR_LINEAR)); result++; sym = -sym; } @@ -1058,7 +1058,7 @@ public: m_Xforms[i].m_Affine.E(m_Xforms[i].m_Affine.A()); m_Xforms[i].m_Affine.C(0); m_Xforms[i].m_Affine.F(0); - m_Xforms[i].AddVariation(m_VariationList.GetVariationCopy(eVariationId::VAR_LINEAR)); + m_Xforms[i].AddVariation(m_VariationList->GetVariationCopy(eVariationId::VAR_LINEAR)); result++; } @@ -1688,7 +1688,7 @@ private: Xform m_FinalXform; //Single global reference to create variations with. - VariationList& m_VariationList = VariationList::Instance(); + shared_ptr> m_VariationList = VariationList::Instance(); /// /// Interpolation function that takes the address of a member variable of type T as a template parameter. diff --git a/Source/Ember/Interpolate.h b/Source/Ember/Interpolate.h index 6626f16..ee80d28 100644 --- a/Source/Ember/Interpolate.h +++ b/Source/Ember/Interpolate.h @@ -44,7 +44,7 @@ public: bool currentFinal, final = sourceEmbers[0].UseFinalXform(); size_t i, xf, currentCount, maxCount = sourceEmbers[0].XformCount(); Xform* destOtherXform; - VariationList& variationList(VariationList::Instance()); + auto variationList = VariationList::Instance(); //Determine the max number of xforms present in sourceEmbers. //Also check if final xforms are used in any of them. @@ -138,7 +138,7 @@ public: destOtherXform->GetVariationById(eVariationId::VAR_WEDGE_SPH) || destOtherXform->GetVariationById(eVariationId::VAR_WEDGE_JULIA)) { - destXform->AddVariation(variationList.GetVariationCopy(eVariationId::VAR_LINEAR, -1)); + destXform->AddVariation(variationList->GetVariationCopy(eVariationId::VAR_LINEAR, -1)); //Set the coefs appropriately. destXform->m_Affine.A(-1); destXform->m_Affine.D(0); @@ -167,7 +167,7 @@ public: if (destOtherXform->GetVariationById(eVariationId::VAR_RECTANGLES)) { - if (auto var = variationList.GetParametricVariationCopy(eVariationId::VAR_RECTANGLES)) + if (auto var = variationList->GetParametricVariationCopy(eVariationId::VAR_RECTANGLES)) { var->SetParamVal("rectangles_x", 0); var->SetParamVal("rectangles_y", 0); @@ -179,7 +179,7 @@ public: if (destOtherXform->GetVariationById(eVariationId::VAR_RINGS2)) { - if (auto var = variationList.GetParametricVariationCopy(eVariationId::VAR_RINGS2)) + if (auto var = variationList->GetParametricVariationCopy(eVariationId::VAR_RINGS2)) { var->SetParamVal("rings2_val", 0); destXform->AddVariation(var); @@ -190,13 +190,13 @@ public: if (destOtherXform->GetVariationById(eVariationId::VAR_FAN2)) { - destXform->AddVariation(variationList.GetVariationCopy(eVariationId::VAR_FAN2)); + destXform->AddVariation(variationList->GetVariationCopy(eVariationId::VAR_FAN2)); found++; } if (destOtherXform->GetVariationById(eVariationId::VAR_BLOB)) { - if (auto var = variationList.GetParametricVariationCopy(eVariationId::VAR_BLOB)) + if (auto var = variationList->GetParametricVariationCopy(eVariationId::VAR_BLOB)) { var->SetParamVal("blob_low", 1); destXform->AddVariation(var); @@ -207,13 +207,13 @@ public: if (destOtherXform->GetVariationById(eVariationId::VAR_PERSPECTIVE)) { - destXform->AddVariation(variationList.GetVariationCopy(eVariationId::VAR_PERSPECTIVE)); + destXform->AddVariation(variationList->GetVariationCopy(eVariationId::VAR_PERSPECTIVE)); found++; } if (destOtherXform->GetVariationById(eVariationId::VAR_CURL)) { - if (auto var = variationList.GetParametricVariationCopy(eVariationId::VAR_CURL)) + if (auto var = variationList->GetParametricVariationCopy(eVariationId::VAR_CURL)) { var->SetParamVal("curl_c1", 0); destXform->AddVariation(var); @@ -224,7 +224,7 @@ public: if (destOtherXform->GetVariationById(eVariationId::VAR_SUPER_SHAPE)) { - if (auto var = variationList.GetParametricVariationCopy(eVariationId::VAR_SUPER_SHAPE)) + if (auto var = variationList->GetParametricVariationCopy(eVariationId::VAR_SUPER_SHAPE)) { var->SetParamVal("super_shape_n1", 2); var->SetParamVal("super_shape_n2", 2); @@ -254,13 +254,13 @@ public: if (destOtherXform->GetVariationById(eVariationId::VAR_FAN)) { - destXform->AddVariation(variationList.GetVariationCopy(eVariationId::VAR_FAN)); + destXform->AddVariation(variationList->GetVariationCopy(eVariationId::VAR_FAN)); found++; } if (destOtherXform->GetVariationById(eVariationId::VAR_RINGS)) { - destXform->AddVariation(variationList.GetVariationCopy(eVariationId::VAR_RINGS)); + destXform->AddVariation(variationList->GetVariationCopy(eVariationId::VAR_RINGS)); found++; } } @@ -280,7 +280,7 @@ public: //If there still are no matches, switch back to linear. if (found == 0) { - destXform->AddVariation(variationList.GetVariationCopy(eVariationId::VAR_LINEAR)); + destXform->AddVariation(variationList->GetVariationCopy(eVariationId::VAR_LINEAR)); } else if (found > 0) { diff --git a/Source/Ember/SheepTools.h b/Source/Ember/SheepTools.h index 60c2f87..16d5ef0 100644 --- a/Source/Ember/SheepTools.h +++ b/Source/Ember/SheepTools.h @@ -83,9 +83,9 @@ public: Xform xform1(T(0.25), T(1), T(0.5), T(1), T(0.5), T(0), T(0), T(0.5), T(0.5), T(0.25)); Xform xform2(T(0.25), T(0.66), T(0.5), T(1), T(0.5), T(0), T(0), T(0.5), T(-0.5), T(0.25)); Xform xform3(T(0.25), T(0.33), T(0.5), T(1), T(0.5), T(0), T(0), T(0.5), T(0.0), T(-0.5)); - xform1.AddVariation(m_VariationList.GetVariationCopy(eVariationId::VAR_LINEAR)); - xform2.AddVariation(m_VariationList.GetVariationCopy(eVariationId::VAR_LINEAR)); - xform3.AddVariation(m_VariationList.GetVariationCopy(eVariationId::VAR_LINEAR)); + xform1.AddVariation(m_VariationList->GetVariationCopy(eVariationId::VAR_LINEAR)); + xform2.AddVariation(m_VariationList->GetVariationCopy(eVariationId::VAR_LINEAR)); + xform3.AddVariation(m_VariationList->GetVariationCopy(eVariationId::VAR_LINEAR)); ember.AddXform(xform1); ember.AddXform(xform2); ember.AddXform(xform3); @@ -599,7 +599,7 @@ public: bool postid, addfinal = false; int var, samed, multid, samepost; glm::length_t i, j, k, n; - size_t varCount = m_VariationList.Size(); + size_t varCount = m_VariationList->Size(); Palette palette; static size_t xformDistrib[] = { @@ -683,12 +683,12 @@ public: if (var > -1) { if (xform->TotalVariationCount() < maxVars) - xform->AddVariation(m_VariationList.GetVariation(var)->Copy());//Use only one variation specified for all xforms. + xform->AddVariation(m_VariationList->GetVariation(var)->Copy());//Use only one variation specified for all xforms. } else if (multid && var == -1) { if (xform->TotalVariationCount() < maxVars) - xform->AddVariation(m_VariationList.GetVariation(m_Rand.Rand() % varCount)->Copy());//Choose a random var for this xform. + xform->AddVariation(m_VariationList->GetVariation(m_Rand.Rand() % varCount)->Copy());//Choose a random var for this xform. } else { @@ -721,7 +721,7 @@ public: if (var != -2) { //Pick a random variation and use a random weight from 0-1. - Variation* v = m_VariationList.GetVariationCopy(static_cast(m_Rand.Rand() % varCount), m_Rand.Frand(T(0.001), 1)); + Variation* v = m_VariationList->GetVariationCopy(static_cast(m_Rand.Rand() % varCount), m_Rand.Frand(T(0.001), 1)); if (v && !xform->AddVariation(v)) delete v;//It already existed and therefore was not added. @@ -729,7 +729,7 @@ public: else { //Pick a random variation from the suppled IDs and use a random weight from 0-1. - Variation* v = m_VariationList.GetVariationCopy(useVars[m_Rand.Rand() % useVars.size()], m_Rand.Frand(T(0.001), 1)); + Variation* v = m_VariationList->GetVariationCopy(useVars[m_Rand.Rand() % useVars.size()], m_Rand.Frand(T(0.001), 1)); if (v && !xform->AddVariation(v)) delete v; @@ -759,12 +759,12 @@ public: if (var != -2) { //Pick a random variation and use a random weight from 0-1. - xform->AddVariation(m_VariationList.GetVariationCopy(static_cast(m_Rand.Rand() % varCount), m_Rand.Frand(T(0.001), 1))); + xform->AddVariation(m_VariationList->GetVariationCopy(static_cast(m_Rand.Rand() % varCount), m_Rand.Frand(T(0.001), 1))); } else { //Pick a random variation from the suppled IDs and use a random weight from 0-1. - xform->AddVariation(m_VariationList.GetVariationCopy(useVars[m_Rand.Rand() % useVars.size()], m_Rand.Frand(T(0.001), 1))); + xform->AddVariation(m_VariationList->GetVariationCopy(useVars[m_Rand.Rand() % useVars.size()], m_Rand.Frand(T(0.001), 1))); } } } @@ -1345,6 +1345,6 @@ private: unique_ptr> m_Renderer; QTIsaac m_Rand; PaletteList m_PaletteList; - VariationList& m_VariationList; + shared_ptr> m_VariationList; }; } diff --git a/Source/Ember/Utils.h b/Source/Ember/Utils.h index 5f3db64..25fcebf 100644 --- a/Source/Ember/Utils.h +++ b/Source/Ember/Utils.h @@ -193,13 +193,16 @@ private: /// member variables cannot be exported across module boundaries. /// Derived classes should inherit from this using the CRTP, and declare a friend to it. /// They also should make their constructors private and destructors public. +/// This has a severe flaw in that it cannot be used across module boundaries, else +/// every module will have its own copy. This makes it function as a per-module +/// singleton, which is unlikely to ever be desired. /// Attribution: This class is a combination of /// http://btorpey.github.io/blog/2014/02/12/shared-singletons/ /// and /// http://enki-tech.blogspot.com/2012/08/c11-generic-singleton.html /// template -class Singleton +class EMBER_API Singleton { public: /// @@ -243,6 +246,28 @@ public: x(const x& other) = delete; \ const x& operator=(const x& other) = delete +//Use this if not deriving from the Singleton class and are declaring Instance() in a header and implementing it in a cpp file. +#define SINGLETON_INSTANCE_DECL(x) \ + static std::shared_ptr Instance(); \ + x(const x& other) = delete; \ + const x& operator=(const x& other) = delete//Semicolon deliberately omitted to force it on the caller. + +//Use this if not deriving from the Singleton class and are implementing Instance() in a cpp file. +#define SINGLETON_INSTANCE_IMPL(x) \ + std::shared_ptr x::Instance() \ + { \ + static weak_ptr staticInstance; \ + auto temp = staticInstance.lock(); \ + \ + if (!temp) \ + { \ + temp.reset(new x()); \ + staticInstance = temp; \ + } \ + \ + return temp; \ + } + /// /// Open a file in binary mode and read its entire contents into a vector of bytes. Optionally null terminate. /// diff --git a/Source/Ember/VarFuncs.h b/Source/Ember/VarFuncs.h index 99d0884..cd76889 100644 --- a/Source/Ember/VarFuncs.h +++ b/Source/Ember/VarFuncs.h @@ -13,7 +13,7 @@ namespace EmberNs /// This class is a singleton since all of its data is shared and read-only. /// template -class EMBER_API VarFuncs : public Singleton> +class EMBER_API VarFuncs { public: /// @@ -542,7 +542,7 @@ public: } } - SINGLETON_DERIVED_IMPL(VarFuncs); + SINGLETON_INSTANCE_DECL(VarFuncs);//Implemented in VariationList.cpp private: /// diff --git a/Source/Ember/VariationList.cpp b/Source/Ember/VariationList.cpp index 1f37039..b27781e 100644 --- a/Source/Ember/VariationList.cpp +++ b/Source/Ember/VariationList.cpp @@ -17,14 +17,12 @@ namespace EmberNs m_Variations.push_back(new Post##varName##Variation()); /// -/// Singleton pattern, return a reference to the only instance of this object in existence. +/// Singleton patterns, return a reference to the only instance of this object in existence. /// template -VariationList& VariationList::Instance() -{ - static VariationList v; - return v; -} +SINGLETON_INSTANCE_IMPL(VarFuncs) +template +SINGLETON_INSTANCE_IMPL(VariationList) /// /// Constructor which initializes all of the variation objects and stores them in the list. diff --git a/Source/Ember/VariationList.h b/Source/Ember/VariationList.h index cf31970..83f7216 100644 --- a/Source/Ember/VariationList.h +++ b/Source/Ember/VariationList.h @@ -21,10 +21,7 @@ template class EMBER_API VariationList { public: - static VariationList& Instance(); ~VariationList(); - VariationList(const VariationList& varList) = delete; - VariationList& operator = (const VariationList& varList) = delete; const Variation* GetVariation(size_t index) const; const Variation* GetVariation(size_t index, eVariationType varType) const; Variation* GetVariationCopy(size_t index, T weight = 1) const; @@ -48,6 +45,8 @@ public: const vector*>& PreVars() const; const vector*>& PostVars() const; + SINGLETON_INSTANCE_DECL(VariationList);//Implemented in VariationList.cpp + private: VariationList(); Variation* MakeCopyWithWeight(const Variation* var, T weight) const; diff --git a/Source/Ember/Variations06.h b/Source/Ember/Variations06.h index f57f286..5a618fc 100644 --- a/Source/Ember/Variations06.h +++ b/Source/Ember/Variations06.h @@ -281,7 +281,6 @@ protected: m_Params.push_back(ParamWithName(&m_Scale, prefix + "hexes_scale", 1)); m_Params.push_back(ParamWithName(true, &m_RotSin, prefix + "hexes_rotsin"));//Precalc. m_Params.push_back(ParamWithName(true, &m_RotCos, prefix + "hexes_rotcos")); - m_VarFuncs = VarFuncs::Instance(); } private: @@ -291,7 +290,7 @@ private: T m_Scale; T m_RotSin;//Precalc. T m_RotCos; - std::shared_ptr> m_VarFuncs; + shared_ptr> m_VarFuncs = VarFuncs::Instance(); }; /// @@ -3774,7 +3773,7 @@ public: //No possible solution was found, so it is unused here. //The full calculation is recomputed for every point. return - "static void Position(__global real_t* p, __global real3* grad, int x, int y, real_t z, real_t s, real_t d, real2* v)\n" + "static void Position(__global real_t* p, __global real_t* grad, int x, int y, real_t z, real_t s, real_t d, real2* v)\n" "{\n" " real3 e, f;\n" " e.x = x * 2.5;\n" @@ -3823,7 +3822,7 @@ public: << "\t\t{\n" << "\t\t for (dj = -1; dj < 2; dj++)\n" << "\t\t {\n" - << "\t\t Position(globalShared + NOISE_INDEX, (__global real3*)(globalShared + NOISE_POINTS), cv.x + di, cv.y + dj, " << z << ", " << halfCellSize << ", " << distort << ", &p[i]);\n" + << "\t\t Position(globalShared + NOISE_INDEX, globalShared + NOISE_POINTS, cv.x + di, cv.y + dj, " << z << ", " << halfCellSize << ", " << distort << ", &p[i]);\n" << "\t\t i++;\n" << "\t\t }\n" << "\t\t}\n" @@ -3839,7 +3838,7 @@ public: << "\t\t{\n" << "\t\t for (dj = -1; dj < 2; dj++)\n" << "\t\t {\n" - << "\t\t Position(globalShared + NOISE_INDEX, (__global real3*)(globalShared + NOISE_POINTS), cv.x + di, cv.y + dj, " << z << ", " << halfCellSize << ", " << distort << ", &p[i]);\n" + << "\t\t Position(globalShared + NOISE_INDEX, globalShared + NOISE_POINTS, cv.x + di, cv.y + dj, " << z << ", " << halfCellSize << ", " << distort << ", &p[i]);\n" << "\t\t i++;\n" << "\t\t }\n" << "\t\t}\n" @@ -3870,7 +3869,6 @@ protected: void Init() { string prefix = Prefix(); - m_VarFuncs = VarFuncs::Instance(); m_Params.clear(); m_Params.reserve(8); m_Params.push_back(ParamWithName(&m_CellSize, prefix + "crackle_cellsize", 1)); @@ -3912,7 +3910,7 @@ private: T m_Z; T m_HalfCellSize;//Precalc v2T m_C[CACHE_WIDTH][CACHE_WIDTH];//Not kept as a precalc because it crashes Nvidia GPUs. - std::shared_ptr> m_VarFuncs; + shared_ptr> m_VarFuncs = VarFuncs::Instance(); }; /// diff --git a/Source/Ember/VariationsDC.h b/Source/Ember/VariationsDC.h index 72e7da6..83a2917 100644 --- a/Source/Ember/VariationsDC.h +++ b/Source/Ember/VariationsDC.h @@ -1314,6 +1314,7 @@ public: << "\t\t break; \n" << "\n" << "\t\t case " << SHAPE_BLUR << ": \n" + << "\t\t default: \n" << "\t\t r = (1 + " << edge << ") * MwcNext01(mwc); \n" << "\n" << "\t\t if (r > 1 - " << edge << ")\n" @@ -1369,6 +1370,7 @@ public: << "\t\t break; \n" << "\n" << "\t\t case " << MAP_BUBBLE2 << ": \n" + << "\t\t default: \n" << "\t\t r = 0.25 - (SQR(vx) + SQR(vy)); \n" << "\n" << "\t\t if (r < 0)\n" @@ -1382,13 +1384,13 @@ public: << "\t\t break; \n" << "\t\t }\n" << "\n" - << "\t\t p = PerlinNoise3D(&v, globalShared + NOISE_INDEX, (__global real3*)(globalShared + NOISE_POINTS), " << amps << ", " << freqs << ", iOctaves); \n" + << "\t\t p = PerlinNoise3D(&v, globalShared + NOISE_INDEX, globalShared + NOISE_POINTS, " << amps << ", " << freqs << ", iOctaves); \n" << "\n" << "\t\t if (p > 0)\n" << "\t\t e = p * (1 + e * e * 20) + 2 * e; \n" << "\t\t else\n" << "\t\t e = p * (1 + e * e * 20) - 2 * e; \n" - << "}\n" + << "\t\t}\n" << "\t\twhile ((e < " << notchBottom << " || e > " << notchTop << ") && t++ < iBailout); \n" << "\n" << "\t\tvOut.x = xform->m_VariationWeights[" << varIndex << "] * vx; \n" @@ -1413,7 +1415,6 @@ protected: void Init() { string prefix = Prefix(); - m_VarFuncs = VarFuncs::Instance(); m_Params.clear(); m_Params.reserve(15); m_Params.push_back(ParamWithName(&m_Shape, prefix + "dc_perlin_shape", 0, eParamType::INTEGER, 0, 2));//Params. @@ -1448,7 +1449,7 @@ private: T m_SelectBailout; T m_NotchBottom;//Precalc. T m_NotchTop; - shared_ptr> m_VarFuncs; + shared_ptr> m_VarFuncs = VarFuncs::Instance(); }; MAKEPREPOSTPARVAR(DCBubble, dc_bubble, DC_BUBBLE) diff --git a/Source/Ember/Xform.h b/Source/Ember/Xform.h index e8d6bf5..2911a51 100644 --- a/Source/Ember/Xform.h +++ b/Source/Ember/Xform.h @@ -879,7 +879,7 @@ public: bool Flatten(vector& names) { bool shouldFlatten = true; - VariationList& vl(VariationList::Instance()); + auto vl = VariationList::Instance(); if (GetVariationById(eVariationId::VAR_FLATTEN) == nullptr) { @@ -898,7 +898,7 @@ public: } //Now traverse the parameters for this variation. - if (ParametricVariation* parVar = dynamic_cast*>(var))//If any parametric variation parameter is present and non-zero, don't flatten. + if (auto parVar = dynamic_cast*>(var))//If any parametric variation parameter is present and non-zero, don't flatten. { for (auto& s : names) { @@ -915,7 +915,7 @@ public: if (shouldFlatten)//Flatten was not present and neither was any variation name or parameter in the list. { - auto var = vl.GetVariationCopy(eVariationId::VAR_FLATTEN); + auto var = vl->GetVariationCopy(eVariationId::VAR_FLATTEN); if (AddVariation(var)) { diff --git a/Source/Ember/XmlToEmber.h b/Source/Ember/XmlToEmber.h index bf69e1b..4a62989 100644 --- a/Source/Ember/XmlToEmber.h +++ b/Source/Ember/XmlToEmber.h @@ -337,8 +337,8 @@ public: ScanForEmberNodes(rootnode, bn, embers, useDefaults); xmlFreeDoc(doc); emberSize = embers.size(); - auto b = embers.begin(); - auto secondToLast = Advance(embers.begin(), emberSize - 2); + auto first = embers.begin(); + //t.Toc("ScanForEmberNodes"); //Check to see if the first control point or the second-to-last @@ -346,11 +346,16 @@ public: //and should be reset to linear (with a warning). if (emberSize > 0) { - if (b->m_Interp == eInterp::EMBER_INTERP_SMOOTH) - b->m_Interp = eInterp::EMBER_INTERP_LINEAR; + if (first->m_Interp == eInterp::EMBER_INTERP_SMOOTH) + first->m_Interp = eInterp::EMBER_INTERP_LINEAR; - if (emberSize >= 2 && secondToLast->m_Interp == eInterp::EMBER_INTERP_SMOOTH) - secondToLast->m_Interp = eInterp::EMBER_INTERP_LINEAR; + if (emberSize >= 2) + { + auto secondToLast = Advance(embers.begin(), emberSize - 2); + + if (secondToLast->m_Interp == eInterp::EMBER_INTERP_SMOOTH) + secondToLast->m_Interp = eInterp::EMBER_INTERP_LINEAR; + } } //Finally, ensure that consecutive 'rotate' parameters never exceed @@ -1263,7 +1268,7 @@ private: //Only correct names if it came from an outside source. Names originating from this library are always considered correct. string s = fromEmber ? string(CCX(curAtt->name)) : GetCorrectedVariationName(m_BadVariationNames, curAtt); - if (auto var = m_VariationList.GetVariation(s)) + if (auto var = m_VariationList->GetVariation(s)) { T weight = 0; Aton(attStr, weight); @@ -1543,7 +1548,7 @@ private: static bool m_Init; static unordered_map m_BadParamNames; static vector, vector>> m_BadVariationNames; - VariationList& m_VariationList;//The variation list used to make copies of variations to populate the embers with. + shared_ptr> m_VariationList;//The variation list used to make copies of variations to populate the embers with. PaletteList m_PaletteList; }; } diff --git a/Source/EmberCL/FunctionMapper.cpp b/Source/EmberCL/FunctionMapper.cpp index 40e35f3..500977f 100644 --- a/Source/EmberCL/FunctionMapper.cpp +++ b/Source/EmberCL/FunctionMapper.cpp @@ -176,7 +176,7 @@ FunctionMapper::FunctionMapper() " return ratiomax;\n" "}\n"; s_GlobalMap["SimplexNoise3D"] = - "inline real_t SimplexNoise3D(real3* v, __global real_t* p, __global real3* grad)\n" + "inline real_t SimplexNoise3D(real3* v, __global real_t* p, __global real_t* grad)\n" "{\n" " real3 c[4];\n" " real_t n = 0;\n" @@ -195,6 +195,7 @@ FunctionMapper::FunctionMapper() " c[0].z = (*v).z - z0;\n" " int i1, j1, k1;\n" " int i2, j2, k2;\n" + " real3 u;\n" "\n" " if (c[0].x >= c[0].y)\n" " {\n" @@ -249,25 +250,28 @@ FunctionMapper::FunctionMapper() " gi[1] = (int)p[ii + i1 + (int)p[jj + j1 + (int)p[kk + k1]]];\n" " gi[2] = (int)p[ii + i2 + (int)p[jj + j2 + (int)p[kk + k2]]];\n" " gi[3] = (int)p[ii + 1 + (int)p[jj + 1 + (int)p[kk + 1]]];\n" + "\n" " for (uint corner = 0; corner < 4; corner++)\n" " {\n" " t = 0.6 - Sqr(c[corner].x) - Sqr(c[corner].y) - Sqr(c[corner].z);\n" "\n" " if (t > 0)\n" " {\n" - " real3 u = grad[gi[corner]];\n" + " u.x = grad[(gi[corner] * 3)];\n" + " u.y = grad[(gi[corner] * 3) + 1];\n" + " u.z = grad[(gi[corner] * 3) + 2];\n" " t *= t;\n" " n += t * t * (u.x * c[corner].x + u.y * c[corner].y + u.z * c[corner].z);\n" " }\n" " }\n" "\n" - " return 32 * n;\n" + " return 32.0 * n;\n" "}\n"; s_GlobalMap["PerlinNoise3D"] = - "inline real_t PerlinNoise3D(real3* v, __global real_t* p, __global real3* grad, real_t aScale, real_t fScale, int octaves)\n" + "inline real_t PerlinNoise3D(real3* v, __global real_t* p, __global real_t* grad, real_t aScale, real_t fScale, int octaves)\n" "{\n" " int i;\n" - " real_t n = 0, a = 1;\n" + " real_t n = 0.0, a = 1.0;\n" " real3 u = *v;\n" "\n" " for (i = 0; i < octaves; i++)\n" diff --git a/Source/EmberCL/OpenCLInfo.cpp b/Source/EmberCL/OpenCLInfo.cpp index 43cbf9d..d16de2b 100644 --- a/Source/EmberCL/OpenCLInfo.cpp +++ b/Source/EmberCL/OpenCLInfo.cpp @@ -68,6 +68,8 @@ OpenCLInfo::OpenCLInfo() } } +SINGLETON_INSTANCE_IMPL(OpenCLInfo) + /// /// Get a const reference to the vector of available platforms. /// diff --git a/Source/EmberCL/OpenCLInfo.h b/Source/EmberCL/OpenCLInfo.h index 8430303..3b6a808 100644 --- a/Source/EmberCL/OpenCLInfo.h +++ b/Source/EmberCL/OpenCLInfo.h @@ -17,7 +17,7 @@ namespace EmberCLns /// This class derives from EmberReport, so the caller is able /// to retrieve a text dump of error information if any errors occur. /// -class EMBERCL_API OpenCLInfo : public EmberReport, public Singleton +class EMBERCL_API OpenCLInfo : public EmberReport { public: const vector& Platforms() const; @@ -54,7 +54,7 @@ public: return val; } - SINGLETON_DERIVED_IMPL(OpenCLInfo); + SINGLETON_INSTANCE_DECL(OpenCLInfo); private: OpenCLInfo(); diff --git a/Source/EmberGenome/EmberGenome.cpp b/Source/EmberGenome/EmberGenome.cpp index 479a2bb..1ce0ec7 100644 --- a/Source/EmberGenome/EmberGenome.cpp +++ b/Source/EmberGenome/EmberGenome.cpp @@ -64,13 +64,13 @@ bool EmberGenome(EmberOptions& opt) return true; } - VariationList& varList(VariationList::Instance()); + auto varList = VariationList::Instance(); if (opt.AllVars() || opt.RegVars() || opt.PreVars() || opt.PostVars()) { if (opt.AllVars()) { - auto& vars = varList.AllVars(); + auto& vars = varList->AllVars(); for (auto& v : vars) cout << v->Name() << "\n"; @@ -82,13 +82,13 @@ bool EmberGenome(EmberOptions& opt) vector*> vars; if (opt.RegVars()) - vars.insert(vars.end(), varList.RegVars().begin(), varList.RegVars().end()); + vars.insert(vars.end(), varList->RegVars().begin(), varList->RegVars().end()); if (opt.PreVars()) - vars.insert(vars.end(), varList.PreVars().begin(), varList.PreVars().end()); + vars.insert(vars.end(), varList->PreVars().begin(), varList->PreVars().end()); if (opt.PostVars()) - vars.insert(vars.end(), varList.PostVars().begin(), varList.PostVars().end()); + vars.insert(vars.end(), varList->PostVars().begin(), varList->PostVars().end()); for (auto& v : vars) cout << v->Name() << "\n"; @@ -192,16 +192,16 @@ bool EmberGenome(EmberOptions& opt) noVars.push_back(eVariationId::VAR_SPLITS); //Loop over the novars and set ivars to the complement. - for (i = 0; i < varList.Size(); i++) + for (i = 0; i < varList->Size(); i++) { for (j = 0; j < noVars.size(); j++) { - if (noVars[j] == varList.GetVariation(i)->VariationId()) + if (noVars[j] == varList->GetVariation(i)->VariationId()) break; } if (j == noVars.size()) - vars.push_back(varList.GetVariation(i)->VariationId()); + vars.push_back(varList->GetVariation(i)->VariationId()); } } else @@ -214,7 +214,7 @@ bool EmberGenome(EmberOptions& opt) { if (parser.Aton(token.c_str(), val)) { - if (val < varList.Size()) + if (val < varList->Size()) vars.push_back(static_cast(val)); } } @@ -227,22 +227,22 @@ bool EmberGenome(EmberOptions& opt) { if (parser.Aton(token.c_str(), val)) { - if (val < varList.Size()) + if (val < varList->Size()) noVars.push_back(static_cast(val)); } } //Loop over the novars and set ivars to the complement. - for (i = 0; i < varList.Size(); i++) + for (i = 0; i < varList->Size(); i++) { for (j = 0; j < noVars.size(); j++) { - if (noVars[j] == varList.GetVariation(i)->VariationId()) + if (noVars[j] == varList->GetVariation(i)->VariationId()) break; } if (j == noVars.size()) - vars.push_back(varList.GetVariation(i)->VariationId()); + vars.push_back(varList->GetVariation(i)->VariationId()); } } } diff --git a/Source/EmberTester/EmberTester.cpp b/Source/EmberTester/EmberTester.cpp index 0894c1e..c66226f 100644 --- a/Source/EmberTester/EmberTester.cpp +++ b/Source/EmberTester/EmberTester.cpp @@ -89,7 +89,7 @@ void MakeTestAllVarsRegPrePost(vector>& embers) { uint index = 0; ostringstream ss; - VariationList& varList(VariationList::Instance()); + auto varList = VariationList::Instance(); PaletteList paletteList; QTIsaac rand; paletteList.Add("flam3-palettes.xml"); @@ -118,7 +118,7 @@ void MakeTestAllVarsRegPrePost(vector>& embers) emberNoVars.m_Palette = *paletteList.GetPalette(paletteList.m_DefaultFilename, 0); embers.push_back(emberNoVars); - while (index < varList.RegSize()) + while (index < varList->RegSize()) { /* if (index != eVariationId::VAR_SYNTH) { @@ -127,9 +127,9 @@ void MakeTestAllVarsRegPrePost(vector>& embers) } */ Ember ember1; - unique_ptr> regVar(varList.GetVariationCopy(index, eVariationType::VARTYPE_REG)); - unique_ptr> preVar(varList.GetVariationCopy("pre_" + regVar->Name())); - unique_ptr> postVar(varList.GetVariationCopy("post_" + regVar->Name())); + unique_ptr> regVar(varList->GetVariationCopy(index, eVariationType::VARTYPE_REG)); + unique_ptr> preVar(varList->GetVariationCopy("pre_" + regVar->Name())); + unique_ptr> postVar(varList->GetVariationCopy("post_" + regVar->Name())); ember1.m_FinalRasW = 640; ember1.m_FinalRasH = 480; ember1.m_Quality = 100; @@ -337,12 +337,12 @@ template static vector*> FindVarsWith(vector& stringVec, bool findAll = true) { int index = 0; - VariationList& vl(VariationList::Instance()); + auto vl = VariationList::Instance(); vector*> vec; - while (index < vl.RegSize()) + while (index < vl->RegSize()) { - auto regVar = vl.GetVariation(index, eVariationType::VARTYPE_REG); + auto regVar = vl->GetVariation(index, eVariationType::VARTYPE_REG); if (SearchVar(regVar, stringVec, false)) { @@ -360,10 +360,10 @@ static vector*> FindVarsWith(vector& stringVec, bool findAl bool TestVarCounts() { - VariationList& vlf(VariationList::Instance()); + auto vlf(VariationList::Instance()); #ifdef DO_DOUBLE - VariationList& vld(VariationList::Instance()); - bool success((vlf.Size() == vld.Size()) && (vlf.Size() == size_t(eVariationId::LAST_VAR))); + auto vld(VariationList::Instance()); + bool success((vlf->Size() == vld->Size()) && (vlf->Size() == size_t(eVariationId::LAST_VAR))); #else bool success = true; #endif @@ -371,12 +371,12 @@ bool TestVarCounts() if (!success) { - cout << "Variation list size " << vlf.Size() << " does not equal the max var ID enum " << et(eVariationId::LAST_VAR) << "." << endl; + cout << "Variation list size " << vlf->Size() << " does not equal the max var ID enum " << et(eVariationId::LAST_VAR) << "." << endl; } for (; start < et(eVariationId::LAST_VAR); start++) { - auto var = vlf.GetVariation((eVariationId)start); + auto var = vlf->GetVariation((eVariationId)start); if (!var) { @@ -392,15 +392,15 @@ template bool TestVarUnique() { bool success = true; - VariationList& vl(VariationList::Instance()); + auto vl = VariationList::Instance(); vector ids; vector names; - ids.reserve(vl.Size()); - names.reserve(vl.Size()); + ids.reserve(vl->Size()); + names.reserve(vl->Size()); - for (size_t i = 0; i < vl.Size(); i++) + for (size_t i = 0; i < vl->Size(); i++) { - auto var = vl.GetVariation(i); + auto var = vl->GetVariation(i); if (std::find(ids.begin(), ids.end(), var->VariationId()) != ids.end()) { @@ -580,11 +580,11 @@ bool TestVarEqual(const Variation* var1, const Variation
* var2) bool TestVarPrePostNames() { bool success = true; - VariationList& vlf(VariationList::Instance()); + auto vlf(VariationList::Instance()); - for (size_t i = 0; i < vlf.Size(); i++) + for (size_t i = 0; i < vlf->Size(); i++) { - auto var = vlf.GetVariation(i); + auto var = vlf->GetVariation(i); string name = var->Name(); if (var->VarType() == eVariationType::VARTYPE_REG) @@ -646,11 +646,11 @@ template bool TestVarCopy() { bool success = true; - VariationList& vlf(VariationList::Instance()); + auto vlf(VariationList::Instance()); - for (size_t i = 0; i < vlf.Size(); i++) + for (size_t i = 0; i < vlf->Size(); i++) { - auto var = vlf.GetVariation(i); + auto var = vlf->GetVariation(i); Variation
* destVar = NULL; unique_ptr> copyVar(var->Copy());//Test Copy(). @@ -676,11 +676,11 @@ bool TestVarCopy() bool TestParVars() { bool success = true; - VariationList& vlf(VariationList::Instance()); + auto vlf(VariationList::Instance()); - for (size_t i = 0; i < vlf.ParametricSize(); i++) + for (size_t i = 0; i < vlf->ParametricSize(); i++) { - if (auto parVar = vlf.GetParametricVariation(i)) + if (auto parVar = vlf->GetParametricVariation(i)) { if (parVar->ParamCount() < 1) { @@ -730,19 +730,19 @@ bool TestParVars() bool TestVarRegPrePost() { bool success = true; - VariationList& vlf(VariationList::Instance()); + auto vlf(VariationList::Instance()); - for (size_t i = 0; i < vlf.RegSize(); i++) + for (size_t i = 0; i < vlf->RegSize(); i++) { - auto regVar = vlf.GetVariation(i, eVariationType::VARTYPE_REG); + auto regVar = vlf->GetVariation(i, eVariationType::VARTYPE_REG); if (regVar) { if (regVar->Name().find("dc_") != 0) { string name = regVar->Name(); - auto preVar = vlf.GetVariation("pre_" + name); - auto postVar = vlf.GetVariation("post_" + name); + auto preVar = vlf->GetVariation("pre_" + name); + auto postVar = vlf->GetVariation("post_" + name); if (!preVar) { @@ -782,11 +782,11 @@ bool TestVarRegPrePost() bool TestVarPrecalcUsedCL() { bool success = true; - VariationList& vlf(VariationList::Instance()); + auto vlf(VariationList::Instance()); - for (size_t i = 0; i < vlf.Size(); i++) + for (size_t i = 0; i < vlf->Size(); i++) { - auto var = vlf.GetVariation(i); + auto var = vlf->GetVariation(i); string s = var->OpenCLString(); if (var->NeedPrecalcAngles()) @@ -951,7 +951,7 @@ bool TestVarPrecalcUsedCL() bool TestVarAssignTypes() { bool success = true; - VariationList& vlf(VariationList::Instance()); + auto vlf(VariationList::Instance()); vector vset, vsum; vset.push_back("vIn.x"); vset.push_back("vIn.y"); @@ -972,9 +972,9 @@ bool TestVarAssignTypes() vsum.push_back("precalcAtanxy"); vsum.push_back("precalcAtanyx"); - for (size_t i = 0; i < vlf.Size(); i++) + for (size_t i = 0; i < vlf->Size(); i++) { - auto var = vlf.GetVariation(i); + auto var = vlf->GetVariation(i); string s = var->OpenCLString(); //Only test pre and post. The assign type for regular is ignored, and will always be summed. @@ -1009,7 +1009,7 @@ bool TestVarAssignTypes() bool TestVarAssignVals() { bool success = true; - VariationList& vlf(VariationList::Instance()); + auto vlf(VariationList::Instance()); vector xout, yout, zout; xout.push_back("vOut.x ="); xout.push_back("vOut.x +="); @@ -1027,9 +1027,9 @@ bool TestVarAssignVals() zout.push_back("vOut.z *="); zout.push_back("vOut.z /="); - for (size_t i = 0; i < vlf.Size(); i++) + for (size_t i = 0; i < vlf->Size(); i++) { - auto var = vlf.GetVariation(i); + auto var = vlf->GetVariation(i); if (!SearchVar(var, xout, false)) { @@ -1056,13 +1056,13 @@ bool TestVarAssignVals() bool TestZepsFloor() { bool success = true; - VariationList& vlf(VariationList::Instance()); + auto vlf(VariationList::Instance()); vector zeps; zeps.push_back("Zeps(floor"); - for (size_t i = 0; i < vlf.Size(); i++) + for (size_t i = 0; i < vlf->Size(); i++) { - auto var = vlf.GetVariation(i); + auto var = vlf->GetVariation(i); if (SearchVar(var, zeps, false)) { @@ -1077,16 +1077,16 @@ bool TestZepsFloor() bool TestConstants() { bool success = true; - VariationList& vlf(VariationList::Instance()); + auto vlf(VariationList::Instance()); vector stringVec; stringVec.push_back("2 * M_PI"); stringVec.push_back("2*M_PI"); stringVec.push_back("M_PI*2"); stringVec.push_back("M_PI * 2"); - for (size_t i = 0; i < vlf.Size(); i++) + for (size_t i = 0; i < vlf->Size(); i++) { - auto var = vlf.GetVariation(i); + auto var = vlf->GetVariation(i); if (SearchVar(var, stringVec, false)) { @@ -1101,13 +1101,13 @@ bool TestConstants() bool TestGlobalFuncs() { bool success = true; - VariationList& vlf(VariationList::Instance()); + auto vlf(VariationList::Instance()); vector funcs; FunctionMapper mapper; - for (size_t i = 0; i < vlf.Size(); i++) + for (size_t i = 0; i < vlf->Size(); i++) { - auto var = vlf.GetVariation(i); + auto var = vlf->GetVariation(i); funcs = var->OpenCLGlobalFuncNames(); for (auto& func : funcs) @@ -1130,30 +1130,30 @@ bool TestGlobalFuncs() void PrintAllVars() { uint i = 0; - VariationList& vlf(VariationList::Instance()); + auto vlf(VariationList::Instance()); - while (auto var = vlf.GetVariation(i++)) + while (auto var = vlf->GetVariation(i++)) cout << var->Name() << endl; } void TestXformsInOutPoints() { uint index = 0; - VariationList& varList(VariationList::Instance()); + auto varList(VariationList::Instance()); PaletteList paletteList; QTIsaac rand; paletteList.Add("flam3-palettes.xml"); - while (index < varList.RegSize()) + while (index < varList->RegSize()) { vector> xforms; - unique_ptr> regVar(varList.GetVariationCopy(index, eVariationType::VARTYPE_REG)); + unique_ptr> regVar(varList->GetVariationCopy(index, eVariationType::VARTYPE_REG)); string s = regVar->OpenCLString() + regVar->OpenCLFuncsString(); if (s.find("MwcNext") == string::npos) { - unique_ptr> preVar(varList.GetVariationCopy("pre_" + regVar->Name())); - unique_ptr> postVar(varList.GetVariationCopy("post_" + regVar->Name())); + unique_ptr> preVar(varList->GetVariationCopy("pre_" + regVar->Name())); + unique_ptr> postVar(varList->GetVariationCopy("post_" + regVar->Name())); Xform xform0(0.25f, rand.Frand01(), rand.Frand11(), 1, rand.Frand11(), rand.Frand11(), rand.Frand11(), rand.Frand11(), rand.Frand11(), rand.Frand11()); Xform xform1(0.25f, rand.Frand01(), rand.Frand11(), 1, rand.Frand11(), rand.Frand11(), rand.Frand11(), rand.Frand11(), rand.Frand11(), rand.Frand11()); Xform xform2(0.25f, rand.Frand01(), rand.Frand11(), 1, rand.Frand11(), rand.Frand11(), rand.Frand11(), rand.Frand11(), rand.Frand11(), rand.Frand11()); @@ -1257,13 +1257,13 @@ void TestVarTime() IteratorHelper helper; QTIsaac rand; vector> times; - times.reserve(vlf.RegSize()); + times.reserve(vlf->RegSize()); - while (i < vlf.RegSize()) + while (i < vlf->RegSize()) { double sum = 0; Xform xform; - Variation* var = vlf.GetVariationCopy(i, eVariationType::VARTYPE_REG); + Variation* var = vlf->GetVariationCopy(i, eVariationType::VARTYPE_REG); xform.AddVariation(var); for (int iter = 0; iter < iters; iter++) @@ -1365,18 +1365,18 @@ void TestVarsSimilar() IteratorHelper helper; QTIsaac rand; vector> diffs; - diffs.reserve(vlf.RegSize()); + diffs.reserve(vlf->RegSize()); - while (i < vlf.RegSize()) + while (i < vlf->RegSize()) { double diff = 0, highest = TMAX; Xform xform; - Variation* var = vlf.GetVariationCopy(i, eVariationType::VARTYPE_REG); + Variation* var = vlf->GetVariationCopy(i, eVariationType::VARTYPE_REG); pair match("", TMAX); compIndex = 0; xform.AddVariation(var); - while (compIndex < vlf.RegSize()) + while (compIndex < vlf->RegSize()) { if (compIndex == i) { @@ -1386,7 +1386,7 @@ void TestVarsSimilar() double sum = 0, xdiff = 0, ydiff = 0, zdiff = 0; Xform xformComp; - Variation* varComp = vlf.GetVariationCopy(compIndex, eVariationType::VARTYPE_REG); + Variation* varComp = vlf->GetVariationCopy(compIndex, eVariationType::VARTYPE_REG); xformComp.AddVariation(varComp); ParametricVariation* parVar = dynamic_cast*>(var); ParametricVariation* parVarComp = dynamic_cast*>(varComp); @@ -1536,11 +1536,11 @@ void TestCpuGpuResults(size_t platform, size_t device) RendererCL renderer(devices); points.resize(renderer.TotalIterKernelCount()); - while (i < vlf.RegSize()) + while (i < vlf->RegSize()) { bool bad = false; double sum = 0; - Variation* var = vlf.GetVariation(i, eVariationType::VARTYPE_REG); + Variation* var = vlf->GetVariation(i, eVariationType::VARTYPE_REG); string s = var->OpenCLString() + var->OpenCLFuncsString(); if (s.find("MwcNext") != string::npos) @@ -1631,7 +1631,7 @@ void TestGpuVectorRead(size_t platform, size_t device) vector> devices{ std::make_pair(platform, device) }; RendererCL renderer(devices); points.resize(renderer.TotalIterKernelCount()); - Variation* var = vlf.GetVariation(eVariationId::VAR_LINEAR); + Variation* var = vlf->GetVariation(eVariationId::VAR_LINEAR); bool newAlloc = false; Point p, p2; Ember ember; @@ -2132,12 +2132,12 @@ int _tmain(int argc, _TCHAR* argv[]) TestCasting(); t.Toc("TestCasting()"); t.Tic(); - VariationList& vlf(VariationList::Instance()); + auto vlf(VariationList::Instance()); t.Toc("Creating VariationList"); - cout << "There are " << vlf.Size() << " variations present." << endl; + cout << "There are " << vlf->Size() << " variations present." << endl; #ifdef DO_DOUBLE t.Tic(); - VariationList& vld(VariationList::Instance()); + auto vld(VariationList::Instance()); t.Toc("Creating VariationList"); #endif t.Tic(); diff --git a/Source/Fractorium/FinalRenderDialog.cpp b/Source/Fractorium/FinalRenderDialog.cpp index 52522bd..0985bfe 100644 --- a/Source/Fractorium/FinalRenderDialog.cpp +++ b/Source/Fractorium/FinalRenderDialog.cpp @@ -400,7 +400,7 @@ void FractoriumFinalRenderDialog::OnDoSequenceCheckBoxStateChanged(int state) /// Ignored void FractoriumFinalRenderDialog::OnCurrentSpinChanged(int d) { - m_Controller->SetEmber(d - 1); + m_Controller->SetEmber(d - 1, false); m_Controller->SyncCurrentToGui(); SetMemory(); } @@ -743,7 +743,7 @@ bool FractoriumFinalRenderDialog::CreateControllerFromGUI(bool createRenderer) if (m_Controller.get()) { m_Controller->SetEmberFile(efd);//Convert float to double or set double verbatim; - m_Controller->SetEmber(index); + m_Controller->SetEmber(index, false); } } diff --git a/Source/Fractorium/FinalRenderEmberController.cpp b/Source/Fractorium/FinalRenderEmberController.cpp index 9990ef3..8611fab 100644 --- a/Source/Fractorium/FinalRenderEmberController.cpp +++ b/Source/Fractorium/FinalRenderEmberController.cpp @@ -406,7 +406,7 @@ template void FinalRenderEmberController::CopyEmberFile(EmberFil ///
/// The index in the file from which to retrieve the ember template -void FinalRenderEmberController::SetEmber(size_t index) +void FinalRenderEmberController::SetEmber(size_t index, bool verbatim) { if (index < m_EmberFile.Size()) { diff --git a/Source/Fractorium/FinalRenderEmberController.h b/Source/Fractorium/FinalRenderEmberController.h index 9a46daf..05e21e3 100644 --- a/Source/Fractorium/FinalRenderEmberController.h +++ b/Source/Fractorium/FinalRenderEmberController.h @@ -109,7 +109,7 @@ public: virtual void SetEmberFile(const EmberFile& emberFile) override; virtual void CopyEmberFile(EmberFile& emberFile, std::function& ember)> perEmberOperation/* = [&](Ember& ember) { }*/) override; #endif - virtual void SetEmber(size_t index) override; + virtual void SetEmber(size_t index, bool verbatim) override; virtual bool Render() override; virtual bool CreateRenderer(eRendererType renderType, const vector>& devices, bool shared = true) override; virtual int ProgressFunc(Ember& ember, void* foo, double fraction, int stage, double etaMs) override; diff --git a/Source/Fractorium/FractoriumEmberController.cpp b/Source/Fractorium/FractoriumEmberController.cpp index 2133b1f..4a8a8a4 100644 --- a/Source/Fractorium/FractoriumEmberController.cpp +++ b/Source/Fractorium/FractoriumEmberController.cpp @@ -134,7 +134,7 @@ FractoriumEmberController::~FractoriumEmberController() { } /// These are used to preserve the current ember/file when switching between renderers. /// Note that some precision will be lost when going from double to float. ///
-template void FractoriumEmberController::SetEmber(const Ember& ember, bool verbatim) { SetEmberPrivate(ember, verbatim); } +template void FractoriumEmberController::SetEmber(const Ember& ember, bool verbatim, bool updatePointer) { SetEmberPrivate(ember, verbatim, updatePointer); } template void FractoriumEmberController::CopyEmber(Ember& ember, std::function& ember)> perEmberOperation) { ember = m_Ember; perEmberOperation(ember); } template void FractoriumEmberController::SetEmberFile(const EmberFile& emberFile) { m_EmberFile = emberFile; } template void FractoriumEmberController::CopyEmberFile(EmberFile& emberFile, std::function& ember)> perEmberOperation) @@ -146,7 +146,7 @@ template void FractoriumEmberController::CopyEmberFile(EmberFile template void FractoriumEmberController::SetTempPalette(const Palette& palette) { m_TempPalette = palette; } template void FractoriumEmberController::CopyTempPalette(Palette& palette) { palette = m_TempPalette; } #ifdef DO_DOUBLE -template void FractoriumEmberController::SetEmber(const Ember& ember, bool verbatim) { SetEmberPrivate(ember, verbatim); } +template void FractoriumEmberController::SetEmber(const Ember& ember, bool verbatim, bool updatePointer) { SetEmberPrivate(ember, verbatim, updatePointer); } template void FractoriumEmberController::CopyEmber(Ember& ember, std::function& ember)> perEmberOperation) { ember = m_Ember; perEmberOperation(ember); } template void FractoriumEmberController::SetEmberFile(const EmberFile& emberFile) { m_EmberFile = emberFile; } template void FractoriumEmberController::CopyEmberFile(EmberFile& emberFile, std::function& ember)> perEmberOperation) @@ -173,8 +173,9 @@ void FractoriumEmberController::ConstrainDimensions(Ember& ember) /// Resets the rendering process. ///
/// The index in the file from which to retrieve the ember +/// If true, do not overwrite temporal samples, quality or supersample value, else overwrite. template -void FractoriumEmberController::SetEmber(size_t index) +void FractoriumEmberController::SetEmber(size_t index, bool verbatim) { if (index < m_EmberFile.Size()) { @@ -188,7 +189,7 @@ void FractoriumEmberController::SetEmber(size_t index) } ClearUndo(); - SetEmber(*m_EmberFile.Get(index)); + SetEmber(*m_EmberFile.Get(index), verbatim, true); } } @@ -318,9 +319,10 @@ void FractoriumEmberController::UpdateXform(std::function*)> fu ///
/// The ember to set as the current /// If true, do not overwrite temporal samples, quality or supersample value, else overwrite. +/// If true, update the current ember pointer to the address of the one passed in. template template -void FractoriumEmberController::SetEmberPrivate(const Ember& ember, bool verbatim) +void FractoriumEmberController::SetEmberPrivate(const Ember& ember, bool verbatim, bool updatePointer) { if (ember.m_Name != m_Ember.m_Name) m_LastSaveCurrent = ""; @@ -328,7 +330,9 @@ void FractoriumEmberController::SetEmberPrivate(const Ember& ember, bool v size_t w = m_Ember.m_FinalRasW;//Cache values for use below. size_t h = m_Ember.m_FinalRasH; m_Ember = ember; - m_EmberFilePointer = &ember; + + if (updatePointer) + m_EmberFilePointer = &ember; if (!verbatim) { diff --git a/Source/Fractorium/FractoriumEmberController.h b/Source/Fractorium/FractoriumEmberController.h index 70f7cf2..6e6eaf6 100644 --- a/Source/Fractorium/FractoriumEmberController.h +++ b/Source/Fractorium/FractoriumEmberController.h @@ -52,21 +52,21 @@ public: virtual ~FractoriumEmberControllerBase(); //Embers. - virtual void SetEmber(const Ember& ember, bool verbatim = false) { } + virtual void SetEmber(const Ember& ember, bool verbatim, bool updatePointer) { } virtual void CopyEmber(Ember& ember, std::function& ember)> perEmberOperation/* = [&](Ember& ember) { }*/) { }//Uncomment default lambdas once LLVM fixes a crash in their compiler with default lambda parameters.//TODO virtual void SetEmberFile(const EmberFile& emberFile) { } virtual void CopyEmberFile(EmberFile& emberFile, std::function& ember)> perEmberOperation/* = [&](Ember& ember) { }*/) { } virtual void SetTempPalette(const Palette& palette) { } virtual void CopyTempPalette(Palette& palette) { } #ifdef DO_DOUBLE - virtual void SetEmber(const Ember& ember, bool verbatim = false) { } + virtual void SetEmber(const Ember& ember, bool verbatim, bool updatePointer) { } virtual void CopyEmber(Ember& ember, std::function& ember)> perEmberOperation/* = [&](Ember& ember) { }*/) { } virtual void SetEmberFile(const EmberFile& emberFile) { } virtual void CopyEmberFile(EmberFile& emberFile, std::function& ember)> perEmberOperation/* = [&](Ember& ember) { }*/) { } virtual void SetTempPalette(const Palette& palette) { } virtual void CopyTempPalette(Palette& palette) { } #endif - virtual void SetEmber(size_t index) { } + virtual void SetEmber(size_t index, bool verbatim) { } //virtual void Clear() { } virtual void AddXform() { } virtual void AddLinkedXform() { } @@ -95,7 +95,7 @@ public: virtual void OpenAndPrepFiles(const QStringList& filenames, bool append) { } virtual void SaveCurrentAsXml() { } virtual void SaveEntireFileAsXml() { } - virtual void SaveCurrentToOpenedFile() { } + virtual uint SaveCurrentToOpenedFile() { return 0; } virtual void Undo() { }//Edit. virtual void Redo() { } virtual void CopyXml() { } @@ -290,21 +290,21 @@ public: virtual ~FractoriumEmberController(); //Embers. - virtual void SetEmber(const Ember& ember, bool verbatim = false) override; + virtual void SetEmber(const Ember& ember, bool verbatim, bool updatePointer) override; virtual void CopyEmber(Ember& ember, std::function& ember)> perEmberOperation/* = [&](Ember& ember) { }*/) override; virtual void SetEmberFile(const EmberFile& emberFile) override; virtual void CopyEmberFile(EmberFile& emberFile, std::function& ember)> perEmberOperation/* = [&](Ember& ember) { }*/) override; virtual void SetTempPalette(const Palette& palette) override; virtual void CopyTempPalette(Palette& palette) override; #ifdef DO_DOUBLE - virtual void SetEmber(const Ember& ember, bool verbatim = false) override; + virtual void SetEmber(const Ember& ember, bool verbatim, bool updatePointer) override; virtual void CopyEmber(Ember& ember, std::function& ember)> perEmberOperation/* = [&](Ember& ember) { }*/) override; virtual void SetEmberFile(const EmberFile& emberFile) override; virtual void CopyEmberFile(EmberFile& emberFile, std::function& ember)> perEmberOperation/* = [&](Ember& ember) { }*/) override; virtual void SetTempPalette(const Palette& palette) override; virtual void CopyTempPalette(Palette& palette) override; #endif - virtual void SetEmber(size_t index) override; + virtual void SetEmber(size_t index, bool verbatim) override; //virtual void Clear() override { } virtual void AddXform() override; virtual void AddLinkedXform() override; @@ -336,7 +336,7 @@ public: virtual void OpenAndPrepFiles(const QStringList& filenames, bool append) override; virtual void SaveCurrentAsXml() override; virtual void SaveEntireFileAsXml() override; - virtual void SaveCurrentToOpenedFile() override; + virtual uint SaveCurrentToOpenedFile() override; virtual void Undo() override; virtual void Redo() override; virtual void CopyXml() override; @@ -472,7 +472,7 @@ public: private: //Embers. void ApplyXmlSavingTemplate(Ember& ember); - template void SetEmberPrivate(const Ember& ember, bool verbatim); + template void SetEmberPrivate(const Ember& ember, bool verbatim, bool updatePointer); //Params. void ParamsToEmber(Ember& ember); @@ -509,7 +509,7 @@ private: Xform m_CopiedFinalXform; Palette m_TempPalette; PaletteList m_PaletteList; - VariationList& m_VariationList; + shared_ptr> m_VariationList; unique_ptr> m_SheepTools; unique_ptr> m_GLController; unique_ptr> m_PreviewRenderer = make_unique>(); diff --git a/Source/Fractorium/FractoriumLibrary.cpp b/Source/Fractorium/FractoriumLibrary.cpp index 79ad94e..fe50746 100644 --- a/Source/Fractorium/FractoriumLibrary.cpp +++ b/Source/Fractorium/FractoriumLibrary.cpp @@ -243,7 +243,7 @@ void FractoriumEmberController::EmberTreeItemDoubleClicked(QTreeWidgetItem* i { //qDebug() << "Setting current ember to: " << QString::fromStdString(emberItem->GetEmber()->m_Name); ClearUndo(); - SetEmber(*emberItem->GetEmber()); + SetEmber(*emberItem->GetEmber(), false, true); } } diff --git a/Source/Fractorium/FractoriumMenus.cpp b/Source/Fractorium/FractoriumMenus.cpp index b16eca6..d0c4554 100644 --- a/Source/Fractorium/FractoriumMenus.cpp +++ b/Source/Fractorium/FractoriumMenus.cpp @@ -76,7 +76,7 @@ void FractoriumEmberController::NewFlock(size_t count) void Fractorium::OnActionNewFlock(bool checked) { m_Controller->NewFlock(m_Settings->RandomCount()); - m_Controller->SetEmber(0); + m_Controller->SetEmber(0, false); } /// @@ -102,7 +102,7 @@ void FractoriumEmberController::NewEmptyFlameInCurrentFile() m_EmberFile.m_Embers.push_back(ember);//Will invalidate the pointers contained in the EmberTreeWidgetItems, UpdateLibraryTree() will resync. m_EmberFile.MakeNamesUnique(); UpdateLibraryTree(); - SetEmber(m_EmberFile.Size() - 1); + SetEmber(m_EmberFile.Size() - 1, false); } void Fractorium::OnActionNewEmptyFlameInCurrentFile(bool checked) { m_Controller->NewEmptyFlameInCurrentFile(); } @@ -124,7 +124,7 @@ void FractoriumEmberController::NewRandomFlameInCurrentFile() m_EmberFile.m_Embers.push_back(ember);//Will invalidate the pointers contained in the EmberTreeWidgetItems, UpdateLibraryTree() will resync. m_EmberFile.MakeNamesUnique(); UpdateLibraryTree(); - SetEmber(m_EmberFile.Size() - 1); + SetEmber(m_EmberFile.Size() - 1, false); } void Fractorium::OnActionNewRandomFlameInCurrentFile(bool checked) { m_Controller->NewRandomFlameInCurrentFile(); } @@ -144,7 +144,7 @@ void FractoriumEmberController::CopyFlameInCurrentFile() m_EmberFile.m_Embers.push_back(ember);//Will invalidate the pointers contained in the EmberTreeWidgetItems, UpdateLibraryTree() will resync. m_EmberFile.MakeNamesUnique(); UpdateLibraryTree(); - SetEmber(m_EmberFile.Size() - 1); + SetEmber(m_EmberFile.Size() - 1, false); } void Fractorium::OnActionCopyFlameInCurrentFile(bool checked) { m_Controller->CopyFlameInCurrentFile(); } @@ -231,7 +231,7 @@ void FractoriumEmberController::OpenAndPrepFiles(const QStringList& filenames FillLibraryTree(append ? previousSize - 1 : 0); ClearUndo(); - SetEmber(previousSize); + SetEmber(previousSize, false); } } @@ -365,37 +365,45 @@ void Fractorium::OnActionSaveCurrentScreen(bool checked) /// /// Save the current ember back to its position in the opened file. +/// This will not take any action if the previews are still rendering because +/// this writes to memory the preview renderer might be reading, and also stops the +/// preview renderer. /// This does not save to disk. /// template -void FractoriumEmberController::SaveCurrentToOpenedFile() +uint FractoriumEmberController::SaveCurrentToOpenedFile() { uint i = 0; bool fileFound = false; - for (auto& it : m_EmberFile.m_Embers) + if (!m_PreviewRunning) { - if (&it == m_EmberFilePointer)//Just compare memory addresses. + for (auto& it : m_EmberFile.m_Embers) { - it = m_Ember;//Save it to the opened file in memory. - fileFound = true; - break; + if (&it == m_EmberFilePointer)//Just compare memory addresses. + { + it = m_Ember;//Save it to the opened file in memory. + fileFound = true; + break; + } + + i++; } - i++; + if (!fileFound) + { + StopPreviewRender(); + m_EmberFile.m_Embers.push_back(m_Ember); + m_EmberFile.MakeNamesUnique(); + UpdateLibraryTree(); + } + else + { + RenderPreviews(i, i + 1); + } } - if (!fileFound) - { - StopPreviewRender(); - m_EmberFile.m_Embers.push_back(m_Ember); - m_EmberFile.MakeNamesUnique(); - UpdateLibraryTree(); - } - else - { - RenderPreviews(i, i + 1); - } + return i; } /// @@ -419,9 +427,7 @@ void FractoriumEmberController::Undo() int index = m_Ember.GetTotalXformIndex(CurrentXform()); m_LastEditWasUndoRedo = true; m_UndoIndex = std::max(0u, m_UndoIndex - 1u); - auto temp = m_EmberFilePointer;//m_EmberFilePointer will be set to point to whatever is passed in, which we don't want since it's coming from the undo list... - SetEmber(m_UndoList[m_UndoIndex], true); - m_EmberFilePointer = temp;//...keep it pointing to the original one in the file. + SetEmber(m_UndoList[m_UndoIndex], true, false);//Don't update pointer because it's coming from the undo list... m_EditState = eEditUndoState::UNDO_REDO; if (index >= 0) @@ -445,9 +451,7 @@ void FractoriumEmberController::Redo() int index = m_Ember.GetTotalXformIndex(CurrentXform()); m_LastEditWasUndoRedo = true; m_UndoIndex = std::min(m_UndoIndex + 1, m_UndoList.size() - 1); - auto temp = m_EmberFilePointer; - SetEmber(m_UndoList[m_UndoIndex], true); - m_EmberFilePointer = temp;//...keep it pointing to the original one in the file. + SetEmber(m_UndoList[m_UndoIndex], true, false); m_EditState = eEditUndoState::UNDO_REDO; if (index >= 0) @@ -552,7 +556,7 @@ void FractoriumEmberController::PasteXmlAppend() m_EmberFile.MakeNamesUnique(); UpdateLibraryTree(); - SetEmber(previousSize); + SetEmber(previousSize, false); } } @@ -611,7 +615,7 @@ void FractoriumEmberController::PasteXmlOver() m_EmberFile.MakeNamesUnique(); FillLibraryTree(); - SetEmber(0); + SetEmber(0, false); } void Fractorium::OnActionPasteXmlOver(bool checked) { m_Controller->PasteXmlOver(); } diff --git a/Source/Fractorium/FractoriumRender.cpp b/Source/Fractorium/FractoriumRender.cpp index c3a4822..fe42746 100644 --- a/Source/Fractorium/FractoriumRender.cpp +++ b/Source/Fractorium/FractoriumRender.cpp @@ -455,7 +455,7 @@ bool FractoriumEmberController::Render() gl->update(); if (ProcessState() == eProcessState::ACCUM_DONE) - SaveCurrentToOpenedFile(); + SaveCurrentToOpenedFile();//Will not save if the previews are still rendering. //Uncomment for debugging kernel build and execution errors. //m_Fractorium->ui.InfoRenderingTextEdit->setText(QString::fromStdString(m_Fractorium->m_Wrapper.DumpInfo())); @@ -671,6 +671,7 @@ bool Fractorium::CreateControllerFromOptions() auto blur = m_PaletteBlurSpin->value(); auto freq = m_PaletteFrequencySpin->value(); double scale; + uint current = 0; #ifdef DO_DOUBLE Ember ed; EmberFile efd; @@ -686,6 +687,7 @@ bool Fractorium::CreateControllerFromOptions() if (m_Controller.get()) { scale = m_Controller->LockedScale(); + current = m_Controller->SaveCurrentToOpenedFile(); m_Controller->StopPreviewRender();//Must stop any previews first, else changing controllers will crash the program. m_Controller->CopyTempPalette(tempPalette);//Convert float to double or save double verbatim; //Replace below with this once LLVM fixes a crash in their compiler with default lambda parameters.//TODO @@ -713,8 +715,8 @@ bool Fractorium::CreateControllerFromOptions() if (m_Controller.get()) { ed.m_Palette = tempPalette;//Restore base temp palette. Adjustments will be then be applied and stored back in in m_Ember.m_Palette below. - m_Controller->SetEmber(ed);//Convert float to double or set double verbatim. This will assign m_Ember.m_Palette (which was just tempPalette) to m_TempPalette. m_Controller->SetEmberFile(efd); + m_Controller->SetEmber(current, true); m_Controller->LockedScale(scale); //Setting these and updating the GUI overwrites the work of clearing them done in SetEmber() above. //It's a corner case, but doesn't seem to matter. diff --git a/Source/Fractorium/FractoriumXforms.cpp b/Source/Fractorium/FractoriumXforms.cpp index 6800ab8..c9e9df4 100644 --- a/Source/Fractorium/FractoriumXforms.cpp +++ b/Source/Fractorium/FractoriumXforms.cpp @@ -279,7 +279,7 @@ void FractoriumEmberController::AddFinalXform() Update([&]() { Xform final; - final.AddVariation(m_VariationList.GetVariationCopy(eVariationId::VAR_LINEAR));//Just a placeholder so other parts of the code don't see it as being empty. + final.AddVariation(m_VariationList->GetVariationCopy(eVariationId::VAR_LINEAR));//Just a placeholder so other parts of the code don't see it as being empty. m_Ember.SetFinalXform(final); int index = int(m_Ember.TotalXformCount() - 1);//Set index to the last item. FillXforms(index); diff --git a/Source/Fractorium/FractoriumXformsVariations.cpp b/Source/Fractorium/FractoriumXformsVariations.cpp index e4acdda..206559a 100644 --- a/Source/Fractorium/FractoriumXformsVariations.cpp +++ b/Source/Fractorium/FractoriumXformsVariations.cpp @@ -84,8 +84,8 @@ void FractoriumEmberController::FilteredVariations() m_FilteredVariations.clear(); m_FilteredVariations.reserve(map.size()); - for (auto i = 0; i < m_VariationList.Size(); i++) - if (auto var = m_VariationList.GetVariation(i)) + for (auto i = 0; i < m_VariationList->Size(); i++) + if (auto var = m_VariationList->GetVariation(i)) if (map.contains(var->Name().c_str()) && map[var->Name().c_str()].toBool()) m_FilteredVariations.push_back(var->VariationId()); } @@ -107,9 +107,9 @@ void FractoriumEmberController::SetupVariationsTree() tree->clear(); tree->blockSignals(true); - for (size_t i = 0; i < m_VariationList.Size(); i++) + for (size_t i = 0; i < m_VariationList->Size(); i++) { - auto var = m_VariationList.GetVariation(i); + auto var = m_VariationList->GetVariation(i); auto parVar = dynamic_cast*>(var); //First add the variation, with a spinner for its weight. auto item = new VariationTreeWidgetItem(var->VariationId(), tree); @@ -206,7 +206,7 @@ void FractoriumEmberController::VariationSpinBoxValueChanged(double d)//Would { UpdateXform([&](Xform* xform) { - auto var = m_VariationList.GetVariation(sender->GetVariationId());//The variation attached to the sender, for reference only. + auto var = m_VariationList->GetVariation(sender->GetVariationId());//The variation attached to the sender, for reference only. auto parVar = dynamic_cast*>(var);//The parametric cast of that variation. auto xformVar = xform->GetVariationById(var->VariationId());//The corresponding variation in the currently selected xform. auto widgetItem = sender->WidgetItem(); @@ -294,7 +294,7 @@ void FractoriumEmberController::FillVariationTreeWithXform(Xform* xform) auto item = dynamic_cast(tree->topLevelItem(i)); auto var = xform->GetVariationById(item->Id());//See if this variation in the tree was contained in the xform. auto parVar = dynamic_cast*>(var);//Attempt cast to parametric variation for later. - auto origParVar = dynamic_cast*>(m_VariationList.GetVariation(item->Id())); + auto origParVar = dynamic_cast*>(m_VariationList->GetVariation(item->Id())); if (auto spinBox = dynamic_cast(tree->itemWidget(item, 1)))//Get the widget for the item, and cast the widget to the VariationTreeDoubleSpinBox type. { diff --git a/Source/Fractorium/Main.cpp b/Source/Fractorium/Main.cpp index 308f645..4eb27cd 100644 --- a/Source/Fractorium/Main.cpp +++ b/Source/Fractorium/Main.cpp @@ -27,6 +27,8 @@ int main(int argc, char* argv[]) putenv(const_cast("GPU_MAX_ALLOC_PERCENT=100")); #endif int rv = -1; + auto vlf = VariationList::Instance();//Create two instances that will stay alive until this function exits. + auto vld = VariationList::Instance();//No further creations should occur after this. try { diff --git a/Source/Fractorium/VariationsDialog.cpp b/Source/Fractorium/VariationsDialog.cpp index dbc8b58..d827785 100644 --- a/Source/Fractorium/VariationsDialog.cpp +++ b/Source/Fractorium/VariationsDialog.cpp @@ -128,26 +128,26 @@ void FractoriumVariationsDialog::OnSelectNoneButtonClicked(bool checked) void FractoriumVariationsDialog::Populate() { auto table = ui.VariationsTable; - int size = int(std::max(std::max(m_VariationList.RegSize(), m_VariationList.PreSize()), m_VariationList.PostSize())); + int size = int(std::max(std::max(m_VariationList->RegSize(), m_VariationList->PreSize()), m_VariationList->PostSize())); table->setRowCount(size); for (auto i = 0; i < size; i++) { - if (auto pre = m_VariationList.GetVariation(i, eVariationType::VARTYPE_PRE)) + if (auto pre = m_VariationList->GetVariation(i, eVariationType::VARTYPE_PRE)) { auto cb = new QTableWidgetItem(pre->Name().c_str()); table->setItem(i, 0, cb); SetCheckFromMap(cb, pre); } - if (auto reg = m_VariationList.GetVariation(i, eVariationType::VARTYPE_REG)) + if (auto reg = m_VariationList->GetVariation(i, eVariationType::VARTYPE_REG)) { auto cb = new QTableWidgetItem(reg->Name().c_str()); table->setItem(i, 1, cb); SetCheckFromMap(cb, reg); } - if (auto post = m_VariationList.GetVariation(i, eVariationType::VARTYPE_POST)) + if (auto post = m_VariationList->GetVariation(i, eVariationType::VARTYPE_POST)) { auto cb = new QTableWidgetItem(post->Name().c_str()); table->setItem(i, 2, cb); @@ -209,7 +209,7 @@ void FractoriumVariationsDialog::DataToGui() { ForEachCell([&](QTableWidgetItem * cb) { - if (auto var = m_VariationList.GetVariation(cb->text().toStdString())) + if (auto var = m_VariationList->GetVariation(cb->text().toStdString())) SetCheckFromMap(cb, var); }); } @@ -221,7 +221,7 @@ void FractoriumVariationsDialog::GuiToData() { ForEachCell([&](QTableWidgetItem * cb) { - if (auto var = m_VariationList.GetVariation(cb->text().toStdString())) + if (auto var = m_VariationList->GetVariation(cb->text().toStdString())) m_Vars[cb->text()] = (cb->checkState() == Qt::Checked); }); } diff --git a/Source/Fractorium/VariationsDialog.h b/Source/Fractorium/VariationsDialog.h index 3297e79..20e0f0e 100644 --- a/Source/Fractorium/VariationsDialog.h +++ b/Source/Fractorium/VariationsDialog.h @@ -41,7 +41,7 @@ private: void GuiToData(); void Populate(); void SetCheckFromMap(QTableWidgetItem* cb, const Variation* var); - VariationList& m_VariationList; + shared_ptr> m_VariationList; QMap m_Vars; FractoriumSettings* m_Settings; Ui::VariationsDialog ui;