Understanding arrays in Odin

  Рет қаралды 1,040

Karl Zylinski

Karl Zylinski

Күн бұрын

Пікірлер: 17
@Davi_Dash
@Davi_Dash 12 күн бұрын
There also small_arrays from "core:container/small_array", a small array is struct with a fixed_array and a length, you set the max_size of the array and then you have acess to procedures that are associated with dynamic array: append, unordered_remove, ordered_remove... but still keeping the array on the stack.
@Whatthetrash
@Whatthetrash 9 күн бұрын
Thank you so much! I find your videos like these so helpful. 😊
@sbr27287
@sbr27287 12 күн бұрын
thank you for the video, looking forward to the book :)
@brownietcg20
@brownietcg20 6 күн бұрын
I started ODIN and asked myself one question: How to handle errors in Odin? BTW u are by far the best resource learning ODIN!
@karl_zylinski
@karl_zylinski 6 күн бұрын
Thank you! Errors in Odin work just like any other value. You return an extra bool, enum or union from the struct that can have some error happen and then you act on the error. There are some special syntax you can use to make handling errors easier, such as: if data, ok := os.read_entire_file("file.txt"); ok { // in here ok is true and data is possible to use } Above read_entire_file returns two values: the data and a bool that says if everything went OK. After the ; there is the actual condition of the if statement. It checks if `ok` is true. If it is then we can use data inside the braces.
@magisterkarlsson
@magisterkarlsson 12 күн бұрын
Clearly explained content, as usual. Thanks for sharing!
@karl_zylinski
@karl_zylinski 12 күн бұрын
Thank you magistern!
@kunimitanaka1079
@kunimitanaka1079 2 күн бұрын
Great video as usual Karl. Thank you. Might I make a small critical observation though? You often use the term "pointer" when what you mean is "address". Technically a pointer is a variable that holds an address. As you are aiming to educate and are writing a book I personally think the detail matters. Am I being too pedantic? Keep up the good work.
@karl_zylinski
@karl_zylinski Күн бұрын
Thank you. In the book more care is taken around this. I'll try to do better in the videos too. But it's almost impossible to say the correct thing at all times when speaking, unless you script the video completely, in which case the video will be terrible instead.
@bomber5671
@bomber5671 8 күн бұрын
I'm confused about the difference between a slice an and array and when you would want to use one over the other? They just seem very interchangeable to me. Like, `position[3] f32` makes this {0, 0, 0} But, what would `ints = make([]20, 128)` make 128 0s same as the normal fixed array? Is the notion to just use slices for function calls and things like that? Why would you ever want to clone a slice if so?
@karl_zylinski
@karl_zylinski 8 күн бұрын
A slice can be seen as "a window into another array". A slice can look into parts of a fixed array or look into parts of a dynamic array. You can use them as a generic way to pass the data of an array or parts of it into a procedure (function). This creates a new fixed array: position: [3]f32 The above does not dynamically allocate any memory. If you write the above within a procedure then the memory of that fixed array lives within the running procedure and dies when it finishes running. When you copy the fixed array variable, all the data in the fixed array is copied also: position: [3]f32 position2 := position position2[0] = 5 The last line only affects position2. There's no shared data between position and position2. However if you do this: position: [3]f32 pos_slice := position[:] pos_slice[0] = 5 Then the first element of position has changed. As I explain in the video the slice has a pointer inside to the data it looks at. In this case that pointer points to the beginning of position. So the slice is "looking into" position and modifying elements of the slice modifies elements of position. It's a window into another array. However, there is an exception to this "looking into an array". Slices can have their own data that doesn't look into anything else. If you do this: ints := make([]int, 128) Then you've made a slice that doesn't look into any other array, but it actually has its own dynamically allocated data! When the procedure in which you run the line above finishes, the data still lives on, because it is dynamically allocated. You need to at some point deallocate that memory by typing delete(ints) The reason you want to make a slice that has its own memory or clone a slice so that it gets its own memory is because you need it to live on for as long as you desire. For example if you have ints: [128]int then ints will die the when the current procedure dies but if you do ints: [128]int my_slice := slice.clone(ints[:20]) Then ints will still die when the procedure finishes, but my_slice now contains a clone of the first 20 elements. And that clone is dynamically allocated, it will live on until you run delete() on it! Also, typing ints := make([]int, 128) ints2 := ints does not make a copy of the data. This is again, as I explained in the video, because the slice `ints` has data pointer inside it. So both `ints` and `ints2` have the same data pointer inside, so no data is copied. Changing one changes the other. Use slice.clone to copy it. So in a sense, you can see how fixed arrays are very simple and copy in a simple way. That's why they are often used for things like Vector2 and Vector3 types, i.e. coordinates in 2 or 3 dimensions. They copy easily and don't do dynamic memory allocation. Dynamic memory allocation is slow and should be avoided.
@bomber5671
@bomber5671 8 күн бұрын
@@karl_zylinski Thank you! I guess it just seems odd to me that a slice in this language seems to both be some kind of array list from java but also a way to do pointer arithmetic from C. Like it almost seems like a slice on the stack is for something totally different than a slice on the heap.
@karl_zylinski
@karl_zylinski 7 күн бұрын
@@bomber5671 You are correct that it can be used in two different ways that are unrelated. You can think of a slice that is allocated using make as a "dynamically allocated array of fixed size". If you do ints := make([]int, 128) then there's actually another way to get the same result: ints_arr := new([128]int) ints := ints_arr[:] ints_arr is a dynamically allocated fixed array of 128 ints. This second example may make more sense when you think about how to make a dynamically allocated fixed array and then turn it into a slice. But the end result is identical. And in most cases you'd want something with of type []int and not of [128]int because the later is too specific to use with generic procs etc. So it's more convinient to do ints := make([]int, 128) right away and think of it as a way to make "dynamically allocated arrays of fixed size". Now to free the memory of something allocated with new, you'd usually use free: ints_arr := new([128]int) ints := ints_arr[:] // later free(ints_arr) However, since delete(ints) also just frees the contained memory block, you can in this case also use that: ints_arr := new([128]int) ints := ints_arr[:] // later delete(ints) This shows that this style is truly identical to using make([]int, 128)
@bomber5671
@bomber5671 6 күн бұрын
@@karl_zylinski Oh okay thanks that makes a little more sense to me now. I can see how a slice would take that functionality on now. Thank you! Appreciate you taking the time to write this up
@BlowaterNostr
@BlowaterNostr 12 күн бұрын
I am working on a music player in Odin with Raylib and I found that Raylib can't set the progress of the music. It only plays from start to end. Do you have other recommendations for music playing in Odin?
@karl_zylinski
@karl_zylinski 12 күн бұрын
If you are making a program to play the music and have control over the position in the music via some slider or something, then I think you need to control the playback yourself. I don't have any specific ideas, but in `vendor:miniaudio` you find stuff to play audio (it's the stuff that raylib wraps). Perhaps you can get more control by going to miniaudio directly. Other ideas are to use standalone libs like `vendor:stb/vorbis` (for .ogg files) and then other libs for loading `.mp3` etc... And then you interface directly to the sound API of your operating system, writing things to a buffer than is played. That way you can get maximal control over what is sent to the sound API.
@ar_xiv
@ar_xiv 12 күн бұрын
SeekMusicStream() ?
Odin's constants have their own little type system
11:55
Karl Zylinski
Рет қаралды 953
C# Records Are Functional - Use Them That Way!
10:55
Zoran Horvat
Рет қаралды 12 М.
Alat yang Membersihkan Kaki dalam Hitungan Detik 🦶🫧
00:24
Poly Holy Yow Indonesia
Рет қаралды 11 МЛН
Новый уровень твоей сосиски
00:33
Кушать Хочу
Рет қаралды 3,8 МЛН
Demystifying the C++ Compiler!
12:52
Low Level Game Dev
Рет қаралды 10 М.
Dynamic Programming isn't too hard. You just don't know what it is.
22:31
DecodingIntuition
Рет қаралды 140 М.
New Breakthrough on a 90-year-old Telephone Question
28:45
Eric Rowland
Рет қаралды 93 М.
Reacting to Controversial Opinions of Software Engineers
9:18
Fireship
Рет қаралды 2,1 МЛН
WHY IS THE STACK SO FAST?
13:46
Core Dumped
Рет қаралды 152 М.
Dynamic Arrays in C
11:46
Dylan Falconer
Рет қаралды 67 М.
Why Democracy Is Mathematically Impossible
23:34
Veritasium
Рет қаралды 4 МЛН
Zen, CUDA, and Tensor Cores - Part 1
21:06
Molly Rocket
Рет қаралды 23 М.
Alat yang Membersihkan Kaki dalam Hitungan Detik 🦶🫧
00:24
Poly Holy Yow Indonesia
Рет қаралды 11 МЛН