{"id":378390,"date":"2024-06-09T15:03:31","date_gmt":"2024-06-09T15:03:31","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=378390"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=378390","title":{"rendered":"<span>\u042f\u0437\u044b\u043a \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u041a\u0435\u0434\u0440. \u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441, \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u043e\u0448\u0438\u0431\u043e\u043a, \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0441 \u044f\u0437\u044b\u043a\u043e\u043c \u0421 \u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f.<\/p>\n<p>\u041f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0430\u044f \u0441\u0442\u0430\u0442\u044c\u044f <a href=\"https:\/\/habr.com\/ru\/articles\/816917\" rel=\"noopener noreferrer nofollow\">\u0437\u0434\u0435\u0441\u044c<\/a>.<\/p>\n<h3>\u041e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u0430<\/h3>\n<pre><code class=\"fsharp\">val identity = Matrix4 1 0 0 0                        0 1 0 0                        0 0 1 0                        0 0 0 1<\/code><\/pre>\n<p>\u041f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u043e\u043b\u0435\u0439 \u0445\u043e\u0440\u043e\u0448\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442 \u0434\u043b\u044f \u043c\u0430\u0442\u0440\u0438\u0446. \u0426\u0435\u043b\u043e\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u0439 \u043b\u0438\u0442\u0435\u0440\u0430\u043b \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u0442\u0430\u043a\u0436\u0435 \u0434\u043b\u044f \u0432\u0435\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432 \u0447\u0438\u0441\u0435\u043b.<\/p>\n<pre><code class=\"fsharp\">control.set_width width         set_height control.measure_height         arrange  import num::vector_f32::Vector3                         Vector4             vector_i32::Vector2i<\/code><\/pre>\n<p>\u041c\u0435\u0442\u043e\u0434\u044b <code>set_width<\/code>, <code>set_height<\/code> \u0438 <code>arrange<\/code> \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043d\u0430 \u043e\u0434\u043d\u043e\u0439 \u0438 \u0442\u043e\u0439 \u0436\u0435 \u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0435 <code>control<\/code>.<\/p>\n<pre><code class=\"fsharp\">let enabled_extension_names = [\"VK_EXT_debug_report\"                                \"VK_EXT_debug_utils\"                                \"VK_KHR_surface\"                                \"VK_KHR_xcb_surface\"                                \"VK_KHR_xlib_surface\"]<\/code><\/pre>\n<p>\u0417\u0430\u043f\u044f\u0442\u044b\u0435 \u043c\u0435\u0436\u0434\u0443 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u043c\u0438 \u043d\u0435 \u043d\u0443\u0436\u043d\u044b, \u0435\u0441\u043b\u0438 \u043a\u0430\u0436\u0434\u044b\u0439 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043d\u0430 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0435 \u0438\u043b\u0438 \u0441\u0442\u0440\u043e\u043a\u0430\u0445. \u0423\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 \u043c\u0430\u0441\u0441\u0438\u0432 \u0431\u0443\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u043d \u0432 \u0421 \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u0441\u0435 \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u044b\u0435 \u043b\u0438\u0442\u0435\u0440\u0430\u043b\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0442 \u0442\u0438\u043f <code>CString<\/code>.<\/p>\n<pre><code class=\"fsharp\">text |> lines |> filter { line -> line.starts_with \"layout\" } |> map { remove_comment _ }<\/code><\/pre>\n<p>\u041e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u044b <code>|><\/code> \u0443\u0434\u043e\u0431\u043d\u043e \u0440\u0430\u0441\u043f\u043e\u043b\u0430\u0433\u0430\u0442\u044c \u0432 \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u0440\u044f\u0434. \u0417\u0430\u043c\u044b\u043a\u0430\u043d\u0438\u044f \u0441\u043e\u0437\u0434\u0430\u044e\u0442\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0444\u0438\u0433\u0443\u0440\u043d\u044b\u0445 \u0441\u043a\u043e\u0431\u043e\u043a. \u041a\u0430\u0436\u0434\u043e\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u0434\u0447\u0451\u0440\u043a\u0438\u0432\u0430\u043d\u0438\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440.<\/p>\n<pre><code class=\"fsharp\">let up_right = Vector3 left.as_f32 0 border_z let adjusted_size = size as f32 * 1.5 |> as_u32<\/code><\/pre>\n<p>\u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0442\u0438\u043f\u0430 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043a\u0430\u043a \u0432\u044b\u0437\u043e\u0432 \u043c\u0435\u0442\u043e\u0434\u0430.<\/p>\n<pre><code class=\"fsharp\">let thickness = (left = border.left                  right = border.right                  up = border.up                  down = border.down)  let sizes = List&lt;(u32, u32) width height>.new<\/code><\/pre>\n<p>\u041f\u043e\u043b\u044f \u043a\u043e\u0440\u0442\u0435\u0436\u0430 \u043d\u0435 \u0438\u043c\u0435\u044e\u0442 \u0438\u043c\u0451\u043d \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e, \u043e\u0431\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u043a \u043d\u0438\u043c \u043c\u043e\u0436\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e \u044f\u0432\u043d\u043e \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u043c.<\/p>\n<h4>\u0412\u043d\u0443\u0442\u0440\u0438\u0441\u0442\u0440\u043e\u0447\u043d\u043e\u0435 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u0442\u0438\u043f\u043e\u0432<\/h4>\n<pre><code class=\"fsharp\">type Entry =     path : String     created : DateTime          | File size : u32     | Directory entries : Slice&lt;Entry>                 | Local                 | Remote url : String<\/code><\/pre>\n<p><code>Entry<\/code> \u0438 <code>Directory<\/code> \u044d\u0442\u043e \u0442\u0438\u043f\u044b-\u0441\u0443\u043c\u043c\u044b, <code>Local<\/code> \u0438 <code>Remote<\/code> \u2014 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b. \u041f\u043e\u043b\u044f <code>path<\/code> \u0438 <code>created<\/code> \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u043a\u0430\u043a \u0434\u043b\u044f <code>Entry<\/code>, \u0442\u0430\u043a \u0438 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0438\u0437 \u043f\u043e\u0434\u0442\u0438\u043f\u043e\u0432.<\/p>\n<pre><code class=\"fsharp\">type Entry @abstract = struct     path : String     created : DateTime     is_directory : bool      | File size : u32     | Directory entries : Slice&lt;mut ref Entry>                 is_remote : bool                 | Remote url : String<\/code><\/pre>\n<p>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b <code>File<\/code> \u0438 <code>Directory<\/code> \u043d\u0430\u0441\u043b\u0435\u0434\u0443\u044e\u0442 \u043f\u043e\u043b\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b <code>Entry<\/code>. \u0421\u0441\u044b\u043b\u043a\u0430 \u0442\u0438\u043f\u0430 <code>mut ref Entry<\/code> \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043d\u0430 <code>File<\/code>, <code>Directory<\/code> \u0438\u043b\u0438 <code>Remote<\/code>.<\/p>\n<h3>\u041a\u043b\u0430\u0441\u0441\u044b \u0442\u0438\u043f\u043e\u0432<\/h3>\n<pre><code class=\"fsharp\">type Comparable = class     def (>) (rhs : Self) : bool     def (&lt;) (rhs : Self) : bool     def (>=) (rhs : Self) : bool     def (&lt;=) (rhs : Self) : bool  type Compare @virtual =     def compare (other : Self) : Ordering      def (>) (rhs : Self) =         let result = compare rhs         result == Ordering::Greater      ...      is Comparable<\/code><\/pre>\n<p>\u0422\u0438\u043f \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d \u043f\u0440\u0438\u043d\u0430\u0434\u043b\u0435\u0436\u0430\u0449\u0438\u043c \u043a \u043a\u043b\u0430\u0441\u0441\u0443, \u0435\u0441\u043b\u0438 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0432\u0441\u0435\u043c \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u043c \u0434\u043b\u044f \u043a\u043b\u0430\u0441\u0441\u0430 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f\u043c.<\/p>\n<h3>\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043e\u0448\u0438\u0431\u043e\u043a<\/h3>\n<pre><code class=\"fsharp\">def try_read_file (path : String) : Result&lt;String, String> =     ...  object i32     def try_parse (s : String) : Option&lt;i32> =         ...<\/code><\/pre>\n<p><code>Result&lt;String, String><\/code> \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043b\u0438\u0431\u043e \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043d\u043d\u044b\u0439 \u0438\u0437 \u0444\u0430\u0439\u043b\u0430 \u0442\u0435\u043a\u0441\u0442 \u0432 <code>Ok&lt;String><\/code>, \u043b\u0438\u0431\u043e <code>Error&lt;String><\/code> \u0441 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435\u043c \u043e\u0431 \u043e\u0448\u0438\u0431\u043a\u0435.<\/p>\n<pre><code class=\"fsharp\">def try_add (lhs_path : String) (rhs : i32) =     let lhs =         let! text = try_read_file lhs_path         let! number = i32.try_parse text         number      lhs + rhs |> Some<\/code><\/pre>\n<p>\u041f\u0440\u0438\u0432\u044f\u0437\u043a\u0438 <code>text<\/code> \u0438 <code>number<\/code> \u0438\u043c\u0435\u044e\u0442 \u0442\u0438\u043f\u044b <code>String<\/code> \u0438 <code>i32<\/code>, \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u044e\u0449\u0438\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u043b\u0443\u0447\u0430\u0438 \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u0433\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0439 <code>try_read_file<\/code> \u0438 <code>try_parse<\/code>.<\/p>\n<p>\u041d\u0438\u0436\u0435 \u043f\u043e\u043a\u0430\u0437\u0430\u043d \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u044b\u0439 \u043a\u043e\u0434 \u0431\u0435\u0437 <code>let!<\/code>.<\/p>\n<pre><code class=\"fsharp\">def try_add (lhs_path : String) (rhs : i32) =     let lhs =         let text = case try_read_file lhs_path of             Result::Ok text -> text             Result::Error _ -> return None          let number = case i32.try_parse text of             Some number -> number             None -> return None          number      lhs + rhs |> Some<\/code><\/pre>\n<p>\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u0435 \u043e\u0442 <code>try_read_file<\/code> \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e\u0431 \u043e\u0448\u0438\u0431\u043a\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0432\u044b\u0448\u0435 \u043f\u043e \u0441\u0442\u0435\u043a\u0443 \u0432\u044b\u0437\u043e\u0432\u043e\u0432, \u0432\u0435\u0440\u043d\u0443\u0432 <code>Result&lt;i32, String><\/code> \u0438\u0437 <code>try_add<\/code> \u0432\u043c\u0435\u0441\u0442\u043e <code>Option&lt;i32><\/code>.<\/p>\n<pre><code class=\"fsharp\">def try_add (lhs_path : String) (rhs : i32) =     let lhs =         let! text = try_read_file lhs_path         let! number = i32.try_parse text |> to_result \"cannot parse $text\"         number      lhs + rhs |> Result::Ok<\/code><\/pre>\n<p><code>Option<\/code> \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0432 <code>Result<\/code> \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u0435\u0442\u043e\u0434\u0430 <code>to_result<\/code>.<\/p>\n<h3>\u0412\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0441 \u044f\u0437\u044b\u043a\u043e\u043c \u0421<\/h3>\n<h4>\u0422\u0438\u043f\u044b<\/h4>\n<pre><code class=\"fsharp\">type VkInstance = MutPtr type CString = Ptr&lt;c_char><\/code><\/pre>\n<p>\u0418\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u0440\u0442\u0435\u0436 \u0441 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u043c \u0432 \u0421 \u043a\u043e\u0434\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d \u043a\u0430\u043a \u0442\u0438\u043f \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u044f\u0445 \u0432\u043d\u0435\u0448\u043d\u0438\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 <code>VkInstance<\/code> \u0438 <code>CString<\/code> \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u043c\u0435\u0441\u0442\u043e <code>void*<\/code> \u0438 <code>const char*<\/code>.<\/p>\n<pre><code class=\"fsharp\">typealias DebugUtilsMessengerCallbackExt = fn     (message_severity : DebugUtilsMessageSeverityFlagsExt)     * (message_types : DebugUtilsMessageTypeFlagsExt)     * (callback_data : ptr DebugUtilsMessengerCallbackDataExt)     * (user_data : MutPtr) -> u32  typealias CharFun = fn GlfwWindow * u32 -> Unit<\/code><\/pre>\n<p>\u041f\u0441\u0435\u0432\u0434\u043e\u043d\u0438\u043c\u044b \u0434\u043b\u044f \u0442\u0438\u043f\u043e\u0432 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0435\u0439 \u043d\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044e.<\/p>\n<pre><code class=\"fsharp\">type SampleCountFlags = flags     | 1     | 2     | 4     | 8     | 16     | 32     | 64<\/code><\/pre>\n<p>\u0421\u0438\u043c\u0432\u043e\u043b\u044b \u0444\u043b\u0430\u0433\u043e\u0432 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0447\u0438\u0441\u043b\u0430\u043c\u0438 \u0438\u043b\u0438 \u043d\u0430\u0447\u0438\u043d\u0430\u0442\u044c\u0441\u044f \u0441 \u0446\u0438\u0444\u0440\u044b.<\/p>\n<pre><code class=\"fsharp\">type InstanceCreateInfo = struct     type : StructureType     next : Ptr     flags : InstanceCreateFlags     application_info : ptr ApplicationInfo     enabled_layer_count : u32     enabled_layer_names : ptr CString     enabled_extension_count : u32     enabled_extension_names : ptr CString<\/code><\/pre>\n<p>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u044f\u0442\u0441\u044f \u043d\u0430 \u0421 \u0434\u043e\u0441\u043b\u043e\u0432\u043d\u043e.<\/p>\n<h4>\u0417\u043d\u0430\u0447\u0435\u043d\u0438\u044f<\/h4>\n<pre><code class=\"fsharp\">object f64     val min \"DBL_MIN\" : f64     val max \"DBL_MAX\" : f64     val epsilon \"DBL_EPSILON\" : f64<\/code><\/pre>\n<p>\u0412\u043d\u0435\u0448\u043d\u0438\u0435 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u044b <code>DBL_MIN<\/code>, <code>DBL_MAX<\/code> \u0438 <code>DBL_EPSILON<\/code> \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b \u043f\u043e\u043b\u044f\u043c\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 <code>f64<\/code>.<\/p>\n<h4>\u0424\u0443\u043d\u043a\u0446\u0438\u0438<\/h4>\n<pre><code class=\"fsharp\">module vk  def create_semaphore \"vkCreateSemaphore\"     (device : VkDevice)     (create_info : ptr SemaphoreCreateInfo)     (allocator : Allocator)     (semaphore : mut ptr VkSemaphore) : Result  endmodule<\/code><\/pre>\n<p>\u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u0447\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>vkCreateSemaphore<\/code> \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430 \u043f\u043e\u0434 \u0438\u043c\u0435\u043d\u0435\u043c <code>vk::create_semaphore<\/code>.<\/p>\n<pre><code class=\"fsharp\">def create_semaphore (device : VkDevice) =     let semaphore_create_info = SemaphoreCreateInfo         type = StructureType::SemaphoreCreateInfo         next = null         flags = SemaphoreCreateFlags@zero      let mut semaphore = null     let result = vk::create_semaphore device semaphore_create_info@ptr null                                       semaphore@mut_ptr     assert result == Result::Success      semaphore<\/code><\/pre>\n<p>\u041c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u044b <code>@ptr<\/code> \u0438 <code>@mut_ptr<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0442 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, <code>@fn<\/code> \u2014 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044e, <code>@zero<\/code> \u2014 \u043e\u0431\u043d\u0443\u043b\u0451\u043d\u043d\u044b\u0439 \u0431\u043b\u043e\u043a \u043f\u0430\u043c\u044f\u0442\u0438.<\/p>\n<pre><code class=\"fsharp\">type f32     def Real.sin \"sinf\" : f32     def Real.cos \"cosf\" : f32     def Real.floor \"floorf\" : f32     def Real.sqrt \"sqrtf\" : f32<\/code><\/pre>\n<p>\u0412\u043d\u0435\u0448\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u044b\u043c\u0438, \u043d\u043e \u0438 \u043c\u0435\u0442\u043e\u0434\u0430\u043c\u0438 \u0442\u0438\u043f\u0430, \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u0441\u043b\u0443\u0436\u0438\u0442\u044c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435\u043c \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u0445.<\/p>\n<pre><code class=\"fsharp\">type f64     def Real.sin : f64     def Real.cos : f64     def Real.floor : f64     def Real.sqrt : f64<\/code><\/pre>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f <code>f64<\/code> \u0443\u0436\u0435 \u0438\u043c\u0435\u044e\u0442 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0435 \u0438\u043c\u0435\u043d\u0430.<\/p>\n<h4>\u041a\u043e\u0434<\/h4>\n<p>\u0412 \u043e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u043d\u043d\u043e\u043c \u043a\u043e\u0434\u0435 \u0435\u0441\u0442\u044c \u044f\u0449\u0438\u043a\u0438 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 <a href=\"https:\/\/gitflic.ru\/project\/denismarkelov\/crates\/file?file=vulkan&amp;branch=master\" rel=\"noopener noreferrer nofollow\">vulkan<\/a> \u0438 <a href=\"https:\/\/gitflic.ru\/project\/denismarkelov\/crates\/file?file=glfw&amp;branch=master\" rel=\"noopener noreferrer nofollow\">glfw<\/a>.<\/p>\n<h3>\u0420\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435<\/h3>\n<pre><code class=\"fsharp\">type Border =     inherit Control      var obs left : u32 = 0     var obs right : u32 = 0     var obs up : u32 = 0     var obs down : u32 = 0     var obs content : Option&lt;Control> = None<\/code><\/pre>\n<p>\u041c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 <code>obs<\/code> \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0442\u0438\u043f\u0430 <code>mut Atom&lt;T><\/code>, \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0449\u0438\u0439 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u044e \u043e\u043f\u043e\u0432\u0435\u0449\u0435\u043d\u0438\u0439 \u043e\u0431 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f.<\/p>\n<pre><code class=\"fsharp\">let content_width = content@atom.map     { case _ of           None -> 0           Some control -> control.width }<\/code><\/pre>\n<p><code>content@atom<\/code> \u0432\u043c\u0435\u0441\u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u044f <code>content<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>map<\/code>.<\/p>\n<pre><code class=\"fsharp\">let thickness = (border.left@atom                  border.right@atom                  border.up@atom                  border.down@atom)                 |> to_atom<\/code><\/pre>\n<p>\u041c\u043e\u0436\u043d\u043e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0440\u0442\u0435\u0436 \u0430\u0442\u043e\u043c\u043e\u0432 \u0432 \u0430\u0442\u043e\u043c \u043a\u043e\u0440\u0442\u0435\u0436\u0435\u0439, <code>thickness<\/code> \u0438\u043c\u0435\u0435\u0442 \u0442\u0438\u043f <code>Atom&lt;(u32, u32, u32, u32)><\/code>.<\/p>\n<pre><code class=\"fsharp\">val memory@atom = (content_width, content_height, thickness)                   |> to_atom                   |> map { width, height, thickness ->                       if width == 0 || height == 0                       then None                       else Some (width, height, thickness) }                   |> option_map { width, height, (left, right, up, down) ->                       ...                       MeshMemory.from_quads quads.as_slice }<\/code><\/pre>\n<p>\u0418\u0437-\u0437\u0430 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430 <code>@atom<\/code> \u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0430 <code>memory<\/code> \u0438\u043c\u0435\u0435\u0442 \u0442\u0438\u043f <code>Option&lt;MeshMemory><\/code>, \u0430 \u043d\u0435 <code>Atom&lt;Option&lt;MeshMemory>><\/code>.<\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/818119\/\"> https:\/\/habr.com\/ru\/articles\/818119\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441, \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u043e\u0448\u0438\u0431\u043e\u043a, \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0441 \u044f\u0437\u044b\u043a\u043e\u043c \u0421 \u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f.<\/p>\n<p>\u041f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0430\u044f \u0441\u0442\u0430\u0442\u044c\u044f <a href=\"https:\/\/habr.com\/ru\/articles\/816917\" rel=\"noopener noreferrer nofollow\">\u0437\u0434\u0435\u0441\u044c<\/a>.<\/p>\n<h3>\u041e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u0430<\/h3>\n<pre><code class=\"fsharp\">val identity = Matrix4 1 0 0 0                        0 1 0 0                        0 0 1 0                        0 0 0 1<\/code><\/pre>\n<p>\u041f\u043e\u0437\u0438\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u043e\u043b\u0435\u0439 \u0445\u043e\u0440\u043e\u0448\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442 \u0434\u043b\u044f \u043c\u0430\u0442\u0440\u0438\u0446. \u0426\u0435\u043b\u043e\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u0439 \u043b\u0438\u0442\u0435\u0440\u0430\u043b \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u0442\u0430\u043a\u0436\u0435 \u0434\u043b\u044f \u0432\u0435\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432 \u0447\u0438\u0441\u0435\u043b.<\/p>\n<pre><code class=\"fsharp\">control.set_width width         set_height control.measure_height         arrange  import num::vector_f32::Vector3                         Vector4             vector_i32::Vector2i<\/code><\/pre>\n<p>\u041c\u0435\u0442\u043e\u0434\u044b <code>set_width<\/code>, <code>set_height<\/code> \u0438 <code>arrange<\/code> \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043d\u0430 \u043e\u0434\u043d\u043e\u0439 \u0438 \u0442\u043e\u0439 \u0436\u0435 \u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0435 <code>control<\/code>.<\/p>\n<pre><code class=\"fsharp\">let enabled_extension_names = [\"VK_EXT_debug_report\"                                \"VK_EXT_debug_utils\"                                \"VK_KHR_surface\"                                \"VK_KHR_xcb_surface\"                                \"VK_KHR_xlib_surface\"]<\/code><\/pre>\n<p>\u0417\u0430\u043f\u044f\u0442\u044b\u0435 \u043c\u0435\u0436\u0434\u0443 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u043c\u0438 \u043d\u0435 \u043d\u0443\u0436\u043d\u044b, \u0435\u0441\u043b\u0438 \u043a\u0430\u0436\u0434\u044b\u0439 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043d\u0430 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0435 \u0438\u043b\u0438 \u0441\u0442\u0440\u043e\u043a\u0430\u0445. \u0423\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 \u043c\u0430\u0441\u0441\u0438\u0432 \u0431\u0443\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u043d \u0432 \u0421 \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u0441\u0435 \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u044b\u0435 \u043b\u0438\u0442\u0435\u0440\u0430\u043b\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0442 \u0442\u0438\u043f <code>CString<\/code>.<\/p>\n<pre><code class=\"fsharp\">text |> lines |> filter { line -> line.starts_with \"layout\" } |> map { remove_comment _ }<\/code><\/pre>\n<p>\u041e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u044b <code>|><\/code> \u0443\u0434\u043e\u0431\u043d\u043e \u0440\u0430\u0441\u043f\u043e\u043b\u0430\u0433\u0430\u0442\u044c \u0432 \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u0440\u044f\u0434. \u0417\u0430\u043c\u044b\u043a\u0430\u043d\u0438\u044f \u0441\u043e\u0437\u0434\u0430\u044e\u0442\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0444\u0438\u0433\u0443\u0440\u043d\u044b\u0445 \u0441\u043a\u043e\u0431\u043e\u043a. \u041a\u0430\u0436\u0434\u043e\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u0434\u0447\u0451\u0440\u043a\u0438\u0432\u0430\u043d\u0438\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440.<\/p>\n<pre><code class=\"fsharp\">let up_right = Vector3 left.as_f32 0 border_z let adjusted_size = size as f32 * 1.5 |> as_u32<\/code><\/pre>\n<p>\u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0442\u0438\u043f\u0430 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043a\u0430\u043a \u0432\u044b\u0437\u043e\u0432 \u043c\u0435\u0442\u043e\u0434\u0430.<\/p>\n<pre><code class=\"fsharp\">let thickness = (left = border.left                  right = border.right                  up = border.up                  down = border.down)  let sizes = List&lt;(u32, u32) width height>.new<\/code><\/pre>\n<p>\u041f\u043e\u043b\u044f \u043a\u043e\u0440\u0442\u0435\u0436\u0430 \u043d\u0435 \u0438\u043c\u0435\u044e\u0442 \u0438\u043c\u0451\u043d \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e, \u043e\u0431\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u043a \u043d\u0438\u043c \u043c\u043e\u0436\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e \u044f\u0432\u043d\u043e \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u043c.<\/p>\n<h4>\u0412\u043d\u0443\u0442\u0440\u0438\u0441\u0442\u0440\u043e\u0447\u043d\u043e\u0435 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u0442\u0438\u043f\u043e\u0432<\/h4>\n<pre><code class=\"fsharp\">type Entry =     path : String     created : DateTime          | File size : u32     | Directory entries : Slice&lt;Entry>                 | Local                 | Remote url : String<\/code><\/pre>\n<p><code>Entry<\/code> \u0438 <code>Directory<\/code> \u044d\u0442\u043e \u0442\u0438\u043f\u044b-\u0441\u0443\u043c\u043c\u044b, <code>Local<\/code> \u0438 <code>Remote<\/code> \u2014 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b. \u041f\u043e\u043b\u044f <code>path<\/code> \u0438 <code>created<\/code> \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u043a\u0430\u043a \u0434\u043b\u044f <code>Entry<\/code>, \u0442\u0430\u043a \u0438 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0438\u0437 \u043f\u043e\u0434\u0442\u0438\u043f\u043e\u0432.<\/p>\n<pre><code class=\"fsharp\">type Entry @abstract = struct     path : String     created : DateTime     is_directory : bool      | File size : u32     | Directory entries : Slice&lt;mut ref Entry>                 is_remote : bool                 | Remote url : String<\/code><\/pre>\n<p>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b <code>File<\/code> \u0438 <code>Directory<\/code> \u043d\u0430\u0441\u043b\u0435\u0434\u0443\u044e\u0442 \u043f\u043e\u043b\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b <code>Entry<\/code>. \u0421\u0441\u044b\u043b\u043a\u0430 \u0442\u0438\u043f\u0430 <code>mut ref Entry<\/code> \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043d\u0430 <code>File<\/code>, <code>Directory<\/code> \u0438\u043b\u0438 <code>Remote<\/code>.<\/p>\n<h3>\u041a\u043b\u0430\u0441\u0441\u044b \u0442\u0438\u043f\u043e\u0432<\/h3>\n<pre><code class=\"fsharp\">type Comparable = class     def (>) (rhs : Self) : bool     def (&lt;) (rhs : Self) : bool     def (>=) (rhs : Self) : bool     def (&lt;=) (rhs : Self) : bool  type Compare @virtual =     def compare (other : Self) : Ordering      def (>) (rhs : Self) =         let result = compare rhs         result == Ordering::Greater      ...      is Comparable<\/code><\/pre>\n<p>\u0422\u0438\u043f \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d \u043f\u0440\u0438\u043d\u0430\u0434\u043b\u0435\u0436\u0430\u0449\u0438\u043c \u043a \u043a\u043b\u0430\u0441\u0441\u0443, \u0435\u0441\u043b\u0438 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0432\u0441\u0435\u043c \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u043c \u0434\u043b\u044f \u043a\u043b\u0430\u0441\u0441\u0430 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f\u043c.<\/p>\n<h3>\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043e\u0448\u0438\u0431\u043e\u043a<\/h3>\n<pre><code class=\"fsharp\">def try_read_file (path : String) : Result&lt;String, String> =     ...  object i32     def try_parse (s : String) : Option&lt;i32> =         ...<\/code><\/pre>\n<p><code>Result&lt;String, String><\/code> \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043b\u0438\u0431\u043e \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043d\u043d\u044b\u0439 \u0438\u0437 \u0444\u0430\u0439\u043b\u0430 \u0442\u0435\u043a\u0441\u0442 \u0432 <code>Ok&lt;String><\/code>, \u043b\u0438\u0431\u043e <code>Error&lt;String><\/code> \u0441 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435\u043c \u043e\u0431 \u043e\u0448\u0438\u0431\u043a\u0435.<\/p>\n<pre><code class=\"fsharp\">def try_add (lhs_path : String) (rhs : i32) =     let lhs =         let! text = try_read_file lhs_path         let! number = i32.try_parse text         number      lhs + rhs |> Some<\/code><\/pre>\n<p>\u041f\u0440\u0438\u0432\u044f\u0437\u043a\u0438 <code>text<\/code> \u0438 <code>number<\/code> \u0438\u043c\u0435\u044e\u0442 \u0442\u0438\u043f\u044b <code>String<\/code> \u0438 <code>i32<\/code>, \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u044e\u0449\u0438\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u043b\u0443\u0447\u0430\u0438 \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u0433\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0439 <code>try_read_file<\/code> \u0438 <code>try_parse<\/code>.<\/p>\n<p>\u041d\u0438\u0436\u0435 \u043f\u043e\u043a\u0430\u0437\u0430\u043d \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u044b\u0439 \u043a\u043e\u0434 \u0431\u0435\u0437 <code>let!<\/code>.<\/p>\n<pre><code class=\"fsharp\">def try_add (lhs_path : String) (rhs : i32) =     let lhs =         let text = case try_read_file lhs_path of             Result::Ok text -> text             Result::Error _ -> return None          let number = case i32.try_parse text of             Some number -> number             None -> return None          number      lhs + rhs |> Some<\/code><\/pre>\n<p>\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u0435 \u043e\u0442 <code>try_read_file<\/code> \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e\u0431 \u043e\u0448\u0438\u0431\u043a\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0432\u044b\u0448\u0435 \u043f\u043e \u0441\u0442\u0435\u043a\u0443 \u0432\u044b\u0437\u043e\u0432\u043e\u0432, \u0432\u0435\u0440\u043d\u0443\u0432 <code>Result&lt;i32, String><\/code> \u0438\u0437 <code>try_add<\/code> \u0432\u043c\u0435\u0441\u0442\u043e <code>Option&lt;i32><\/code>.<\/p>\n<pre><code class=\"fsharp\">def try_add (lhs_path : String) (rhs : i32) =     let lhs =         let! text = try_read_file lhs_path         let! number = i32.try_parse text |> to_result \"cannot parse $text\"         number      lhs + rhs |> Result::Ok<\/code><\/pre>\n<p><code>Option<\/code> \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0432 <code>Result<\/code> \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u0435\u0442\u043e\u0434\u0430 <code>to_result<\/code>.<\/p>\n<h3>\u0412\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0441 \u044f\u0437\u044b\u043a\u043e\u043c \u0421<\/h3>\n<h4>\u0422\u0438\u043f\u044b<\/h4>\n<pre><code class=\"fsharp\">type VkInstance = MutPtr type CString = Ptr&lt;c_char><\/code><\/pre>\n<p>\u0418\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u0440\u0442\u0435\u0436 \u0441 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u043c \u0432 \u0421 \u043a\u043e\u0434\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d \u043a\u0430\u043a \u0442\u0438\u043f \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u044f\u0445 \u0432\u043d\u0435\u0448\u043d\u0438\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 <code>VkInstance<\/code> \u0438 <code>CString<\/code> \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u043c\u0435\u0441\u0442\u043e <code>void*<\/code> \u0438 <code>const char*<\/code>.<\/p>\n<pre><code class=\"fsharp\">typealias DebugUtilsMessengerCallbackExt = fn     (message_severity : DebugUtilsMessageSeverityFlagsExt)     * (message_types : DebugUtilsMessageTypeFlagsExt)     * (callback_data : ptr DebugUtilsMessengerCallbackDataExt)     * (user_data : MutPtr) -> u32  typealias CharFun = fn GlfwWindow * u32 -> Unit<\/code><\/pre>\n<p>\u041f\u0441\u0435\u0432\u0434\u043e\u043d\u0438\u043c\u044b \u0434\u043b\u044f \u0442\u0438\u043f\u043e\u0432 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0435\u0439 \u043d\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044e.<\/p>\n<pre><code class=\"fsharp\">type SampleCountFlags = flags     | 1     | 2     | 4     | 8     | 16     | 32     | 64<\/code><\/pre>\n<p>\u0421\u0438\u043c\u0432\u043e\u043b\u044b \u0444\u043b\u0430\u0433\u043e\u0432 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0447\u0438\u0441\u043b\u0430\u043c\u0438 \u0438\u043b\u0438 \u043d\u0430\u0447\u0438\u043d\u0430\u0442\u044c\u0441\u044f \u0441 \u0446\u0438\u0444\u0440\u044b.<\/p>\n<pre><code class=\"fsharp\">type InstanceCreateInfo = struct     type : StructureType     next : Ptr     flags : InstanceCreateFlags     application_info : ptr ApplicationInfo     enabled_layer_count : u32     enabled_layer_names : ptr CString     enabled_extension_count : u32     enabled_extension_names : ptr CString<\/code><\/pre>\n<p>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u044f\u0442\u0441\u044f \u043d\u0430 \u0421 \u0434\u043e\u0441\u043b\u043e\u0432\u043d\u043e.<\/p>\n<h4>\u0417\u043d\u0430\u0447\u0435\u043d\u0438\u044f<\/h4>\n<pre><code class=\"fsharp\">object f64     val min \"DBL_MIN\" : f64     val max \"DBL_MAX\" : f64     val epsilon \"DBL_EPSILON\" : f64<\/code><\/pre>\n<p>\u0412\u043d\u0435\u0448\u043d\u0438\u0435 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u044b <code>DBL_MIN<\/code>, <code>DBL_MAX<\/code> \u0438 <code>DBL_EPSILON<\/code> \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b \u043f\u043e\u043b\u044f\u043c\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u0430 <code>f64<\/code>.<\/p>\n<h4>\u0424\u0443\u043d\u043a\u0446\u0438\u0438<\/h4>\n<pre><code class=\"fsharp\">module vk  def create_semaphore \"vkCreateSemaphore\"     (device : VkDevice)     (create_info : ptr SemaphoreCreateInfo)     (allocator : Allocator)     (semaphore : mut ptr VkSemaphore) : Result  endmodule<\/code><\/pre>\n<p>\u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u0447\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>vkCreateSemaphore<\/code> \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430 \u043f\u043e\u0434 \u0438\u043c\u0435\u043d\u0435\u043c <code>vk::create_semaphore<\/code>.<\/p>\n<pre><code class=\"fsharp\">def create_semaphore (device : VkDevice) =     let semaphore_create_info = SemaphoreCreateInfo         type = StructureType::SemaphoreCreateInfo         next = null         flags = SemaphoreCreateFlags@zero      let mut semaphore = null     let result = vk::create_semaphore device semaphore_create_info@ptr null                                       semaphore@mut_ptr     assert result == Result::Success      semaphore<\/code><\/pre>\n<p>\u041c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u044b <code>@ptr<\/code> \u0438 <code>@mut_ptr<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0442 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, <code>@fn<\/code> \u2014 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044e, <code>@zero<\/code> \u2014 \u043e\u0431\u043d\u0443\u043b\u0451\u043d\u043d\u044b\u0439 \u0431\u043b\u043e\u043a \u043f\u0430\u043c\u044f\u0442\u0438.<\/p>\n<pre><code class=\"fsharp\">type f32     def Real.sin \"sinf\" : f32     def Real.cos \"cosf\" : f32     def Real.floor \"floorf\" : f32     def Real.sqrt \"sqrtf\" : f32<\/code><\/pre>\n<p>\u0412\u043d\u0435\u0448\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u044b\u043c\u0438, \u043d\u043e \u0438 \u043c\u0435\u0442\u043e\u0434\u0430\u043c\u0438 \u0442\u0438\u043f\u0430, \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u0441\u043b\u0443\u0436\u0438\u0442\u044c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435\u043c \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u0445.<\/p>\n<pre><code class=\"fsharp\">type f64     def Real.sin : f64     def Real.cos : f64     def Real.floor : f64     def Real.sqrt : f64<\/code><\/pre>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f <code>f64<\/code> \u0443\u0436\u0435 \u0438\u043c\u0435\u044e\u0442 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0435 \u0438\u043c\u0435\u043d\u0430.<\/p>\n<h4>\u041a\u043e\u0434<\/h4>\n<p>\u0412 \u043e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u043d\u043d\u043e\u043c \u043a\u043e\u0434\u0435 \u0435\u0441\u0442\u044c \u044f\u0449\u0438\u043a\u0438 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 <a href=\"https:\/\/gitflic.ru\/project\/denismarkelov\/crates\/file?file=vulkan&amp;branch=master\" rel=\"noopener noreferrer nofollow\">vulkan<\/a> \u0438 <a href=\"https:\/\/gitflic.ru\/project\/denismarkelov\/crates\/file?file=glfw&amp;branch=master\" rel=\"noopener noreferrer nofollow\">glfw<\/a>.<\/p>\n<h3>\u0420\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435<\/h3>\n<pre><code class=\"fsharp\">type Border =     inherit Control      var obs left : u32 = 0     var obs right : u32 = 0     var obs up : u32 = 0     var obs down : u32 = 0     var obs content : Option&lt;Control> = None<\/code><\/pre>\n<p>\u041c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 <code>obs<\/code> \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 \u0442\u0438\u043f\u0430 <code>mut Atom&lt;T><\/code>, \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0449\u0438\u0439 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u044e \u043e\u043f\u043e\u0432\u0435\u0449\u0435\u043d\u0438\u0439 \u043e\u0431 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f.<\/p>\n<pre><code class=\"fsharp\">let content_width = content@atom.map     { case _ of           None -> 0           Some control -> control.width }<\/code><\/pre>\n<p><code>content@atom<\/code> \u0432\u043c\u0435\u0441\u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u044f <code>content<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>map<\/code>.<\/p>\n<pre><code class=\"fsharp\">let thickness = (border.left@atom                  border.right@atom                  border.up@atom                  border.down@atom)                 |> to_atom<\/code><\/pre>\n<p>\u041c\u043e\u0436\u043d\u043e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0440\u0442\u0435\u0436 \u0430\u0442\u043e\u043c\u043e\u0432 \u0432 \u0430\u0442\u043e\u043c \u043a\u043e\u0440\u0442\u0435\u0436\u0435\u0439, <code>thickness<\/code> \u0438\u043c\u0435\u0435\u0442 \u0442\u0438\u043f <code>Atom&lt;(u32, u32, u32, u32)><\/code>.<\/p>\n<pre><code class=\"fsharp\">val memory@atom = (content_width, content_height, thickness)                   |> to_atom                   |> map { width, height, thickness ->                       if width == 0 || height == 0                       then None                       else Some (width, height, thickness) }                   |> option_map { width, height, (left, right, up, down) ->                       ...                       MeshMemory.from_quads quads.as_slice }<\/code><\/pre>\n<p>\u0418\u0437-\u0437\u0430 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430 <code>@atom<\/code> \u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0430 <code>memory<\/code> \u0438\u043c\u0435\u0435\u0442 \u0442\u0438\u043f <code>Option&lt;MeshMemory><\/code>, \u0430 \u043d\u0435 <code>Atom&lt;Option&lt;MeshMemory>><\/code>.<\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/818119\/\"> https:\/\/habr.com\/ru\/articles\/818119\/<\/a><br \/><\/br><\/br><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-378390","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/378390","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=378390"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/378390\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=378390"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=378390"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=378390"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}