fosstodon.org is one of the many independent Mastodon servers you can use to participate in the fediverse.
Fosstodon is an invite only Mastodon instance that is open to those who are interested in technology; particularly free & open source software. If you wish to join, contact us for an invite.

Administered by:

Server stats:

9.8K
active users

#trytrytryagain

0 posts0 participants0 posts today
0xThylacine<p>That took *quite* some debugging.</p><p>I have a Mersenne Twister trait-based implementation providing an extract() method. Trait because there are u32 and u64 implementations of MT and they are different internally.</p><p>My screen manager (a struct) initially included the whole MT engine for internal use for random delays, random positions, etc. It worked perfectly.</p><p>But function pointers are a thing right? And I don't want the screen manager code to be dependent on my MT code - when all it needs is the function to provide a random u32.</p><p>So I could simply:<br>let mut fptr = mt.extract;</p><p>Doesn't work, more research... Needs a closure. Okay...</p><p>let mut fptr = || mt.extract();<br>// and call it like so<br>let randomnumber = fptr();</p><p>Cool - that works. Should be just as simple to attach that to the screen struct, right? Right?</p><p>No.... Not even remotely close.</p><p>Try to attach that function pointer to the screen struct. I dare you. (Just kidding, please don't.)</p><p>After some hair loss...and a few elapsed days thinking about the problem, and reading, reading.... Ok I give up, build a small test program.</p><p>jfc</p><p>The solution? In main program:<br>let mut mt = MersenneTwister::&lt;u32&gt;::new();<br>mt.seed(...) // my MT intentionally panics if unseeded and extract is called<br>let randfn = Box::new(move || mt.extract() );<br>let screen = Screen::init(... , randfn);</p><p>...and change the screen's struct and init code to accept that thing...</p><p>pub struct Screen {<br> ...<br> pub randfn: Box&lt;dyn FnMut() -&gt; u32&gt;,<br> ...<br>}</p><p>impl Screen {<br> ...<br> pub fn init(... randfn: Box&lt;dyn FnMut() -&gt; u32&gt; ) -&gt; Screen {<br> let s = Screen::new();<br> ...<br> s.randfn = randfn;<br> s // return screen object<br> }<br> ...<br>}</p><p>That was hard, examples are few and far between. To be fair, I don't know what I should have searched for since the errors were all about lifetimes of the mt object, or a closure that is not a fn()-&gt;u32. No lifetime annotations are required to make this work now.... Unless you intend to build a setter function, in which case there is one lifetime required "+ 'static" ala:</p><p> pub fn setfunc(&amp;mut self, func: impl FnMut() -&gt; u32 + 'static ) {<br> self.randfn = Box::new(func);<br> }</p><p><a href="https://infosec.exchange/tags/rust" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>rust</span></a> <a href="https://infosec.exchange/tags/learning" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>learning</span></a> <a href="https://infosec.exchange/tags/AlwaysLearning" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>AlwaysLearning</span></a> <a href="https://infosec.exchange/tags/TryTryTryAgain" class="mention hashtag" rel="nofollow noopener noreferrer" target="_blank">#<span>TryTryTryAgain</span></a></p>