Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src/Shiny
diff options
context:
space:
mode:
Diffstat (limited to 'src/Shiny')
-rw-r--r--src/Shiny/CMakeLists.txt25
-rw-r--r--src/Shiny/Shiny.h36
-rw-r--r--src/Shiny/ShinyConfig.h61
-rw-r--r--src/Shiny/ShinyData.h102
-rw-r--r--src/Shiny/ShinyMacros.h281
-rw-r--r--src/Shiny/ShinyManager.c445
-rw-r--r--src/Shiny/ShinyManager.h263
-rw-r--r--src/Shiny/ShinyNode.c129
-rw-r--r--src/Shiny/ShinyNode.h133
-rw-r--r--src/Shiny/ShinyNodePool.c77
-rw-r--r--src/Shiny/ShinyNodePool.h67
-rw-r--r--src/Shiny/ShinyNodeState.c108
-rw-r--r--src/Shiny/ShinyNodeState.h56
-rw-r--r--src/Shiny/ShinyOutput.c189
-rw-r--r--src/Shiny/ShinyOutput.h68
-rw-r--r--src/Shiny/ShinyPrereqs.h138
-rw-r--r--src/Shiny/ShinyTools.c116
-rw-r--r--src/Shiny/ShinyTools.h57
-rw-r--r--src/Shiny/ShinyVersion.h37
-rw-r--r--src/Shiny/ShinyZone.c201
-rw-r--r--src/Shiny/ShinyZone.h91
21 files changed, 2680 insertions, 0 deletions
diff --git a/src/Shiny/CMakeLists.txt b/src/Shiny/CMakeLists.txt
new file mode 100644
index 000000000..8be7592ae
--- /dev/null
+++ b/src/Shiny/CMakeLists.txt
@@ -0,0 +1,25 @@
+project(Shiny)
+cmake_minimum_required(VERSION 2.6)
+
+add_library(Shiny STATIC
+ Shiny.h
+ ShinyConfig.h
+ ShinyData.h
+ ShinyMacros.h
+ ShinyManager.c
+ ShinyManager.h
+ ShinyNode.c
+ ShinyNode.h
+ ShinyNodePool.c
+ ShinyNodePool.h
+ ShinyNodeState.c
+ ShinyNodeState.h
+ ShinyOutput.c
+ ShinyOutput.h
+ ShinyPrereqs.h
+ ShinyTools.c
+ ShinyTools.h
+ ShinyVersion.h
+ ShinyZone.c
+ ShinyZone.h
+)
diff --git a/src/Shiny/Shiny.h b/src/Shiny/Shiny.h
new file mode 100644
index 000000000..a2905aef0
--- /dev/null
+++ b/src/Shiny/Shiny.h
@@ -0,0 +1,36 @@
+/*
+The MIT License
+
+Copyright (c) 2007-2010 Aidin Abedi http://code.google.com/p/shinyprofiler/
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#ifndef SHINY_H
+#define SHINY_H
+
+/*---------------------------------------------------------------------------*/
+
+#include "ShinyMacros.h"
+
+#ifdef SLIC3R_PROFILE
+#include "ShinyManager.h"
+#endif /* SLIC3R_PROFILE */
+
+#endif /* SHINY_H */
diff --git a/src/Shiny/ShinyConfig.h b/src/Shiny/ShinyConfig.h
new file mode 100644
index 000000000..54c632151
--- /dev/null
+++ b/src/Shiny/ShinyConfig.h
@@ -0,0 +1,61 @@
+/*
+The MIT License
+
+Copyright (c) 2007-2010 Aidin Abedi http://code.google.com/p/shinyprofiler/
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#ifndef SHINY_CONFIG_H
+#define SHINY_CONFIG_H
+
+
+/*---------------------------------------------------------------------------*/
+
+/* if SHINY_LOOKUP_RATE is defined to TRUE then Shiny will record the success of its hash function. This is useful for debugging. Default is FALSE.
+ */
+#ifndef SHINY_LOOKUP_RATE
+// #define SHINY_LOOKUP_RATE FALSE
+#endif
+
+/* if SHINY_HAS_ENABLED is defined to TRUE then Shiny can be enabled and disabled at runtime. TODO: bla bla...
+ */
+#ifndef SHINY_HAS_ENABLED
+// #define SHINY_HAS_ENABLED FALSE
+#endif
+
+/* TODO:
+ */
+#define SHINY_OUTPUT_MODE_FLAT 0x1
+
+/* TODO:
+ */
+#define SHINY_OUTPUT_MODE_TREE 0x2
+
+/* TODO:
+ */
+#define SHINY_OUTPUT_MODE_BOTH 0x3
+
+/* TODO:
+ */
+#ifndef SHINY_OUTPUT_MODE
+#define SHINY_OUTPUT_MODE SHINY_OUTPUT_MODE_BOTH
+#endif
+
+#endif /* SHINY_CONFIG_H */
diff --git a/src/Shiny/ShinyData.h b/src/Shiny/ShinyData.h
new file mode 100644
index 000000000..d75d4f5bf
--- /dev/null
+++ b/src/Shiny/ShinyData.h
@@ -0,0 +1,102 @@
+/*
+The MIT License
+
+Copyright (c) 2007-2010 Aidin Abedi http://code.google.com/p/shinyprofiler/
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#ifndef SHINY_DATA_H
+#define SHINY_DATA_H
+
+#include "ShinyPrereqs.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*---------------------------------------------------------------------------*/
+
+typedef struct {
+ uint32_t entryCount;
+ shinytick_t selfTicks;
+} ShinyLastData;
+
+
+/*---------------------------------------------------------------------------*/
+
+typedef struct {
+ shinytick_t cur;
+ float avg;
+} ShinyTickData;
+
+typedef struct {
+ uint32_t cur;
+ float avg;
+} ShinyCountData;
+
+typedef struct {
+ ShinyCountData entryCount;
+ ShinyTickData selfTicks;
+ ShinyTickData childTicks;
+} ShinyData;
+
+SHINY_INLINE shinytick_t ShinyData_totalTicksCur(const ShinyData *self) {
+ return self->selfTicks.cur + self->childTicks.cur;
+}
+
+SHINY_INLINE float ShinyData_totalTicksAvg(const ShinyData *self) {
+ return self->selfTicks.avg + self->childTicks.avg;
+}
+
+SHINY_INLINE void ShinyData_computeAverage(ShinyData *self, float a_damping) {
+ self->entryCount.avg = self->entryCount.cur +
+ a_damping * (self->entryCount.avg - self->entryCount.cur);
+ self->selfTicks.avg = self->selfTicks.cur +
+ a_damping * (self->selfTicks.avg - self->selfTicks.cur);
+ self->childTicks.avg = self->childTicks.cur +
+ a_damping * (self->childTicks.avg - self->childTicks.cur);
+}
+
+SHINY_INLINE void ShinyData_copyAverage(ShinyData *self) {
+ self->entryCount.avg = (float) self->entryCount.cur;
+ self->selfTicks.avg = (float) self->selfTicks.cur;
+ self->childTicks.avg = (float) self->childTicks.cur;
+}
+
+SHINY_INLINE void ShinyData_clearAll(ShinyData *self) {
+ self->entryCount.cur = 0;
+ self->entryCount.avg = 0;
+ self->selfTicks.cur = 0;
+ self->selfTicks.avg = 0;
+ self->childTicks.cur = 0;
+ self->childTicks.avg = 0;
+}
+
+SHINY_INLINE void ShinyData_clearCurrent(ShinyData *self) {
+ self->entryCount.cur = 0;
+ self->selfTicks.cur = 0;
+ self->childTicks.cur = 0;
+}
+
+#if __cplusplus
+} /* end of extern "C" */
+#endif
+
+#endif /* SHINY_DATA_H */
diff --git a/src/Shiny/ShinyMacros.h b/src/Shiny/ShinyMacros.h
new file mode 100644
index 000000000..79dfa4381
--- /dev/null
+++ b/src/Shiny/ShinyMacros.h
@@ -0,0 +1,281 @@
+/*
+The MIT License
+
+Copyright (c) 2007-2010 Aidin Abedi http://code.google.com/p/shinyprofiler/
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#ifndef SHINY_MACROS_H
+#define SHINY_MACROS_H
+
+#ifdef SLIC3R_PROFILE
+
+#include "ShinyManager.h"
+
+/*---------------------------------------------------------------------------*/
+/* public preprocessors */
+
+#define PROFILE_UPDATE() \
+ ShinyManager_update(&Shiny_instance)
+
+#define PROFILE_SET_DAMPING(floatfrom0to1) \
+ Shiny_instance.damping = (floatfrom0to1);
+
+#define PROFILE_GET_DAMPING() \
+ (Shiny_instance.damping)
+
+#define PROFILE_OUTPUT(filename) \
+ ShinyManager_output(&Shiny_instance, (filename))
+
+#define PROFILE_OUTPUT_STREAM(stream) \
+ ShinyManager_outputToStream(&Shiny_instance, (stream))
+
+#ifdef __cplusplus
+#define PROFILE_GET_TREE_STRING() \
+ ShinyManager_outputTreeToString(&Shiny_instance)
+
+#define PROFILE_GET_FLAT_STRING() \
+ ShinyManager_outputFlatToString(&Shiny_instance)
+#endif /* __cplusplus */
+
+#define PROFILE_DESTROY() \
+ ShinyManager_destroy(&Shiny_instance)
+
+#define PROFILE_CLEAR() \
+ ShinyManager_clear(&Shiny_instance)
+
+#define PROFILE_SORT_ZONES() \
+ ShinyManager_sortZones(&Shiny_instance)
+
+
+/*---------------------------------------------------------------------------*/
+/* public preprocessors */
+
+#define PROFILE_GET_TOTAL_TICKS_CUR() \
+ ShinyData_totalTicksCur(&Shiny_instance.rootZone.data)
+
+#define PROFILE_GET_TOTAL_TICKS() \
+ ShinyData_totalTicksAvg(&Shiny_instance.rootZone.data)
+
+#define PROFILE_GET_PROFILED_TICKS_CUR() \
+ (Shiny_instance.rootZone.data.selfTicks.cur)
+
+#define PROFILE_GET_PROFILED_TICKS() \
+ (Shiny_instance.rootZone.data.selfTicks.avg)
+
+#define PROFILE_GET_UNPROFILED_TICKS_CUR() \
+ (Shiny_instance.rootZone.data.childTicks.cur)
+
+#define PROFILE_GET_UNPROFILED_TICKS() \
+ (Shiny_instance.rootZone.data.childTicks.avg)
+
+#define PROFILE_GET_SHARED_TOTAL_TICKS_CUR(name) \
+ ShinyData_totalTicksCur(&(_PROFILE_ID_ZONE_SHARED(name).data))
+
+#define PROFILE_GET_SHARED_TOTAL_TICKS(name) \
+ ShinyData_totalTicksAvg(&(_PROFILE_ID_ZONE_SHARED(name).data))
+
+#define PROFILE_GET_SHARED_SELF_TICKS_CUR(name) \
+ (_PROFILE_ID_ZONE_SHARED(name).data.selfTicks.cur)
+
+#define PROFILE_GET_SHARED_SELF_TICKS(name) \
+ (_PROFILE_ID_ZONE_SHARED(name).data.selfTicks.avg)
+
+
+/*---------------------------------------------------------------------------*/
+/* public preprocessors */
+
+#define PROFILE_IS_SHARED_SELF_BELOW(name, floatfrom0to1) \
+ ShinyManager_isZoneSelfTimeBelow( \
+ &Shiny_instance, _PROFILE_ID_ZONE_SHARED(name), floatfrom0to1)
+
+#define PROFILE_IS_SHARED_TOTAL_BELOW(name, floatfrom0to1) \
+ ShinyManager_isZoneTotalTimeBelow( \
+ &Shiny_instance, _PROFILE_ID_ZONE_SHARED(name), floatfrom0to1)
+
+
+/*---------------------------------------------------------------------------*/
+/* public preprocessors */
+
+#define PROFILE_END() \
+ ShinyManager_endCurNode(&Shiny_instance)
+
+
+/*---------------------------------------------------------------------------*/
+/* public preprocessors */
+
+#define PROFILE_BEGIN( name ) \
+ \
+ static _PROFILE_ZONE_DEFINE(_PROFILE_ID_ZONE(name), #name); \
+ _PROFILE_ZONE_BEGIN(_PROFILE_ID_ZONE(name))
+
+
+/*---------------------------------------------------------------------------*/
+/* public preprocessors */
+
+#ifdef __cplusplus
+#define PROFILE_BLOCK( name ) \
+ \
+ _PROFILE_BLOCK_DEFINE(_PROFILE_ID_BLOCK()); \
+ PROFILE_BEGIN(name)
+#endif /* __cplusplus */
+
+/*---------------------------------------------------------------------------*/
+/* public preprocessors */
+
+#ifdef __cplusplus
+#define PROFILE_FUNC() \
+ \
+ _PROFILE_BLOCK_DEFINE(_PROFILE_ID_BLOCK()); \
+ static _PROFILE_ZONE_DEFINE(_PROFILE_ID_ZONE_FUNC(), __FUNCTION__); \
+ _PROFILE_ZONE_BEGIN(_PROFILE_ID_ZONE_FUNC())
+#endif /* __cplusplus */
+
+/*---------------------------------------------------------------------------*/
+/* public preprocessors */
+
+#define PROFILE_CODE( code ) \
+ \
+ do { \
+ static _PROFILE_ZONE_DEFINE(_PROFILE_ID_ZONE_CODE(), #code); \
+ _PROFILE_ZONE_BEGIN(_PROFILE_ID_ZONE_CODE()); \
+ { code; } \
+ PROFILE_END(); \
+ } while(0)
+
+
+/*---------------------------------------------------------------------------*/
+/* public preprocessors */
+
+#define PROFILE_SHARED_EXTERN( name ) \
+ \
+ _PROFILE_ZONE_DECLARE(extern, _PROFILE_ID_ZONE_SHARED(name))
+
+
+/*---------------------------------------------------------------------------*/
+/* public preprocessors */
+
+#define PROFILE_SHARED_DEFINE( name ) \
+ \
+ _PROFILE_ZONE_DEFINE(_PROFILE_ID_ZONE_SHARED(name), #name)
+
+
+/*---------------------------------------------------------------------------*/
+/* public preprocessors */
+
+#define PROFILE_SHARED_BEGIN( name ) \
+ \
+ _PROFILE_ZONE_BEGIN(_PROFILE_ID_ZONE_SHARED(name))
+
+
+/*---------------------------------------------------------------------------*/
+/* public preprocessors */
+
+#ifdef __cplusplus
+#define PROFILE_SHARED_BLOCK( name ) \
+ \
+ _PROFILE_BLOCK_DEFINE(_PROFILE_ID_BLOCK()); \
+ _PROFILE_ZONE_BEGIN(_PROFILE_ID_ZONE_SHARED(name))
+#endif /* __cplusplus */
+
+
+/*---------------------------------------------------------------------------*/
+/* public preprocessors */
+
+#ifdef SHINY_HAS_ENABLED
+#define PROFILE_SET_ENABLED( boolean ) \
+ Shiny_instance.enabled = boolean
+#endif
+
+
+/*---------------------------------------------------------------------------*/
+/* internal preprocessors */
+
+#define _PROFILE_ID_ZONE( name ) __ShinyZone_##name
+#define _PROFILE_ID_ZONE_FUNC() __ShinyZoneFunc
+#define _PROFILE_ID_ZONE_CODE() __ShinyZoneCode
+#define _PROFILE_ID_ZONE_SHARED( name ) name##__ShinyZoneShared
+#define _PROFILE_ID_BLOCK() __ShinyBlock
+
+
+/*---------------------------------------------------------------------------*/
+/* internal preprocessor */
+
+#define _PROFILE_ZONE_DEFINE( id, string ) \
+ \
+ ShinyZone id = { \
+ NULL, SHINY_ZONE_STATE_HIDDEN, string, \
+ { { 0, 0 }, { 0, 0 }, { 0, 0 } } \
+ }
+
+
+/*---------------------------------------------------------------------------*/
+/* internal preprocessor */
+
+#define _PROFILE_ZONE_DECLARE( prefix, id ) \
+ \
+ prefix ShinyZone id
+
+
+/*---------------------------------------------------------------------------*/
+/* internal preprocessor */
+
+#define _PROFILE_BLOCK_DEFINE( id ) \
+ \
+ ShinyEndNodeOnDestruction SHINY_UNUSED id
+
+
+/*---------------------------------------------------------------------------*/
+/* internal preprocessor */
+
+#define _PROFILE_ZONE_BEGIN( id ) \
+ \
+ do { \
+ static ShinyNodeCache cache = &_ShinyNode_dummy; \
+ ShinyManager_lookupAndBeginNode(&Shiny_instance, &cache, &id); \
+ } while(0)
+
+/*---------------------------------------------------------------------------*/
+
+#else /* SLIC3R_PROFILE */
+
+#define PROFILE_UPDATE()
+#define PROFILE_SET_DAMPING(x)
+#define PROFILE_GET_DAMPING() 0.0f
+#define PROFILE_OUTPUT(x)
+#define PROFILE_OUTPUT_STREAM(x)
+#define PROFILE_CLEAR()
+#define PROFILE_GET_TREE_STRING() std::string()
+#define PROFILE_GET_FLAT_STRING() std::string()
+#define PROFILE_DESTROY()
+#define PROFILE_BEGIN(name)
+#define PROFILE_BLOCK(name)
+#define PROFILE_FUNC()
+#define PROFILE_CODE(code) do { code; } while (0)
+#define PROFILE_SHARED_GLOBAL(name)
+#define PROFILE_SHARED_MEMBER(name)
+#define PROFILE_SHARED_DEFINE(name)
+#define PROFILE_SHARED_BEGIN(name)
+#define PROFILE_SHARED_BLOCK(name)
+#define PROFILE_SET_ENABLED(boolean)
+
+#endif /* SLIC3R_PROFILE */
+
+#endif /* SHINY_MACROS_H */
diff --git a/src/Shiny/ShinyManager.c b/src/Shiny/ShinyManager.c
new file mode 100644
index 000000000..6b2811851
--- /dev/null
+++ b/src/Shiny/ShinyManager.c
@@ -0,0 +1,445 @@
+/*
+The MIT License
+
+Copyright (c) 2007-2010 Aidin Abedi http://code.google.com/p/shinyprofiler/
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#ifdef SLIC3R_PROFILE
+
+#include "ShinyManager.h"
+
+#include <malloc.h>
+#include <memory.h>
+#include <string.h>
+#include <stdio.h>
+
+/*---------------------------------------------------------------------------*/
+
+#define TABLE_SIZE_INIT 256
+
+/*---------------------------------------------------------------------------*/
+
+ShinyManager Shiny_instance = {
+#if SHINY_HAS_ENABLED == TRUE
+ /* enabled = */ false,
+#endif
+ /* _lastTick = */ 0,
+ /* _curNode = */ &Shiny_instance.rootNode,
+ /* _tableMask = */ 0,
+ /* _nodeTable = */ _ShinyManager_dummyNodeTable,
+#if SHINY_LOOKUP_RATE == TRUE
+ /* _lookupCount = */ 0,
+ /* _lookupSuccessCount = */ 0,
+#endif
+ /* _tableSize = */ 1,
+ /* nodeCount = */ 1,
+ /* zoneCount = */ 1,
+ /* _lastZone = */ &Shiny_instance.rootZone,
+ /* _lastNodePool = */ NULL,
+ /* _firstNodePool = */ NULL,
+ /* rootNode = */ {
+ /* _last = */ { 0, 0 },
+ /* zone = */ &Shiny_instance.rootZone,
+ /* parent = */ &Shiny_instance.rootNode,
+ /* nextSibling = */ NULL,
+ /* firstChild = */ NULL,
+ /* lastChild = */ NULL,
+ /* childCount = */ 0,
+ /* entryLevel = */ 0,
+ /* _cache = */ NULL,
+ /* data = */ { { 0, 0 }, { 0, 0 }, { 0, 0 } }
+ },
+ /* rootZone = */ {
+ /* next = */ NULL,
+ /* _state = */ SHINY_ZONE_STATE_HIDDEN,
+ /* name = */ "<unprofiled>",
+ /* data = */ { { 0, 0 }, { 0, 0 }, { 0, 0 } }
+ },
+ /* damping = */ 0.f, // Damping disabled, every PROFILE_UPDATE will be performed from scratch. Original value: 0.9f
+ /* _initialized = */ FALSE,
+ /* _firstUpdate = */ TRUE
+};
+
+ShinyNode* _ShinyManager_dummyNodeTable[] = { NULL };
+
+
+/*---------------------------------------------------------------------------*/
+
+#if SHINY_COMPILER == SHINY_COMPILER_MSVC
+# pragma warning (push)
+# pragma warning (disable: 4311)
+#endif
+
+/* primary hash function */
+SHINY_INLINE uint32_t hash_value(void* a_pParent, void* a_pZone) {
+ uint32_t a = (uint32_t) a_pParent + (uint32_t) a_pZone;
+// uint32_t a = *reinterpret_cast<uint32_t*>(&a_pParent) + *reinterpret_cast<uint32_t*>(&a_pZone);
+
+ a = (a+0x7ed55d16) + (a<<12);
+ a = (a^0xc761c23c) ^ (a>>19);
+ return a;
+}
+
+/*
+ * secondary hash used as index offset: force it to be odd
+ * so it's relatively prime to the power-of-two table size
+ */
+SHINY_INLINE uint32_t hash_offset(uint32_t a) {
+ return ((a << 8) + (a >> 4)) | 1;
+}
+
+#if SHINY_COMPILER == SHINY_COMPILER_MSVC
+# pragma warning (pop)
+#endif
+
+
+/*---------------------------------------------------------------------------*/
+
+void ShinyManager_preLoad(ShinyManager *self) {
+ if (!self->_initialized) {
+ _ShinyManager_init(self);
+
+ _ShinyManager_createNodeTable(self, TABLE_SIZE_INIT);
+ _ShinyManager_createNodePool(self, TABLE_SIZE_INIT / 2);
+ }
+}
+
+
+/*---------------------------------------------------------------------------*/
+
+void ShinyManager_update(ShinyManager *self) {
+#if SHINY_HAS_ENABLED == TRUE
+ if (!enabled) return;
+#endif
+
+ _ShinyManager_appendTicksToCurNode(self);
+ ShinyZone_preUpdateChain(&self->rootZone);
+
+ if (self->_firstUpdate || self->damping == 0) {
+ self->_firstUpdate = FALSE;
+ ShinyNode_updateTreeClean(&self->rootNode);
+ ShinyZone_updateChainClean(&self->rootZone);
+
+ } else {
+ ShinyNode_updateTree(&self->rootNode, self->damping);
+ ShinyZone_updateChain(&self->rootZone, self->damping);
+ }
+}
+
+
+/*---------------------------------------------------------------------------*/
+
+void ShinyManager_updateClean(ShinyManager *self) {
+#if SHINY_HAS_ENABLED == TRUE
+ if (!enabled) return;
+#endif
+
+ _ShinyManager_appendTicksToCurNode(self);
+ ShinyZone_preUpdateChain(&self->rootZone);
+
+ self->_firstUpdate = FALSE;
+ ShinyNode_updateTreeClean(&self->rootNode);
+ ShinyZone_updateChainClean(&self->rootZone);
+}
+
+
+/*---------------------------------------------------------------------------*/
+
+void ShinyManager_clear(ShinyManager *self) {
+ ShinyManager_destroy(self);
+ ShinyManager_preLoad(self);
+}
+
+
+/*---------------------------------------------------------------------------*/
+
+void ShinyManager_destroy(ShinyManager *self) {
+ ShinyManager_destroyNodes(self);
+ ShinyManager_resetZones(self);
+ _ShinyManager_uninit(self);
+}
+
+
+/*---------------------------------------------------------------------------*/
+
+ShinyNode* _ShinyManager_lookupNode(ShinyManager *self, ShinyNodeCache *a_cache, ShinyZone *a_zone) {
+ uint32_t nHash = hash_value(self->_curNode, a_zone);
+ uint32_t nIndex = nHash & self->_tableMask;
+ ShinyNode* pNode = self->_nodeTable[nIndex];
+
+ _ShinyManager_incLookup(self);
+ _ShinyManager_incLookupSuccess(self);
+
+ if (pNode) {
+ uint32_t nStep;
+
+ if (ShinyNode_isEqual(pNode, self->_curNode, a_zone)) return pNode; /* found it! */
+
+ /* hash collision: */
+
+ /* compute a secondary hash function for stepping */
+ nStep = hash_offset(nHash);
+
+ for (;;) {
+ _ShinyManager_incLookup(self);
+
+ nIndex = (nIndex + nStep) & self->_tableMask;
+ pNode = self->_nodeTable[nIndex];
+
+ if (!pNode) break; /* found empty slot */
+ else if (ShinyNode_isEqual(pNode, self->_curNode, a_zone)) return pNode; /* found it! */
+ }
+
+ /* loop is guaranteed to end because the hash table is never full */
+ }
+
+ if (a_zone->_state == SHINY_ZONE_STATE_HIDDEN) { /* zone is not initialized */
+ ShinyZone_init(a_zone, self->_lastZone);
+
+ self->_lastZone = a_zone;
+ self->zoneCount++;
+
+ if (self->_initialized == FALSE) { /* first time init */
+ _ShinyManager_init(self);
+
+ _ShinyManager_createNodeTable(self, TABLE_SIZE_INIT);
+ _ShinyManager_createNodePool(self, TABLE_SIZE_INIT / 2);
+
+ /* initialization has invalidated nIndex
+ * we must compute nIndex again
+ */
+ return _ShinyManager_createNode(self, a_cache, a_zone);
+ }
+ }
+
+ /* Althouth nodeCount is not updated
+ * it includes rootNode so it adds up.
+ *
+ * check if we need to grow the table
+ * we keep it at most 1/2 full to be very fast
+ */
+ if (self->_tableSize < 2 * self->nodeCount) {
+
+ _ShinyManager_resizeNodeTable(self, 2 * self->_tableSize);
+ _ShinyManager_resizeNodePool(self, self->nodeCount - 1);
+
+ /* resize has invalidated nIndex
+ * we must compute nIndex again
+ */
+ return _ShinyManager_createNode(self, a_cache, a_zone);
+ }
+
+ self->nodeCount++;
+
+ {
+ ShinyNode* pNewNode = ShinyNodePool_newItem(self->_lastNodePool);
+ ShinyNode_init(pNewNode, self->_curNode, a_zone, a_cache);
+
+ self->_nodeTable[nIndex] = pNewNode;
+ return pNewNode;
+ }
+}
+
+
+/*---------------------------------------------------------------------------*/
+
+void _ShinyManager_insertNode(ShinyManager *self, ShinyNode* a_pNode) {
+ uint32_t nHash = hash_value(a_pNode->parent, a_pNode->zone);
+ uint32_t nIndex = nHash & self->_tableMask;
+
+ if (self->_nodeTable[nIndex]) {
+ uint32_t nStep = hash_offset(nHash);
+
+ while (self->_nodeTable[nIndex])
+ nIndex = (nIndex + nStep) & self->_tableMask;
+ }
+
+ self->_nodeTable[nIndex] = a_pNode;
+}
+
+
+/*---------------------------------------------------------------------------*/
+
+ShinyNode* _ShinyManager_createNode(ShinyManager *self, ShinyNodeCache* a_cache, ShinyZone* a_pZone) {
+ ShinyNode* pNewNode = ShinyNodePool_newItem(self->_lastNodePool);
+ ShinyNode_init(pNewNode, self->_curNode, a_pZone, a_cache);
+
+ self->nodeCount++;
+ _ShinyManager_insertNode(self, pNewNode);
+ return pNewNode;
+}
+
+
+/*---------------------------------------------------------------------------*/
+
+void _ShinyManager_createNodePool(ShinyManager *self, uint32_t a_nCount) {
+ self->_firstNodePool = ShinyNodePool_create(a_nCount);
+ self->_lastNodePool = self->_firstNodePool;
+}
+
+
+/*---------------------------------------------------------------------------*/
+
+void _ShinyManager_resizeNodePool(ShinyManager *self, uint32_t a_nCount) {
+ ShinyNodePool* pPool = ShinyNodePool_create(a_nCount);
+ self->_lastNodePool->nextPool = pPool;
+ self->_lastNodePool = pPool;
+}
+
+
+/*---------------------------------------------------------------------------*/
+
+void _ShinyManager_createNodeTable(ShinyManager *self, uint32_t a_nCount) {
+ self->_tableSize = a_nCount;
+ self->_tableMask = a_nCount - 1;
+
+ self->_nodeTable = (ShinyNodeTable*)
+ malloc(sizeof(ShinyNode) * a_nCount);
+
+ memset(self->_nodeTable, 0, a_nCount * sizeof(ShinyNode*));
+}
+
+
+/*---------------------------------------------------------------------------*/
+
+void _ShinyManager_resizeNodeTable(ShinyManager *self, uint32_t a_nCount) {
+ ShinyNodePool* pPool;
+
+ free(self->_nodeTable);
+ _ShinyManager_createNodeTable(self, a_nCount);
+
+ pPool = self->_firstNodePool;
+ while (pPool) {
+
+ ShinyNode *pIter = ShinyNodePool_firstItem(pPool);
+
+ while (pIter != pPool->_nextItem)
+ _ShinyManager_insertNode(self, pIter++);
+
+ pPool = pPool->nextPool;
+ }
+}
+
+
+/*---------------------------------------------------------------------------*/
+
+void ShinyManager_resetZones(ShinyManager *self) {
+ ShinyZone_resetChain(&self->rootZone);
+ self->_lastZone = &self->rootZone;
+ self->zoneCount = 1;
+}
+
+
+/*---------------------------------------------------------------------------*/
+
+void ShinyManager_destroyNodes(ShinyManager *self) {
+ if (self->_firstNodePool) {
+ ShinyNodePool_destroy(self->_firstNodePool);
+ self->_firstNodePool = NULL;
+ }
+
+ if (self->_nodeTable != _ShinyManager_dummyNodeTable) {
+ free(self->_nodeTable);
+
+ self->_nodeTable = _ShinyManager_dummyNodeTable;
+ self->_tableSize = 1;
+ self->_tableMask = 0;
+ }
+
+ self->_curNode = &self->rootNode;
+ self->nodeCount = 1;
+
+ _ShinyManager_init(self);
+}
+
+
+/*---------------------------------------------------------------------------*/
+
+const char* ShinyManager_getOutputErrorString(ShinyManager *self) {
+ if (self->_firstUpdate) return "!!! Profile data must first be updated !!!";
+ else if (!self->_initialized) return "!!! No profiles where executed !!!";
+ else return NULL;
+}
+
+
+/*---------------------------------------------------------------------------*/
+
+#if SHINY_COMPILER == SHINY_COMPILER_MSVC
+# pragma warning (push)
+# pragma warning (disable: 4996)
+#endif
+
+int ShinyManager_output(ShinyManager *self, const char *a_filename) {
+ if (!a_filename) {
+ ShinyManager_outputToStream(self, stdout);
+
+ } else {
+ FILE *file = fopen(a_filename, "w");
+ if (!file) return FALSE;
+ ShinyManager_outputToStream(self, file);
+ fclose(file);
+ }
+
+ return TRUE;
+}
+
+#if SHINY_COMPILER == SHINY_COMPILER_MSVC
+# pragma warning (pop)
+#endif
+
+
+/*---------------------------------------------------------------------------*/
+
+void ShinyManager_outputToStream(ShinyManager *self, FILE *a_stream) {
+ const char *error = ShinyManager_getOutputErrorString(self);
+
+ if (error) {
+ fwrite(error, 1, strlen(error), a_stream);
+ fwrite("\n\n", 1, 2, a_stream);
+ return;
+ }
+
+#if SHINY_OUTPUT_MODE & SHINY_OUTPUT_MODE_FLAT
+ ShinyManager_sortZones(self);
+
+ {
+ int size = ShinyPrintZonesSize(self->zoneCount);
+ char *buffer = (char*) malloc(size);
+ ShinyPrintZones(buffer, &self->rootZone);
+ fwrite(buffer, 1, size - 1, a_stream);
+ fwrite("\n\n", 1, 2, a_stream);
+ free(buffer);
+ }
+#endif
+
+#if SHINY_OUTPUT_MODE & SHINY_OUTPUT_MODE_TREE
+ {
+ int size = ShinyPrintNodesSize(self->nodeCount);
+ char *buffer = (char*) malloc(size);
+ ShinyPrintNodes(buffer, &self->rootNode);
+ fwrite(buffer, 1, size - 1, a_stream);
+ fwrite("\n\n", 1, 2, a_stream);
+ free(buffer);
+ }
+#endif
+}
+
+#endif /* SLIC3R_PROFILE */
diff --git a/src/Shiny/ShinyManager.h b/src/Shiny/ShinyManager.h
new file mode 100644
index 000000000..403e0e878
--- /dev/null
+++ b/src/Shiny/ShinyManager.h
@@ -0,0 +1,263 @@
+/*
+The MIT License
+
+Copyright (c) 2007-2010 Aidin Abedi http://code.google.com/p/shinyprofiler/
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#ifndef SHINY_MANAGER_H
+#define SHINY_MANAGER_H
+
+#include "ShinyZone.h"
+#include "ShinyNode.h"
+#include "ShinyNodePool.h"
+#include "ShinyTools.h"
+#include "ShinyOutput.h"
+
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*---------------------------------------------------------------------------*/
+
+typedef struct {
+#ifdef SHINY_HAS_ENABLED
+ bool enabled;
+#endif
+
+ shinytick_t _lastTick;
+
+ ShinyNode* _curNode;
+
+ uint32_t _tableMask; /* = _tableSize - 1 */
+
+ ShinyNodeTable* _nodeTable;
+
+#ifdef SHINY_LOOKUP_RATE
+ uint64_t _lookupCount;
+ uint64_t _lookupSuccessCount;
+#endif
+
+ uint32_t _tableSize;
+
+ uint32_t nodeCount;
+ uint32_t zoneCount;
+
+ ShinyZone* _lastZone;
+
+ ShinyNodePool* _lastNodePool;
+ ShinyNodePool* _firstNodePool;
+
+ ShinyNode rootNode;
+ ShinyZone rootZone;
+
+ float damping;
+
+ int _initialized;
+ int _firstUpdate;
+} ShinyManager;
+
+
+/*---------------------------------------------------------------------------*/
+
+extern ShinyNode* _ShinyManager_dummyNodeTable[];
+
+extern ShinyManager Shiny_instance;
+
+
+/*---------------------------------------------------------------------------*/
+
+SHINY_INLINE void _ShinyManager_appendTicksToCurNode(ShinyManager *self) {
+ shinytick_t curTick;
+ ShinyGetTicks(&curTick);
+
+ ShinyNode_appendTicks(self->_curNode, curTick - self->_lastTick);
+ self->_lastTick = curTick;
+}
+
+SHINY_API ShinyNode* _ShinyManager_lookupNode(ShinyManager *self, ShinyNodeCache* a_cache, ShinyZone* a_zone);
+
+SHINY_API void _ShinyManager_createNodeTable(ShinyManager *self, uint32_t a_count);
+SHINY_API void _ShinyManager_resizeNodeTable(ShinyManager *self, uint32_t a_count);
+
+SHINY_API void _ShinyManager_createNodePool(ShinyManager *self, uint32_t a_count);
+SHINY_API void _ShinyManager_resizeNodePool(ShinyManager *self, uint32_t a_count);
+
+SHINY_API ShinyNode* _ShinyManager_createNode(ShinyManager *self, ShinyNodeCache* a_cache, ShinyZone* a_pZone);
+SHINY_API void _ShinyManager_insertNode(ShinyManager *self, ShinyNode* a_pNode);
+
+SHINY_INLINE void _ShinyManager_init(ShinyManager *self) {
+ self->_initialized = TRUE;
+
+ self->rootNode._last.entryCount = 1;
+ self->rootNode._last.selfTicks = 0;
+ ShinyGetTicks(&self->_lastTick);
+}
+
+SHINY_INLINE void _ShinyManager_uninit(ShinyManager *self) {
+ self->_initialized = FALSE;
+
+ ShinyNode_clear(&self->rootNode);
+ self->rootNode.parent = &self->rootNode;
+ self->rootNode.zone = &self->rootZone;
+}
+
+#ifdef SHINY_LOOKUP_RATE
+SHINY_INLINE void _ShinyManager_incLookup(ShinyManager *self) { self->_lookupCount++; }
+SHINY_INLINE void _ShinyManager_incLookupSuccess(ShinyManager *self) { self->_lookupSuccessCount++; }
+SHINY_INLINE float ShinyManager_lookupRate(const ShinyManager *self) { return ((float) self->_lookupSuccessCount) / ((float) self->_lookupCount); }
+
+#else
+SHINY_INLINE void _ShinyManager_incLookup(ShinyManager * self) { self = self; }
+SHINY_INLINE void _ShinyManager_incLookupSuccess(ShinyManager * self) { self = self; }
+SHINY_INLINE float ShinyManager_lookupRate(const ShinyManager * self) { self = self; return -1; }
+#endif
+
+SHINY_API void ShinyManager_resetZones(ShinyManager *self);
+SHINY_API void ShinyManager_destroyNodes(ShinyManager *self);
+
+SHINY_INLINE float ShinyManager_tableUsage(const ShinyManager *self) {
+ return ((float) self->nodeCount) / ((float) self->_tableSize);
+}
+
+SHINY_INLINE uint32_t ShinyManager_allocMemInBytes(const ShinyManager *self) {
+ return self->_tableSize * sizeof(ShinyNode*)
+ + (self->_firstNodePool)? ShinyNodePool_memoryUsageChain(self->_firstNodePool) : 0;
+}
+
+SHINY_INLINE void ShinyManager_beginNode(ShinyManager *self, ShinyNode* a_node) {
+ ShinyNode_beginEntry(a_node);
+
+ _ShinyManager_appendTicksToCurNode(self);
+ self->_curNode = a_node;
+}
+
+SHINY_INLINE void ShinyManager_lookupAndBeginNode(ShinyManager *self, ShinyNodeCache* a_cache, ShinyZone* a_zone) {
+#ifdef SHINY_HAS_ENABLED
+ if (!self->enabled) return;
+#endif
+
+ if (self->_curNode != (*a_cache)->parent)
+ *a_cache = _ShinyManager_lookupNode(self, a_cache, a_zone);
+
+ ShinyManager_beginNode(self, *a_cache);
+}
+
+SHINY_INLINE void ShinyManager_endCurNode(ShinyManager *self) {
+#ifdef SHINY_HAS_ENABLED
+ if (!self->enabled) return;
+#endif
+
+ _ShinyManager_appendTicksToCurNode(self);
+ self->_curNode = self->_curNode->parent;
+}
+
+/**/
+
+SHINY_API void ShinyManager_preLoad(ShinyManager *self);
+
+SHINY_API void ShinyManager_updateClean(ShinyManager *self);
+SHINY_API void ShinyManager_update(ShinyManager *self);
+
+SHINY_API void ShinyManager_clear(ShinyManager *self);
+SHINY_API void ShinyManager_destroy(ShinyManager *self);
+
+SHINY_INLINE void ShinyManager_sortZones(ShinyManager *self) {
+ if (self->rootZone.next)
+ self->_lastZone = ShinyZone_sortChain(&self->rootZone.next);
+}
+
+SHINY_API const char* ShinyManager_getOutputErrorString(ShinyManager *self);
+
+SHINY_API int ShinyManager_output(ShinyManager *self, const char *a_filename);
+SHINY_API void ShinyManager_outputToStream(ShinyManager *self, FILE *stream);
+
+#if __cplusplus
+} /* end of extern "C" */
+
+SHINY_INLINE std::string ShinyManager_outputTreeToString(ShinyManager *self) {
+ const char* error = ShinyManager_getOutputErrorString(self);
+ if (error) return error;
+ else return ShinyNodesToString(&self->rootNode, self->nodeCount);
+}
+
+SHINY_INLINE std::string ShinyManager_outputFlatToString(ShinyManager *self) {
+ const char* error = ShinyManager_getOutputErrorString(self);
+ if (error) return error;
+
+ ShinyManager_sortZones(self);
+ return ShinyZonesToString(&self->rootZone, self->zoneCount);
+}
+
+extern "C" { /* end of c++ */
+#endif
+
+SHINY_INLINE int ShinyManager_isZoneSelfTimeBelow(ShinyManager *self, ShinyZone* a_zone, float a_percentage) {
+ return a_percentage * (float) self->rootZone.data.childTicks.cur
+ <= (float) a_zone->data.selfTicks.cur;
+}
+
+SHINY_INLINE int ShinyManager_isZoneTotalTimeBelow(ShinyManager *self, ShinyZone* a_zone, float a_percentage) {
+ return a_percentage * (float) self->rootZone.data.childTicks.cur
+ <= (float) ShinyData_totalTicksCur(&a_zone->data);
+}
+
+/**/
+
+SHINY_INLINE void ShinyManager_enumerateNodes(ShinyManager *self, void (*a_func)(const ShinyNode*)) {
+ ShinyNode_enumerateNodes(&self->rootNode, a_func);
+}
+
+SHINY_INLINE void ShinyManager_enumerateZones(ShinyManager *self, void (*a_func)(const ShinyZone*)) {
+ ShinyZone_enumerateZones(&self->rootZone, a_func);
+}
+
+#if __cplusplus
+} /* end of extern "C" */
+
+template <class T> void ShinyManager_enumerateNodes(ShinyManager *self, T* a_this, void (T::*a_func)(const ShinyNode*)) {
+ ShinyNode_enumerateNodes(&self->rootNode, a_this, a_func);
+}
+
+template <class T> void ShinyManager_enumerateZones(ShinyManager *self, T* a_this, void (T::*a_func)(const ShinyZone*)) {
+ ShinyZone_enumerateZones(&self->rootZone, a_this, a_func);
+}
+
+extern "C" { /* end of c++ */
+#endif
+
+
+/*---------------------------------------------------------------------------*/
+
+#if __cplusplus
+} /* end of extern "C" */
+
+class ShinyEndNodeOnDestruction {
+public:
+
+ SHINY_INLINE ~ShinyEndNodeOnDestruction() {
+ ShinyManager_endCurNode(&Shiny_instance);
+ }
+};
+#endif
+
+#endif /* SHINY_MANAGER_H */
diff --git a/src/Shiny/ShinyNode.c b/src/Shiny/ShinyNode.c
new file mode 100644
index 000000000..9d777073b
--- /dev/null
+++ b/src/Shiny/ShinyNode.c
@@ -0,0 +1,129 @@
+/*
+The MIT License
+
+Copyright (c) 2007-2010 Aidin Abedi http://code.google.com/p/shinyprofiler/
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#ifdef SLIC3R_PROFILE
+
+#include "ShinyNode.h"
+#include "ShinyZone.h"
+#include "ShinyNodeState.h"
+
+#include <memory.h>
+
+/*---------------------------------------------------------------------------*/
+
+ShinyNode _ShinyNode_dummy = {
+ /* _last = */ { 0, 0 },
+ /* zone = */ NULL,
+ /* parent = */ NULL,
+ /* nextSibling = */ NULL,
+ /* firstChild = */ NULL,
+ /* lastChild = */ NULL
+};
+
+
+/*---------------------------------------------------------------------------*/
+
+void ShinyNode_updateTree(ShinyNode* first, float a_damping) {
+ ShinyNodeState *top = NULL;
+ ShinyNode *node = first;
+
+ for (;;) {
+ do {
+ top = ShinyNodeState_push(top, node);
+ node = node->firstChild;
+ } while (node);
+
+ for (;;) {
+ node = ShinyNodeState_finishAndGetNext(top, a_damping);
+ top = ShinyNodeState_pop(top);
+
+ if (node) break;
+ else if (!top) return;
+ }
+ }
+}
+
+
+/*---------------------------------------------------------------------------*/
+
+void ShinyNode_updateTreeClean(ShinyNode* first) {
+ ShinyNodeState *top = NULL;
+ ShinyNode *node = first;
+
+ for (;;) {
+ do {
+ top = ShinyNodeState_push(top, node);
+ node = node->firstChild;
+ } while (node);
+
+ for (;;) {
+ node = ShinyNodeState_finishAndGetNextClean(top);
+ top = ShinyNodeState_pop(top);
+
+ if (node) break;
+ else if (!top) return;
+ }
+ }
+}
+
+
+/*---------------------------------------------------------------------------*/
+
+const ShinyNode* ShinyNode_findNextInTree(const ShinyNode* self) {
+ if (self->firstChild) {
+ return self->firstChild;
+
+ } else if (self->nextSibling) {
+ return self->nextSibling;
+
+ } else {
+ ShinyNode* pParent = self->parent;
+
+ while (!ShinyNode_isRoot(pParent)) {
+ if (pParent->nextSibling) return pParent->nextSibling;
+ else pParent = pParent->parent;
+ }
+
+ return NULL;
+ }
+}
+
+
+/*---------------------------------------------------------------------------*/
+
+void ShinyNode_clear(ShinyNode* self) {
+ memset(self, 0, sizeof(ShinyNode));
+}
+
+
+/*---------------------------------------------------------------------------*/
+
+void ShinyNode_enumerateNodes(const ShinyNode* a_node, void (*a_func)(const ShinyNode*)) {
+ a_func(a_node);
+
+ if (a_node->firstChild) ShinyNode_enumerateNodes(a_node->firstChild, a_func);
+ if (a_node->nextSibling) ShinyNode_enumerateNodes(a_node->nextSibling, a_func);
+}
+
+#endif /* SLIC3R_PROFILE */
diff --git a/src/Shiny/ShinyNode.h b/src/Shiny/ShinyNode.h
new file mode 100644
index 000000000..ee5fdb0de
--- /dev/null
+++ b/src/Shiny/ShinyNode.h
@@ -0,0 +1,133 @@
+/*
+The MIT License
+
+Copyright (c) 2007-2010 Aidin Abedi http://code.google.com/p/shinyprofiler/
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#ifndef SHINY_NODE_H
+#define SHINY_NODE_H
+
+#include "ShinyData.h"
+#include "ShinyTools.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*---------------------------------------------------------------------------*/
+
+typedef struct _ShinyNode {
+
+ ShinyLastData _last;
+
+ struct _ShinyZone* zone;
+ struct _ShinyNode* parent;
+ struct _ShinyNode* nextSibling;
+
+ struct _ShinyNode* firstChild;
+ struct _ShinyNode* lastChild;
+
+ uint32_t childCount;
+ uint32_t entryLevel;
+
+ ShinyNodeCache* _cache;
+
+ ShinyData data;
+
+} ShinyNode;
+
+
+/*---------------------------------------------------------------------------*/
+
+extern ShinyNode _ShinyNode_dummy;
+
+
+/*---------------------------------------------------------------------------*/
+
+SHINY_INLINE void ShinyNode_addChild(ShinyNode* self, ShinyNode* a_child) {
+ if (self->childCount++) {
+ self->lastChild->nextSibling = a_child;
+ self->lastChild = a_child;
+
+ } else {
+ self->lastChild = a_child;
+ self->firstChild = a_child;
+ }
+}
+
+SHINY_INLINE void ShinyNode_init(ShinyNode* self, ShinyNode* a_parent, struct _ShinyZone* a_zone, ShinyNodeCache* a_cache) {
+ /* NOTE: all member variables are assumed to be zero when allocated */
+
+ self->zone = a_zone;
+ self->parent = a_parent;
+
+ self->entryLevel = a_parent->entryLevel + 1;
+ ShinyNode_addChild(a_parent, self);
+
+ self->_cache = a_cache;
+}
+
+SHINY_API void ShinyNode_updateTree(ShinyNode* self, float a_damping);
+SHINY_API void ShinyNode_updateTreeClean(ShinyNode* self);
+
+SHINY_INLINE void ShinyNode_destroy(ShinyNode* self) {
+ *(self->_cache) = &_ShinyNode_dummy;
+}
+
+SHINY_INLINE void ShinyNode_appendTicks(ShinyNode* self, shinytick_t a_elapsedTicks) {
+ self->_last.selfTicks += a_elapsedTicks;
+}
+
+SHINY_INLINE void ShinyNode_beginEntry(ShinyNode* self) {
+ self->_last.entryCount++;
+}
+
+SHINY_INLINE int ShinyNode_isRoot(ShinyNode* self) {
+ return (self->entryLevel == 0);
+}
+
+SHINY_INLINE int ShinyNode_isDummy(ShinyNode* self) {
+ return (self == &_ShinyNode_dummy);
+}
+
+SHINY_INLINE int ShinyNode_isEqual(ShinyNode* self, const ShinyNode* a_parent, const struct _ShinyZone* a_zone) {
+ return (self->parent == a_parent && self->zone == a_zone);
+}
+
+SHINY_API const ShinyNode* ShinyNode_findNextInTree(const ShinyNode* self);
+
+SHINY_API void ShinyNode_clear(ShinyNode* self);
+
+SHINY_API void ShinyNode_enumerateNodes(const ShinyNode* a_node, void (*a_func)(const ShinyNode*));
+
+#if __cplusplus
+} /* end of extern "C" */
+
+template <class T>
+void ShinyNode_enumerateNodes(const ShinyNode* a_node, T* a_this, void (T::*a_func)(const ShinyNode*)) {
+ (a_this->*a_func)(a_node);
+
+ if (a_node->firstChild) ShinyNode_enumerateNodes(a_node->firstChild, a_this, a_func);
+ if (a_node->nextSibling) ShinyNode_enumerateNodes(a_node->nextSibling, a_this, a_func);
+}
+#endif /* __cplusplus */
+
+#endif /* SHINY_NODE_H */
diff --git a/src/Shiny/ShinyNodePool.c b/src/Shiny/ShinyNodePool.c
new file mode 100644
index 000000000..f00293252
--- /dev/null
+++ b/src/Shiny/ShinyNodePool.c
@@ -0,0 +1,77 @@
+/*
+The MIT License
+
+Copyright (c) 2007-2010 Aidin Abedi http://code.google.com/p/shinyprofiler/
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#ifdef SLIC3R_PROFILE
+
+#include "ShinyNodePool.h"
+#include "ShinyTools.h"
+
+#include <memory.h>
+#include <malloc.h>
+
+/*---------------------------------------------------------------------------*/
+
+ShinyNodePool* ShinyNodePool_create(uint32_t a_items) {
+ ShinyNodePool* pPool = (ShinyNodePool*)
+ malloc(sizeof(ShinyNodePool) + sizeof(ShinyNode) * (a_items - 1));
+
+ pPool->nextPool = NULL;
+ pPool->_nextItem = &pPool->_items[0];
+ pPool->endOfItems = &pPool->_items[a_items];
+
+ memset(&pPool->_items[0], 0, a_items * sizeof(ShinyNode));
+ return pPool;
+}
+
+
+/*---------------------------------------------------------------------------*/
+
+uint32_t ShinyNodePool_memoryUsageChain(ShinyNodePool *first) {
+ uint32_t bytes = (uint32_t) ((char*) first->endOfItems - (char*) first);
+ ShinyNodePool *pool = first->nextPool;
+
+ while (pool) {
+ bytes += (uint32_t) ((char*) pool->endOfItems - (char*) pool);
+ pool = pool->nextPool;
+ }
+
+ return bytes;
+}
+
+
+/*---------------------------------------------------------------------------*/
+
+void ShinyNodePool_destroy(ShinyNodePool *self) {
+ ShinyNode* firstNode = ShinyNodePool_firstItem(self);
+ ShinyNode* lastNode = self->_nextItem;
+
+ while (firstNode != lastNode)
+ ShinyNode_destroy(firstNode++);
+
+ /* TODO: make this into a loop or a tail recursion */
+ if (self->nextPool) ShinyNodePool_destroy(self->nextPool);
+ free(self);
+}
+
+#endif /* SLIC3R_PROFILE */
diff --git a/src/Shiny/ShinyNodePool.h b/src/Shiny/ShinyNodePool.h
new file mode 100644
index 000000000..5e30a3306
--- /dev/null
+++ b/src/Shiny/ShinyNodePool.h
@@ -0,0 +1,67 @@
+/*
+The MIT License
+
+Copyright (c) 2007-2010 Aidin Abedi http://code.google.com/p/shinyprofiler/
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#ifndef SHINY_NODE_POOL_H
+#define SHINY_NODE_POOL_H
+
+#include "ShinyNode.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*---------------------------------------------------------------------------*/
+
+typedef struct _ShinyNodePool {
+
+ struct _ShinyNodePool* nextPool;
+
+ ShinyNode *_nextItem;
+ ShinyNode *endOfItems;
+
+ ShinyNode _items[1];
+
+} ShinyNodePool;
+
+
+/*---------------------------------------------------------------------------*/
+
+SHINY_INLINE ShinyNode* ShinyNodePool_firstItem(ShinyNodePool *self) {
+ return &(self->_items[0]);
+}
+
+SHINY_INLINE ShinyNode* ShinyNodePool_newItem(ShinyNodePool *self) {
+ return self->_nextItem++;
+}
+
+ShinyNodePool* ShinyNodePool_create(uint32_t a_items);
+void ShinyNodePool_destroy(ShinyNodePool *self);
+
+uint32_t ShinyNodePool_memoryUsageChain(ShinyNodePool *first);
+
+#if __cplusplus
+} /* end of extern "C" */
+#endif
+
+#endif /* SHINY_NODE_POOL_H */
diff --git a/src/Shiny/ShinyNodeState.c b/src/Shiny/ShinyNodeState.c
new file mode 100644
index 000000000..fbf6dc870
--- /dev/null
+++ b/src/Shiny/ShinyNodeState.c
@@ -0,0 +1,108 @@
+/*
+The MIT License
+
+Copyright (c) 2007-2010 Aidin Abedi http://code.google.com/p/shinyprofiler/
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#ifdef SLIC3R_PROFILE
+
+#include "ShinyNodeState.h"
+#include "ShinyNode.h"
+#include "ShinyZone.h"
+
+#include <malloc.h>
+
+/*---------------------------------------------------------------------------*/
+
+ShinyNodeState* ShinyNodeState_push(ShinyNodeState *a_top, ShinyNode *a_node) {
+ ShinyZone *zone = a_node->zone;
+ ShinyNodeState *self = (ShinyNodeState*) malloc(sizeof(ShinyNodeState));
+ self->node = a_node;
+ self->_prev = a_top;
+
+ a_node->data.selfTicks.cur = a_node->_last.selfTicks;
+ a_node->data.entryCount.cur = a_node->_last.entryCount;
+
+ zone->data.selfTicks.cur += a_node->_last.selfTicks;
+ zone->data.entryCount.cur += a_node->_last.entryCount;
+
+ a_node->data.childTicks.cur = 0;
+ a_node->_last.selfTicks = 0;
+ a_node->_last.entryCount = 0;
+
+ self->zoneUpdating = zone->_state != SHINY_ZONE_STATE_UPDATING;
+ if (self->zoneUpdating) {
+ zone->_state = SHINY_ZONE_STATE_UPDATING;
+ } else {
+ zone->data.childTicks.cur -= a_node->data.selfTicks.cur;
+ }
+
+ return self;
+}
+
+/*---------------------------------------------------------------------------*/
+
+ShinyNodeState* ShinyNodeState_pop(ShinyNodeState *a_top) {
+ ShinyNodeState *prev = a_top->_prev;
+ free(a_top);
+ return prev;
+}
+
+/*---------------------------------------------------------------------------*/
+
+ShinyNode* ShinyNodeState_finishAndGetNext(ShinyNodeState *self, float a_damping) {
+ ShinyNode *node = self->node;
+ ShinyZone *zone = node->zone;
+
+ if (self->zoneUpdating) {
+ zone->data.childTicks.cur += node->data.childTicks.cur;
+ zone->_state = SHINY_ZONE_STATE_INITIALIZED;
+ }
+
+ ShinyData_computeAverage(&node->data, a_damping);
+
+ if (!ShinyNode_isRoot(node))
+ node->parent->data.childTicks.cur += node->data.selfTicks.cur + node->data.childTicks.cur;
+
+ return node->nextSibling;
+}
+
+
+/*---------------------------------------------------------------------------*/
+
+ShinyNode* ShinyNodeState_finishAndGetNextClean(ShinyNodeState *self) {
+ ShinyNode *node = self->node;
+ ShinyZone *zone = node->zone;
+
+ if (self->zoneUpdating) {
+ zone->data.childTicks.cur += node->data.childTicks.cur;
+ zone->_state = SHINY_ZONE_STATE_INITIALIZED;
+ }
+
+ ShinyData_copyAverage(&node->data);
+
+ if (!ShinyNode_isRoot(node))
+ node->parent->data.childTicks.cur += node->data.selfTicks.cur + node->data.childTicks.cur;
+
+ return node->nextSibling;
+}
+
+#endif /* SLIC3R_PROFILE */
diff --git a/src/Shiny/ShinyNodeState.h b/src/Shiny/ShinyNodeState.h
new file mode 100644
index 000000000..62fdd4ba8
--- /dev/null
+++ b/src/Shiny/ShinyNodeState.h
@@ -0,0 +1,56 @@
+/*
+The MIT License
+
+Copyright (c) 2007-2010 Aidin Abedi http://code.google.com/p/shinyprofiler/
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#ifndef SHINY_NODE_STATE_H
+#define SHINY_NODE_STATE_H
+
+#include "ShinyNode.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*---------------------------------------------------------------------------*/
+
+typedef struct _ShinyNodeState {
+ ShinyNode *node;
+ int zoneUpdating;
+
+ struct _ShinyNodeState *_prev;
+} ShinyNodeState;
+
+
+/*---------------------------------------------------------------------------*/
+
+ShinyNodeState* ShinyNodeState_push(ShinyNodeState *a_top, ShinyNode *a_node);
+ShinyNodeState* ShinyNodeState_pop(ShinyNodeState *a_top);
+
+ShinyNode* ShinyNodeState_finishAndGetNext(ShinyNodeState *self, float a_damping);
+ShinyNode* ShinyNodeState_finishAndGetNextClean(ShinyNodeState *self);
+
+#if __cplusplus
+} /* end of extern "C" */
+#endif
+
+#endif /* SHINY_NODE_STATE_H */
diff --git a/src/Shiny/ShinyOutput.c b/src/Shiny/ShinyOutput.c
new file mode 100644
index 000000000..ad02ea003
--- /dev/null
+++ b/src/Shiny/ShinyOutput.c
@@ -0,0 +1,189 @@
+/*
+The MIT License
+
+Copyright (c) 2007-2010 Aidin Abedi http://code.google.com/p/shinyprofiler/
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#ifdef SLIC3R_PROFILE
+
+#include "ShinyOutput.h"
+
+#include <stdio.h>
+
+#if SHINY_COMPILER == SHINY_COMPILER_MSVC
+# pragma warning(disable: 4996)
+# define snprintf _snprintf
+# define TRAILING 0
+
+#else
+# define TRAILING 1
+#endif
+
+/*---------------------------------------------------------------------------*/
+
+#define OUTPUT_WIDTH_CALL 6
+#define OUTPUT_WIDTH_TIME 6
+#define OUTPUT_WIDTH_PERC 4
+#define OUTPUT_WIDTH_SUM 120
+
+#define OUTPUT_WIDTH_DATA (1+OUTPUT_WIDTH_CALL + 1 + 2*(OUTPUT_WIDTH_TIME+4+OUTPUT_WIDTH_PERC+1) + 1)
+#define OUTPUT_WIDTH_NAME (OUTPUT_WIDTH_SUM - OUTPUT_WIDTH_DATA)
+
+
+/*---------------------------------------------------------------------------*/
+
+SHINY_INLINE char* printHeader(char *output, const char *a_title) {
+ snprintf(output, OUTPUT_WIDTH_SUM + TRAILING,
+ "%-*s %*s %*s %*s",
+ OUTPUT_WIDTH_NAME, a_title,
+ OUTPUT_WIDTH_CALL, "calls",
+ OUTPUT_WIDTH_TIME+4+OUTPUT_WIDTH_PERC+1, "self time",
+ OUTPUT_WIDTH_TIME+4+OUTPUT_WIDTH_PERC+1, "total time");
+
+ return output + OUTPUT_WIDTH_SUM;
+}
+
+
+/*---------------------------------------------------------------------------*/
+
+SHINY_INLINE char* printData(char *output, const ShinyData *a_data, float a_topercent) {
+ float totalTicksAvg = ShinyData_totalTicksAvg(a_data);
+ const ShinyTimeUnit *selfUnit = ShinyGetTimeUnit(a_data->selfTicks.avg);
+ const ShinyTimeUnit *totalUnit = ShinyGetTimeUnit(totalTicksAvg);
+
+ snprintf(output, OUTPUT_WIDTH_DATA + TRAILING,
+ " %*.1f %*.0f %-2s %*.0f%% %*.0f %-2s %*.0f%%",
+ OUTPUT_WIDTH_CALL, a_data->entryCount.avg,
+ OUTPUT_WIDTH_TIME, a_data->selfTicks.avg * selfUnit->invTickFreq, selfUnit->suffix,
+ OUTPUT_WIDTH_PERC, a_data->selfTicks.avg * a_topercent,
+ OUTPUT_WIDTH_TIME, totalTicksAvg * totalUnit->invTickFreq, totalUnit->suffix,
+ OUTPUT_WIDTH_PERC, totalTicksAvg * a_topercent);
+
+ return output + OUTPUT_WIDTH_DATA;
+}
+
+
+/*---------------------------------------------------------------------------*/
+
+SHINY_INLINE char* printNode(char* output, const ShinyNode *a_node, float a_topercent) {
+ int offset = a_node->entryLevel * 2;
+
+ snprintf(output, OUTPUT_WIDTH_NAME + TRAILING, "%*s%-*s",
+ offset, "", OUTPUT_WIDTH_NAME - offset, a_node->zone->name);
+
+ output += OUTPUT_WIDTH_NAME;
+
+ output = printData(output, &a_node->data, a_topercent);
+ return output;
+}
+
+
+/*---------------------------------------------------------------------------*/
+
+SHINY_INLINE char* printZone(char* output, const ShinyZone *a_zone, float a_topercent) {
+ snprintf(output, OUTPUT_WIDTH_NAME + TRAILING, "%-*s",
+ OUTPUT_WIDTH_NAME, a_zone->name);
+
+ output += OUTPUT_WIDTH_NAME;
+
+ output = printData(output, &a_zone->data, a_topercent);
+ return output;
+}
+
+
+/*---------------------------------------------------------------------------*/
+
+int ShinyPrintNodesSize(uint32_t a_count) {
+ return (1 + a_count) * (OUTPUT_WIDTH_SUM + 1);
+}
+
+
+/*---------------------------------------------------------------------------*/
+
+int ShinyPrintZonesSize(uint32_t a_count) {
+ return (1 + a_count) * (OUTPUT_WIDTH_SUM + 1);
+}
+
+
+/*---------------------------------------------------------------------------*/
+
+void ShinyPrintANode(char* output, const ShinyNode *a_node, const ShinyNode *a_root) {
+ float fTicksToPc = 100.0f / a_root->data.childTicks.avg;
+ output = printNode(output, a_node, fTicksToPc);
+ (*output++) = '\0';
+}
+
+
+/*---------------------------------------------------------------------------*/
+
+void ShinyPrintAZone(char* output, const ShinyZone *a_zone, const ShinyZone *a_root) {
+ float fTicksToPc = 100.0f / a_root->data.childTicks.avg;
+ output = printZone(output, a_zone, fTicksToPc);
+ (*output++) = '\0';
+}
+
+
+/*---------------------------------------------------------------------------*/
+
+void ShinyPrintNodes(char* output, const ShinyNode *a_root) {
+ float fTicksToPc = 100.0f / a_root->data.childTicks.avg;
+ const ShinyNode *node = a_root;
+
+ output = printHeader(output, "call tree");
+ (*output++) = '\n';
+
+ for (;;) {
+ output = printNode(output, node, fTicksToPc);
+
+ node = ShinyNode_findNextInTree(node);
+ if (node) {
+ (*output++) = '\n';
+ } else {
+ (*output++) = '\0';
+ return;
+ }
+ }
+}
+
+
+/*---------------------------------------------------------------------------*/
+
+void ShinyPrintZones(char* output, const ShinyZone *a_root) {
+ float fTicksToPc = 100.0f / a_root->data.childTicks.avg;
+ const ShinyZone *zone = a_root;
+
+ output = printHeader(output, "sorted list");
+ (*output++) = '\n';
+
+ for (;;) {
+ output = printZone(output, zone, fTicksToPc);
+
+ zone = zone->next;
+ if (zone) {
+ (*output++) = '\n';
+ } else {
+ (*output++) = '\0';
+ return;
+ }
+ }
+}
+
+#endif /* SLIC3R_PROFILE */
diff --git a/src/Shiny/ShinyOutput.h b/src/Shiny/ShinyOutput.h
new file mode 100644
index 000000000..81c1783db
--- /dev/null
+++ b/src/Shiny/ShinyOutput.h
@@ -0,0 +1,68 @@
+/*
+The MIT License
+
+Copyright (c) 2007-2010 Aidin Abedi http://code.google.com/p/shinyprofiler/
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#ifndef SHINY_OUTPUT_H
+#define SHINY_OUTPUT_H
+
+#include "ShinyNode.h"
+#include "ShinyZone.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*---------------------------------------------------------------------------*/
+
+SHINY_API int ShinyPrintNodesSize(uint32_t a_count);
+SHINY_API int ShinyPrintZonesSize(uint32_t a_count);
+
+SHINY_API void ShinyPrintANode(char* output, const ShinyNode *a_node, const ShinyNode *a_root);
+SHINY_API void ShinyPrintAZone(char* output, const ShinyZone *a_zone, const ShinyZone *a_root);
+
+SHINY_API void ShinyPrintNodes(char* output, const ShinyNode *a_root);
+SHINY_API void ShinyPrintZones(char* output, const ShinyZone *a_root);
+
+
+/*---------------------------------------------------------------------------*/
+
+#if __cplusplus
+} /* end of extern "C" */
+#include <string>
+
+SHINY_INLINE std::string ShinyNodesToString(const ShinyNode *a_root, uint32_t a_count) {
+ std::string str;
+ str.resize(ShinyPrintNodesSize(a_count) - 1);
+ ShinyPrintNodes(&str[0], a_root);
+ return str;
+}
+
+SHINY_INLINE std::string ShinyZonesToString(const ShinyZone *a_root, uint32_t a_count) {
+ std::string str;
+ str.resize(ShinyPrintZonesSize(a_count) - 1);
+ ShinyPrintZones(&str[0], a_root);
+ return str;
+}
+#endif /* __cplusplus */
+
+#endif /* SHINY_OUTPUT_H */
diff --git a/src/Shiny/ShinyPrereqs.h b/src/Shiny/ShinyPrereqs.h
new file mode 100644
index 000000000..5a3044dbc
--- /dev/null
+++ b/src/Shiny/ShinyPrereqs.h
@@ -0,0 +1,138 @@
+/*
+The MIT License
+
+Copyright (c) 2007-2010 Aidin Abedi http://code.google.com/p/shinyprofiler/
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#ifndef SHINY_PREREQS_H
+#define SHINY_PREREQS_H
+
+
+#include <stdint.h>
+
+/*---------------------------------------------------------------------------*/
+
+#ifndef FALSE
+#define FALSE 0x0
+#endif
+
+#ifndef TRUE
+#define TRUE 0x1
+#endif
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#include "ShinyConfig.h"
+#include "ShinyVersion.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*---------------------------------------------------------------------------*/
+
+#define SHINY_PLATFORM_WIN32 0x1
+#define SHINY_PLATFORM_POSIX 0x2
+
+#if defined (_WIN32)
+# define SHINY_PLATFORM SHINY_PLATFORM_WIN32
+
+#else /* ASSUME: POSIX-compliant OS */
+# define SHINY_PLATFORM SHINY_PLATFORM_POSIX
+#endif
+
+
+/*---------------------------------------------------------------------------*/
+
+#define SHINY_COMPILER_MSVC 0x1
+#define SHINY_COMPILER_GNUC 0x2
+#define SHINY_COMPILER_OTHER 0x3
+
+#if defined (_MSC_VER)
+# define SHINY_COMPILER SHINY_COMPILER_MSVC
+
+#elif defined (__GNUG__)
+# define SHINY_COMPILER SHINY_COMPILER_GNUC
+
+#else
+# define SHINY_COMPILER SHINY_COMPILER_OTHER
+#endif
+
+
+/*---------------------------------------------------------------------------*/
+
+#if SHINY_COMPILER == SHINY_COMPILER_GNUC
+#include <sys/types.h>
+#include <stdint.h>
+#endif
+
+
+/*---------------------------------------------------------------------------*/
+
+struct _ShinyNode;
+struct _ShinyZone;
+
+typedef struct _ShinyNode* ShinyNodeCache;
+typedef struct _ShinyNode* ShinyNodeTable;
+
+/*---------------------------------------------------------------------------*/
+
+#define SHINY_API
+
+/*---------------------------------------------------------------------------*/
+
+#if SHINY_COMPILER == SHINY_COMPILER_MSVC
+# define SHINY_INLINE __inline
+# define SHINY_UNUSED
+#elif SHINY_COMPILER == SHINY_COMPILER_GNUC
+# define SHINY_INLINE inline
+# define SHINY_UNUSED __attribute__((unused))
+#elif SHINY_COMPILER == SHINY_COMPILER_OTHER
+# define SHINY_INLINE inline
+# define SHINY_UNUSED
+#endif
+
+
+/*---------------------------------------------------------------------------*/
+
+#if SHINY_COMPILER == SHINY_COMPILER_MSVC
+ typedef int int32_t;
+ typedef unsigned int uint32_t;
+
+ typedef __int64 int64_t;
+ typedef unsigned __int64 uint64_t;
+
+/*
+#elif defined(__CYGWIN__)
+ typedef u_int32_t uint32_t;
+ typedef u_int64_t uint64_t;
+*/
+#endif
+
+ typedef uint64_t shinytick_t;
+
+#if __cplusplus
+} /* end of extern "C" */
+#endif
+
+#endif /* SHINY_PREREQS_H */
diff --git a/src/Shiny/ShinyTools.c b/src/Shiny/ShinyTools.c
new file mode 100644
index 000000000..4058e2285
--- /dev/null
+++ b/src/Shiny/ShinyTools.c
@@ -0,0 +1,116 @@
+/*
+The MIT License
+
+Copyright (c) 2007-2010 Aidin Abedi http://code.google.com/p/shinyprofiler/
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#ifdef SLIC3R_PROFILE
+
+#include "ShinyTools.h"
+
+#if SHINY_PLATFORM == SHINY_PLATFORM_WIN32
+#define WIN32_LEAN_AND_MEAN
+#ifndef NOMINMAX
+ #define NOMINMAX
+#endif /* NOMINMAX */
+#include <windows.h>
+
+#elif SHINY_PLATFORM == SHINY_PLATFORM_POSIX
+#include <sys/time.h>
+#endif
+
+
+/*---------------------------------------------------------------------------*/
+
+const ShinyTimeUnit* ShinyGetTimeUnit(float ticks) {
+ static ShinyTimeUnit units[4] = { 0 };
+
+ if (units[0].tickFreq == 0) { /* auto initialize first time */
+ units[0].tickFreq = ShinyGetTickFreq() / 1.0f;
+ units[0].invTickFreq = ShinyGetTickInvFreq() * 1.0f;
+ units[0].suffix = "s";
+
+ units[1].tickFreq = ShinyGetTickFreq() / 1000.0f;
+ units[1].invTickFreq = ShinyGetTickInvFreq() * 1000.0f;
+ units[1].suffix = "ms";
+
+ units[2].tickFreq = ShinyGetTickFreq() / 1000000.0f;
+ units[2].invTickFreq = ShinyGetTickInvFreq() * 1000000.0f;
+ units[2].suffix = "us";
+
+ units[3].tickFreq = ShinyGetTickFreq() / 1000000000.0f;
+ units[3].invTickFreq = ShinyGetTickInvFreq() * 1000000000.0f;
+ units[3].suffix = "ns";
+ }
+
+ if (units[0].tickFreq < ticks) return &units[0];
+ else if (units[1].tickFreq < ticks) return &units[1];
+ else if (units[2].tickFreq < ticks) return &units[2];
+ else return &units[3];
+}
+
+
+/*---------------------------------------------------------------------------*/
+
+#if SHINY_PLATFORM == SHINY_PLATFORM_WIN32
+
+void ShinyGetTicks(shinytick_t *p) {
+ QueryPerformanceCounter((LARGE_INTEGER*)(p));
+}
+
+shinytick_t ShinyGetTickFreq(void) {
+ static shinytick_t freq = 0;
+ if (freq == 0) QueryPerformanceFrequency((LARGE_INTEGER*)(&freq));
+ return freq;
+}
+
+float ShinyGetTickInvFreq(void) {
+ static float invfreq = 0;
+ if (invfreq == 0) invfreq = 1.0f / ShinyGetTickFreq();
+ return invfreq;
+}
+
+
+/*---------------------------------------------------------------------------*/
+
+#elif SHINY_PLATFORM == SHINY_PLATFORM_POSIX
+
+//#include <time.h>
+//#include <sys/time.h>
+
+void ShinyGetTicks(shinytick_t *p) {
+ struct timeval time;
+ gettimeofday(&time, NULL);
+
+ *p = time.tv_sec * 1000000 + time.tv_usec;
+}
+
+shinytick_t ShinyGetTickFreq(void) {
+ return 1000000;
+}
+
+float ShinyGetTickInvFreq(void) {
+ return 1.0f / 1000000.0f;
+}
+
+#endif
+
+#endif /* SLIC3R_PROFILE */
diff --git a/src/Shiny/ShinyTools.h b/src/Shiny/ShinyTools.h
new file mode 100644
index 000000000..379703ee6
--- /dev/null
+++ b/src/Shiny/ShinyTools.h
@@ -0,0 +1,57 @@
+/*
+The MIT License
+
+Copyright (c) 2007-2010 Aidin Abedi http://code.google.com/p/shinyprofiler/
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#ifndef SHINY_TOOLS_H
+#define SHINY_TOOLS_H
+
+#include "ShinyPrereqs.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*---------------------------------------------------------------------------*/
+
+typedef struct {
+ float tickFreq;
+ float invTickFreq;
+ const char* suffix;
+} ShinyTimeUnit;
+
+
+/*---------------------------------------------------------------------------*/
+
+SHINY_API const ShinyTimeUnit* ShinyGetTimeUnit(float ticks);
+
+SHINY_API void ShinyGetTicks(shinytick_t *p);
+
+SHINY_API shinytick_t ShinyGetTickFreq(void);
+
+SHINY_API float ShinyGetTickInvFreq(void);
+
+#if __cplusplus
+} /* end of extern "C" */
+#endif
+
+#endif /* SHINY_TOOLS_H */
diff --git a/src/Shiny/ShinyVersion.h b/src/Shiny/ShinyVersion.h
new file mode 100644
index 000000000..fe6cd4a33
--- /dev/null
+++ b/src/Shiny/ShinyVersion.h
@@ -0,0 +1,37 @@
+/*
+The MIT License
+
+Copyright (c) 2007-2010 Aidin Abedi http://code.google.com/p/shinyprofiler/
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#ifndef SHINY_VERSION_H
+#define SHINY_VERSION_H
+
+
+/*---------------------------------------------------------------------------*/
+
+#define SHINY_VERSION "2.6 RC1"
+#define SHINY_SHORTNAME "Shiny"
+#define SHINY_FULLNAME "Shiny Profiler"
+#define SHINY_COPYRIGHT "Copyright (C) 2007-2010 Aidin Abedi"
+#define SHINY_DESCRIPTION "Shiny is a state of the art profiler designed to help finding bottlenecks in your project."
+
+#endif /* SHINY_VERSION_H */
diff --git a/src/Shiny/ShinyZone.c b/src/Shiny/ShinyZone.c
new file mode 100644
index 000000000..99d90d927
--- /dev/null
+++ b/src/Shiny/ShinyZone.c
@@ -0,0 +1,201 @@
+/*
+The MIT License
+
+Copyright (c) 2007-2010 Aidin Abedi http://code.google.com/p/shinyprofiler/
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#ifdef SLIC3R_PROFILE
+
+#include "ShinyZone.h"
+
+#include <memory.h>
+
+/*---------------------------------------------------------------------------*/
+
+void ShinyZone_preUpdateChain(ShinyZone *first) {
+ ShinyZone* zone = first;
+
+ while (zone) {
+ ShinyData_clearCurrent(&(zone->data));
+ zone = zone->next;
+ }
+}
+
+
+/*---------------------------------------------------------------------------*/
+
+void ShinyZone_updateChain(ShinyZone *first, float a_damping) {
+ ShinyZone* zone = first;
+
+ do {
+ ShinyData_computeAverage(&(zone->data), a_damping);
+ zone = zone->next;
+ } while (zone);
+}
+
+
+/*---------------------------------------------------------------------------*/
+
+void ShinyZone_updateChainClean(ShinyZone *first) {
+ ShinyZone* zone = first;
+
+ do {
+ ShinyData_copyAverage(&(zone->data));
+ zone = zone->next;
+ } while (zone);
+}
+
+
+/*---------------------------------------------------------------------------*/
+
+void ShinyZone_resetChain(ShinyZone *first) {
+ ShinyZone* zone = first, *temp;
+
+ do {
+ zone->_state = SHINY_ZONE_STATE_HIDDEN;
+ temp = zone->next;
+ zone->next = NULL;
+ zone = temp;
+ } while (zone);
+}
+
+/*---------------------------------------------------------------------------*/
+
+/* A Linked-List Memory Sort
+ by Philip J. Erdelsky
+ pje@efgh.com
+ http://www.alumni.caltech.edu/~pje/
+
+ Modified by Aidin Abedi
+*/
+
+ShinyZone* ShinyZone_sortChain(ShinyZone **first) /* return ptr to last zone */
+{
+ ShinyZone *p = *first;
+
+ unsigned base;
+ unsigned long block_size;
+
+ struct tape
+ {
+ ShinyZone *first, *last;
+ unsigned long count;
+ } tape[4];
+
+ /* Distribute the records alternately to tape[0] and tape[1]. */
+
+ tape[0].count = tape[1].count = 0L;
+ tape[0].first = NULL;
+ base = 0;
+ while (p != NULL)
+ {
+ ShinyZone *next = p->next;
+ p->next = tape[base].first;
+ tape[base].first = p;
+ tape[base].count++;
+ p = next;
+ base ^= 1;
+ }
+
+ /* If the list is empty or contains only a single record, then */
+ /* tape[1].count == 0L and this part is vacuous. */
+
+ for (base = 0, block_size = 1L; tape[base+1].count != 0L;
+ base ^= 2, block_size <<= 1)
+ {
+ int dest;
+ struct tape *tape0, *tape1;
+ tape0 = tape + base;
+ tape1 = tape + base + 1;
+ dest = base ^ 2;
+ tape[dest].count = tape[dest+1].count = 0;
+ for (; tape0->count != 0; dest ^= 1)
+ {
+ unsigned long n0, n1;
+ struct tape *output_tape = tape + dest;
+ n0 = n1 = block_size;
+ while (1)
+ {
+ ShinyZone *chosen_record;
+ struct tape *chosen_tape;
+ if (n0 == 0 || tape0->count == 0)
+ {
+ if (n1 == 0 || tape1->count == 0)
+ break;
+ chosen_tape = tape1;
+ n1--;
+ }
+ else if (n1 == 0 || tape1->count == 0)
+ {
+ chosen_tape = tape0;
+ n0--;
+ }
+ else if (ShinyZone_compare(tape1->first, tape0->first) > 0)
+ {
+ chosen_tape = tape1;
+ n1--;
+ }
+ else
+ {
+ chosen_tape = tape0;
+ n0--;
+ }
+ chosen_tape->count--;
+ chosen_record = chosen_tape->first;
+ chosen_tape->first = chosen_record->next;
+ if (output_tape->count == 0)
+ output_tape->first = chosen_record;
+ else
+ output_tape->last->next = chosen_record;
+ output_tape->last = chosen_record;
+ output_tape->count++;
+ }
+ }
+ }
+
+ if (tape[base].count > 1L) {
+ ShinyZone* last = tape[base].last;
+ *first = tape[base].first;
+ last->next = NULL;
+ return last;
+
+ } else {
+ return NULL;
+ }
+}
+
+
+/*---------------------------------------------------------------------------*/
+
+void ShinyZone_clear(ShinyZone* self) {
+ memset(self, 0, sizeof(ShinyZone));
+}
+
+
+/*---------------------------------------------------------------------------*/
+
+void ShinyZone_enumerateZones(const ShinyZone* a_zone, void (*a_func)(const ShinyZone*)) {
+ a_func(a_zone);
+
+ if (a_zone->next) ShinyZone_enumerateZones(a_zone->next, a_func);
+}
+
+#endif /* SLIC3R_PROFILE */
diff --git a/src/Shiny/ShinyZone.h b/src/Shiny/ShinyZone.h
new file mode 100644
index 000000000..dde0d3624
--- /dev/null
+++ b/src/Shiny/ShinyZone.h
@@ -0,0 +1,91 @@
+/*
+The MIT License
+
+Copyright (c) 2007-2010 Aidin Abedi http://code.google.com/p/shinyprofiler/
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#ifndef SHINY_ZONE_H
+#define SHINY_ZONE_H
+
+#include "ShinyData.h"
+#include <memory.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*---------------------------------------------------------------------------*/
+
+#define SHINY_ZONE_STATE_HIDDEN 0
+#define SHINY_ZONE_STATE_INITIALIZED 1
+#define SHINY_ZONE_STATE_UPDATING 2
+
+
+/*---------------------------------------------------------------------------*/
+
+typedef struct _ShinyZone {
+ struct _ShinyZone* next;
+ int _state;
+ const char* name;
+ ShinyData data;
+} ShinyZone;
+
+
+/*---------------------------------------------------------------------------*/
+
+SHINY_INLINE void ShinyZone_init(ShinyZone *self, ShinyZone* a_prev) {
+ self->_state = SHINY_ZONE_STATE_INITIALIZED;
+ a_prev->next = self;
+}
+
+SHINY_INLINE void ShinyZone_uninit(ShinyZone *self) {
+ self->_state = SHINY_ZONE_STATE_HIDDEN;
+ self->next = NULL;
+}
+
+SHINY_API void ShinyZone_preUpdateChain(ShinyZone *first);
+SHINY_API void ShinyZone_updateChain(ShinyZone *first, float a_damping);
+SHINY_API void ShinyZone_updateChainClean(ShinyZone *first);
+
+SHINY_API void ShinyZone_resetChain(ShinyZone *first);
+
+SHINY_API ShinyZone* ShinyZone_sortChain(ShinyZone **first);
+
+SHINY_INLINE float ShinyZone_compare(ShinyZone *a, ShinyZone *b) {
+ return a->data.selfTicks.avg - b->data.selfTicks.avg;
+}
+
+SHINY_API void ShinyZone_clear(ShinyZone* self);
+
+SHINY_API void ShinyZone_enumerateZones(const ShinyZone* a_zone, void (*a_func)(const ShinyZone*));
+
+#if __cplusplus
+} /* end of extern "C" */
+
+template <class T>
+void ShinyZone_enumerateZones(const ShinyZone* a_zone, T* a_this, void (T::*a_func)(const ShinyZone*)) {
+ (a_this->*a_func)(a_zone);
+
+ if (a_zone->next) ShinyZone_enumerateZones(a_zone->next, a_this, a_func);
+}
+#endif /* __cplusplus */
+
+#endif /* SHINY_ZONE_H */