diff --git a/include/Orange/Core/Array.h b/include/Orange/Core/Array.h index 7428b7e..e8f3995 100644 --- a/include/Orange/Core/Array.h +++ b/include/Orange/Core/Array.h @@ -1,182 +1,54 @@ #pragma once +#include #include -#include -#include namespace orange { - template - class SmallArray + template + struct Array { - public: + constexpr Array() + : m_data{ } {} - SmallArray() {} - SmallArray(size_t size) { Resize(size); } - SmallArray(Span span) + constexpr Array(const T components[Size]) { - Reserve(span.size); - for (const auto& val : span) - PushBack(val); + Copy(&components[0], &components[Size], m_data.begin()); } - SmallArray (const SmallArray&) = delete; - SmallArray& operator = (const SmallArray&) = delete; - - ~SmallArray() + template + constexpr Array(const Args&... args) + : m_data {{ args... }} { - for (size_t i = 0; i < m_size; i++) - Ptr(i)->~T(); - - if (m_capacity > N) - delete[] u.m_ptr; + static_assert(sizeof...(Args) == Size); } - template - bool operator == (const Span& x) + constexpr Array(const Array& other) = default; + + constexpr T& operator[](size_t index) { return m_data[index]; } + constexpr const T& operator[](size_t index) const { return m_data[index]; } + + + constexpr const T* begin() const { return &m_data[0]; } + constexpr T* begin() { return &m_data[0]; } + constexpr const T* end() const { return &m_data[Size]; } + constexpr T* end() { return &m_data[Size]; } + + + constexpr bool operator==(const Array& other) const { - return Span(*this) == x; + return Equal(begin(), end(), other.begin()); } - bool operator == (const char *x) + constexpr bool operator!=(const Array& other) const { - return Span(*this) == StringView(x); + return !operator==(other); } - void Reserve(size_t n) - { - n = PickCapacity(n); - - if (n <= m_capacity) - return; - - Storage* data = new Storage[n]; - - for (size_t i = 0; i < m_size; i++) - { - new (&data[i]) T(Move(*Ptr(i))); - Ptr(i)->~T(); - } - - if (m_capacity > N) - delete[] u.m_ptr; - - m_capacity = n; - u.m_ptr = data; - } - - size_t Size() const { return m_size; } - - const T* Data() const { return Ptr(0); } - T* Data() { return Ptr(0); } - - void Resize(size_t n) - { - Reserve(n); - - for (size_t i = n; i < m_size; i++) - Ptr(i)->~T(); - - for (size_t i = m_size; i < n; i++) - new (Ptr(i)) T(); - - m_size = n; - } - - void PushBack(const T& object) - { - Reserve(m_size + 1); - new (Ptr(m_size++)) T(object); - } - - void PushBack(T&& object) - { - Reserve(m_size + 1); - new (Ptr(m_size++)) T(Move(object)); - } - - template - void EmplaceBack(Args... args) - { - Reserve(m_size + 1); - new (Ptr(m_size++)) T(Forward(args)...); - } - - void Erase(size_t idx) - { - Ptr(idx)->~T(); - - for (size_t i = idx; i < m_size - 1; i++) - { - new (Ptr(i)) T(Move(*Ptr(i + 1))); - Ptr(i + 1)->~T(); - } - } - - void PopBack() - { - Ptr(--m_size)->~T(); - } - - bool Empty() const - { - return Size() == 0; - } - - T& operator [] (size_t idx) { return *Ptr(idx); } - const T& operator [] (size_t idx) const { return *Ptr(idx); } - - T* begin() { return Ptr(0); } - const T* begin() const { return Ptr(0); } - - T* end() { return Ptr(m_size); } - const T* end() const { return Ptr(m_size); } - - T& front() { return *Ptr(0); } - const T& front() const { return *Ptr(0); } - - T& back() { return *Ptr(m_size - 1); } - const T& back() const { return *Ptr(m_size - 1); } - - operator Span() { return Span(*this); } - private: - using Storage = AlignedStorage; - size_t m_capacity = N; - size_t m_size = 0; - - union - { - Storage* m_ptr; - Storage m_data[sizeof(T) * N]; - } u; - - size_t PickCapacity(size_t n) { - size_t capacity = m_capacity; - - while (capacity < n) - capacity = (capacity * 2) + 2; - - return capacity; - } - - T* Ptr(size_t idx) { - return m_capacity == N - ? reinterpret_cast(&u.m_data[idx]) - : reinterpret_cast(&u.m_ptr[idx]); - } - - const T* Ptr(size_t idx) const - { - return m_capacity == N - ? reinterpret_cast(&u.m_data[idx]) - : reinterpret_cast(&u.m_ptr[idx]); - } + T m_data[Size]; }; - template - using Array = SmallArray; - } diff --git a/include/Orange/Core/Parse.h b/include/Orange/Core/Parse.h index 5064fca..1a3ed5a 100644 --- a/include/Orange/Core/Parse.h +++ b/include/Orange/Core/Parse.h @@ -1,6 +1,6 @@ #pragma once -#include "Orange/Core/Array.h" +#include "Orange/Core/Vector.h" #include #include @@ -68,7 +68,7 @@ namespace orange::stream return Consume(first, end, " \t"); } - template > + template > size_t ReadOrAdvance(const char*& first, const char* end, StringView delims, size_t advancement = 0, OutArray* array = nullptr) { size_t count = 0; @@ -88,7 +88,7 @@ namespace orange::stream return count; } - template > + template > size_t ReadString(const char*& first, const char* end, StringView delims, OutArray& array) { return ReadOrAdvance(first, end, delims, 0, &array); diff --git a/include/Orange/Core/Traits.h b/include/Orange/Core/Traits.h index 494771a..d154ba3 100644 --- a/include/Orange/Core/Traits.h +++ b/include/Orange/Core/Traits.h @@ -60,4 +60,120 @@ namespace orange { return Min( Max( val, minVal ), maxVal ); } + + // Transformations + + template + OutputIt Transform(InputIt inFirst, InputIt inLast, + OutputIt outFirst, UnaryOperation unaryOp) + { + while (inFirst != inLast) + *outFirst++ = unaryOp(*inFirst++); + return outFirst; + } + + template + OutputIt Transform(InputIt1 first1, InputIt1 last1, InputIt2 first2, + OutputIt outFirst, BinaryOperation binOp) + { + while (first1 != last1) + *outFirst++ = binOp(*first1++, *first2++); + return outFirst; + } + + template + T TransformResult(InputIt first, InputIt last, UnaryOperation op) + { + T result; + Transform(first, last, result.begin(), op); + return result; + } + + template + T TransformResult(InputIt1 first1, InputIt1 last1, InputIt2 first2, BinaryOperation op) + { + T result; + Transform(first1, last1, first2, result.begin(), op); + return result; + } + + template + constexpr T Accumulate(InputIt first, InputIt last, T init) + { + for (; first != last; ++first) + init = Move(init) + *first; + return init; + } + + template + constexpr T Accumulate(InputIt first, InputIt last, T init, BinaryOperation op) + { + for (; first != last; ++first) + init = op(Move(init), *first); + return init; + } + + template + bool Equal(InputIt1 first1, InputIt1 last1, InputIt2 first2) + { + for (; first1 != last1; ++first1, ++first2) + { + if (!(*first1 == *first2)) + return false; + } + return true; + } + + template + bool Equal(InputIt1 first1, InputIt1 last1, InputIt2 first2, BinaryPredicate p) + { + for (; first1 != last1; ++first1, ++first2) + { + if (!p(*first1, *first2)) + return false; + } + return true; + } + + template + OutputIt Copy(InputIt first, InputIt last, OutputIt d_first) + { + for (; first != last; (void)++first, (void)++d_first) + *d_first = *first; + return d_first; + } + + template + OutputIt CopyIf(InputIt first, InputIt last, + OutputIt d_first, UnaryPredicate pred) + { + for (; first != last; ++first) + { + if (pred(*first)) + { + *d_first = *first; + ++d_first; + } + } + return d_first; + } + + template + void Fill(ForwardIt first, ForwardIt last, const T& value) + { + for (; first != last; ++first) + *first = value; + } + + // Math ops + namespace math + { + template T Negate(const T& x) { return -x; } + + template T Add (const T& x, const T& y) { return x + y; } + template T Subtract (const T& x, const T& y) { return x - y; } + template T Multiply (const T& x, const T& y) { return x * y; } + template T Divide (const T& x, const T& y) { return x / y; } + template T Modulo (const T& x, const T& y) { return x % y; } + } } diff --git a/include/Orange/Core/Vector.h b/include/Orange/Core/Vector.h new file mode 100644 index 0000000..775fe22 --- /dev/null +++ b/include/Orange/Core/Vector.h @@ -0,0 +1,182 @@ +#pragma once + +#include +#include +#include + +namespace orange +{ + template + class SmallVector + { + public: + + SmallVector() {} + SmallVector(size_t size) { Resize(size); } + SmallVector(Span span) + { + Reserve(span.size); + for (const auto& val : span) + PushBack(val); + } + + SmallVector (const SmallVector&) = delete; + SmallVector& operator = (const SmallVector&) = delete; + + ~SmallVector() + { + for (size_t i = 0; i < m_size; i++) + Ptr(i)->~T(); + + if (m_capacity > N) + delete[] u.m_ptr; + } + + template + bool operator == (const Span& x) + { + return Span(*this) == x; + } + + bool operator == (const char *x) + { + return Span(*this) == StringView(x); + } + + void Reserve(size_t n) + { + n = PickCapacity(n); + + if (n <= m_capacity) + return; + + Storage* data = new Storage[n]; + + for (size_t i = 0; i < m_size; i++) + { + new (&data[i]) T(Move(*Ptr(i))); + Ptr(i)->~T(); + } + + if (m_capacity > N) + delete[] u.m_ptr; + + m_capacity = n; + u.m_ptr = data; + } + + size_t Size() const { return m_size; } + + const T* Data() const { return Ptr(0); } + T* Data() { return Ptr(0); } + + void Resize(size_t n) + { + Reserve(n); + + for (size_t i = n; i < m_size; i++) + Ptr(i)->~T(); + + for (size_t i = m_size; i < n; i++) + new (Ptr(i)) T(); + + m_size = n; + } + + void PushBack(const T& object) + { + Reserve(m_size + 1); + new (Ptr(m_size++)) T(object); + } + + void PushBack(T&& object) + { + Reserve(m_size + 1); + new (Ptr(m_size++)) T(Move(object)); + } + + template + void EmplaceBack(Args... args) + { + Reserve(m_size + 1); + new (Ptr(m_size++)) T(Forward(args)...); + } + + void Erase(size_t idx) + { + Ptr(idx)->~T(); + + for (size_t i = idx; i < m_size - 1; i++) + { + new (Ptr(i)) T(Move(*Ptr(i + 1))); + Ptr(i + 1)->~T(); + } + } + + void PopBack() + { + Ptr(--m_size)->~T(); + } + + bool Empty() const + { + return Size() == 0; + } + + T& operator [] (size_t idx) { return *Ptr(idx); } + const T& operator [] (size_t idx) const { return *Ptr(idx); } + + T* begin() { return Ptr(0); } + const T* begin() const { return Ptr(0); } + + T* end() { return Ptr(m_size); } + const T* end() const { return Ptr(m_size); } + + T& front() { return *Ptr(0); } + const T& front() const { return *Ptr(0); } + + T& back() { return *Ptr(m_size - 1); } + const T& back() const { return *Ptr(m_size - 1); } + + operator Span() { return Span(*this); } + + private: + using Storage = AlignedStorage; + + size_t m_capacity = N; + size_t m_size = 0; + + union + { + Storage* m_ptr; + Storage m_data[sizeof(T) * N]; + } u; + + size_t PickCapacity(size_t n) { + size_t capacity = m_capacity; + + while (capacity < n) + capacity = (capacity * 2) + 2; + + return capacity; + } + + T* Ptr(size_t idx) { + return m_capacity == N + ? reinterpret_cast(&u.m_data[idx]) + : reinterpret_cast(&u.m_ptr[idx]); + } + + const T* Ptr(size_t idx) const + { + return m_capacity == N + ? reinterpret_cast(&u.m_data[idx]) + : reinterpret_cast(&u.m_ptr[idx]); + } + + }; + + template + using Vector = SmallVector; + +} diff --git a/include/Orange/Math/Basic.h b/include/Orange/Math/Basic.h new file mode 100644 index 0000000..301c23e --- /dev/null +++ b/include/Orange/Math/Basic.h @@ -0,0 +1,30 @@ +#pragma once + +#include + +namespace orange +{ + template + struct DefaultLengthTypeResolver + { + using LengthType = float; + }; + + template <> + struct DefaultLengthTypeResolver + { + using LengthType = double; + }; + + template <> + struct DefaultLengthTypeResolver + { + using LengthType = long double; + }; + + template ::LengthType> + constexpr J rcp(const T& a) + { + return static_cast(1) / static_cast(a); + } +} diff --git a/include/Orange/Math/Vector.h b/include/Orange/Math/Vector.h new file mode 100644 index 0000000..7174e62 --- /dev/null +++ b/include/Orange/Math/Vector.h @@ -0,0 +1,275 @@ +#pragma once + +#include +#include +#include + +#include + +namespace orange +{ + template + struct Vec + { + using DefaultLengthType = DefaultLengthTypeResolver::LengthType; + using DefaultLengthVec = Vec; + + constexpr Vec() + : data{ } {} + + constexpr explicit Vec(T splat) + { + Fill(data.begin(), data.end(), splat); + } + + constexpr Vec(const T components[Size]) + { + Copy(&components[0], &components[Size], data.begin()); + } + + template + constexpr Vec(const Args&... args) + : data {{ args... }} + { + static_assert(sizeof...(Args) == Size); + } + + constexpr Vec(const Vec& other) = default; + + + constexpr T& operator[](size_t index) { return data[index]; } + constexpr const T& operator[](size_t index) const { return data[index]; } + + + constexpr const T* begin() const { return data.begin(); } + constexpr T* begin() { return data.begin(); } + constexpr const T* end() const { return data.end(); } + constexpr T* end() { return data.end(); } + + + constexpr bool operator==(const Vec& other) const + { + return Equal(begin(), end(), other.begin()); + } + + constexpr bool operator!=(const Vec& other) const + { + return !operator==(other); + } + + + template + constexpr Vec TransformResult(UnaryOperation op) const + { + return TransformResult(begin(), end(), op); + } + + template + constexpr Vec TransformResult(const T *other, BinaryOperation op) const + { + return TransformResult(begin(), end(), other, op); + } + + template + constexpr Vec TransformResult(const Vec& other, BinaryOperation op) const + { + return TransformResult(other.begin(), op); + } + + template + constexpr Vec& TransformInPlace(UnaryOperation op) + { + Transform(begin(), end(), begin(), op); + return *this; + } + + template + constexpr Vec& TransformInPlace(const T *other, BinaryOperation op) + { + Transform(begin(), end(), other, begin(), op); + return *this; + } + + template + constexpr Vec& TransformInPlace(const Vec& other, BinaryOperation op) + { + return TransformInPlace(other.begin(), op); + } + + + constexpr Vec operator-() const + { + return TransformResult(math::Negate); + } + + + constexpr Vec operator+(const Vec& other) const + { + return TransformResult(other, math::Add); + } + + constexpr Vec operator-(const Vec& other) const + { + return TransformResult(other, math::Subtract); + } + + constexpr Vec operator*(const Vec& other) const + { + return TransformResult(other, math::Multiply); + } + + constexpr Vec operator*(const T& scalar) const + { + return TransformResult([scalar](T value) { return value * scalar; }); + } + + constexpr Vec operator/(const Vec& other) const + { + return TransformResult(other, math::Divide); + } + + constexpr Vec operator/(const T& scalar) const + { + return TransformResult([scalar](T value) { return value / scalar; }); + } + + constexpr Vec operator%(const Vec& other) const + { + return TransformResult(other, math::Modulo); + } + + constexpr Vec operator%(const T& scalar) const + { + return TransformResult([scalar](T value) { return value % scalar; }); + } + + + constexpr Vec& operator+=(const Vec& other) + { + return TransformInPlace(math::Add); + } + + constexpr Vec& operator-=(const Vec& other) + { + return TransformInPlace(math::Subtract); + } + + constexpr Vec& operator*=(const Vec& other) + { + return TransformInPlace(math::Multiply); + } + + constexpr Vec& operator*=(const T& scalar) + { + return TransformInPlace([scalar](T value) { return value * scalar; }); + } + + constexpr Vec& operator/=(const Vec& other) + { + return TransformInPlace(math::Divide); + } + + constexpr Vec& operator/=(const T& scalar) + { + return TransformInPlace([scalar](T value) { return value / scalar; }); + } + + constexpr Vec& operator%=(const Vec& other) + { + return TransformInPlace(math::Modulo); + } + + constexpr Vec& operator%=(const T& scalar) + { + return TransformInPlace([scalar](T value) { return value % scalar; }); + } + + + static constexpr Vec Zero = Vec{ T{ 0 } }; + static constexpr Vec Identity = Vec{ T{ 1 } }; + + + // Align to 16 if the size is a multiple of 4 and T is 4 bytes in size. + // to take advantage of aligned load/stores. + static constexpr size_t Alignment = + (Size % 4zu == 0 && sizeof(T) == 4zu) + ? Max(16zu, alignof(T)) + : alignof(T); + + alignas(Alignment) Array data; + + }; + + template + constexpr Vec operator*(T scalar, const Vec& Vec) + { + return Vec.TransformResult([scalar](T value) { return scalar * value; }); + } + + template + constexpr Vec operator/(T scalar, const Vec& Vec) + { + return Vec.TransformResult([scalar](T value) { return scalar / value; }); + } + + template + constexpr Vec operator%(T scalar, const Vec& Vec) + { + return Vec.TransformResult([scalar](T value) { return scalar % value; }); + } + + + template + constexpr T accumulate(const Vec& a, T init = T{}) + { + return Accumulate(a.begin(), a.end(), init); + } + + template + constexpr T dot(const Vec& a, const Vec& b) + { + return accumulate(a * b); + } + + template + constexpr T lengthSqr(const Vec& a) + { + return dot(a, a); + } + + template ::DefaultLengthType> + constexpr J length(const Vec& a) + { + sqrtf(J{ lengthSqr(a) }); + } + + template ::DefaultLengthType> + constexpr Vec normalize(const Vec& a) + { + return a * J{ rcp( length(a) ) }; + } + + template ::DefaultLengthType> + constexpr Vec rcp(const Vec& a) + { + return TransformResult>(a.begin(), a.end(), [](T value){ return rcp(value); }); + } + + template + constexpr bool empty(const Vec& a) + { + return a == Vec::Zero; + } + + template + constexpr bool identity(const Vec& a) + { + return a == Vec::Identity; + } + + using Vec1 = Vec; + using Vec2 = Vec; + using Vec3 = Vec; + using Vec4 = Vec; + +} diff --git a/include/Orange/Render/Swapchain.h b/include/Orange/Render/Swapchain.h index 935a48d..77a7202 100644 --- a/include/Orange/Render/Swapchain.h +++ b/include/Orange/Render/Swapchain.h @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include @@ -51,13 +51,13 @@ namespace orange VkExtent2D m_extent; VkSwapchainKHR m_swapchain; - SmallArray m_images; - SmallArray m_imageViews; + SmallVector m_images; + SmallVector m_imageViews; - SmallArray m_commandBuffers; - SmallArray m_imageAvailableSemaphores; - SmallArray m_renderFinishedSemaphores; - SmallArray m_inFlightFences; + SmallVector m_commandBuffers; + SmallVector m_imageAvailableSemaphores; + SmallVector m_renderFinishedSemaphores; + SmallVector m_inFlightFences; uint32_t m_currentFrame = 0; uint32_t m_currentImage = 0; diff --git a/src/Apps/Tools/CubeTest.cpp b/src/Apps/Tools/CubeTest.cpp index fe04f12..c08025c 100644 --- a/src/Apps/Tools/CubeTest.cpp +++ b/src/Apps/Tools/CubeTest.cpp @@ -1,7 +1,9 @@ -#include "Orange/Core/Array.h" +#include +#include #include "Orange/Core/Span.h" #include #include +#include #include #include @@ -16,7 +18,7 @@ Result ParseOBJ(StringView buffer) const char* end = buffer.data + buffer.size; while (obj != end) { - SmallArray element; + SmallVector element; stream::ReadString(obj, end, " #\n", element); if (element == "v" || element == "vn" || element == "vt") @@ -37,7 +39,7 @@ Result ParseOBJ(StringView buffer) else if (element == "g" || element == "o") { stream::ConsumeSpace(obj, end); - SmallArray name; + SmallVector name; stream::ReadString(obj, end, " #\n", name); name.PushBack('\0'); diff --git a/src/Orange/Render/RenderContext_Init.cpp b/src/Orange/Render/RenderContext_Init.cpp index 36f379f..d89796b 100644 --- a/src/Orange/Render/RenderContext_Init.cpp +++ b/src/Orange/Render/RenderContext_Init.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include #include @@ -9,7 +9,7 @@ namespace orange { static VulkanResult CreateVkInstance(const char* appName) { - SmallArray instanceExtensions; + SmallVector instanceExtensions; { auto r_tempWindow = Window::Create(); if (!r_tempWindow) @@ -49,7 +49,7 @@ namespace orange static Result PickQueueFamilyIndex(VkPhysicalDevice physicalDevice) { - SmallArray queueFamilyProperties; + SmallVector queueFamilyProperties; VkEnumerate(vkGetPhysicalDeviceQueueFamilyProperties, queueFamilyProperties, physicalDevice); for (uint32_t i = 0; i < queueFamilyProperties.Size(); i++) @@ -80,7 +80,7 @@ namespace orange static Result PickPhysicalDevice(VkInstance instance) { - SmallArray physicalDevices; + SmallVector physicalDevices; VkEnumerate(vkEnumeratePhysicalDevices, physicalDevices, instance); VkPhysicalDevice bestPhysicalDevice = VK_NULL_HANDLE; diff --git a/src/Orange/Render/Swapchain.cpp b/src/Orange/Render/Swapchain.cpp index 6f2b9e5..b1918cd 100644 --- a/src/Orange/Render/Swapchain.cpp +++ b/src/Orange/Render/Swapchain.cpp @@ -11,7 +11,7 @@ namespace orange static Result ChooseSwapChainFormat(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface) { - SmallArray surfaceFormats; + SmallVector surfaceFormats; if (!VkEnumerate(vkGetPhysicalDeviceSurfaceFormatsKHR, surfaceFormats, physicalDevice, surface)) { log::err("Surface supports no formats"); @@ -29,7 +29,7 @@ namespace orange static VkPresentModeKHR ChoosePresentMode(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface) { - SmallArray presentModes; + SmallVector presentModes; VkEnumerate(vkGetPhysicalDeviceSurfacePresentModesKHR, presentModes, physicalDevice, surface); for (auto& presentMode : presentModes) { if (presentMode == VK_PRESENT_MODE_MAILBOX_KHR) return presentMode; } @@ -99,11 +99,11 @@ namespace orange if (vkCreateSwapchainKHR(context.Device(), &swapchainInfo, nullptr, &swapchain) != VK_SUCCESS) return Result::PrintError("Failed to create swapchain"); - SmallArray swapchainImages; + SmallVector swapchainImages; if (!VkEnumerate(vkGetSwapchainImagesKHR, swapchainImages, context.Device(), swapchain)) return Result::PrintError("Failed to get swapchain images"); - SmallArray swapchainImageViews{ swapchainImages.Size() }; + SmallVector swapchainImageViews{ swapchainImages.Size() }; for (size_t i = 0; i < swapchainImages.Size(); i++) { VkImageViewCreateInfo imageViewInfo = @@ -119,7 +119,7 @@ namespace orange return Result::PrintError("Failed to get swapchain image view"); } - SmallArray commandBuffers{ DefaultFramesInFlight }; + SmallVector commandBuffers{ DefaultFramesInFlight }; { VkCommandBufferAllocateInfo commandBufferInfo = { @@ -133,9 +133,9 @@ namespace orange return Result::PrintError("Failed to get swapchain image view"); } - SmallArray imageAvailableSemaphores{ DefaultFramesInFlight }; - SmallArray renderFinishedSemaphores{ DefaultFramesInFlight }; - SmallArray inFlightFences { DefaultFramesInFlight }; + SmallVector imageAvailableSemaphores{ DefaultFramesInFlight }; + SmallVector renderFinishedSemaphores{ DefaultFramesInFlight }; + SmallVector inFlightFences { DefaultFramesInFlight }; for (uint32_t i = 0; i < DefaultFramesInFlight; i++) { auto r_fence = context.CreateFence(true);