Forum Replies Created
-
AuthorPosts
-
Ok, looks like c++ enforces it, but other languages only warn about it:
http://stackoverflow.com/questions/3404301/whats-wrong-with-overridable-method-calls-in-constructors
https://msdn.microsoft.com/en-us/library/ms182331.aspx
I think it’s generally a good rule – if a ctor calls a method that is overridden by a subclass, that method can no longer depend on it’s class fields being properly initialized because it’s ctor hasn’t been executed yet. Or just as bad, the override could be called, but then anything it did gets undone by the ctor being called later, eg:
But I’ll likely end up sticking with what’s most practical/flexible on the translator side of things.
> In most languages the extended version of startup should be called…
Well, most languages except c++ (and I think Java gives an error).
A bit more on this here:
http://www.monkey-x.com/Community/posts.php?topic=10557
I actually haven’t decided 100% which way I’m going here either.
Attempt 2…
Monkey1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283Method ToJson:JsonValue( rect:Recti )Return New JsonArray( New JsonValue[]( New JsonNumber( rect.min.x ),New JsonNumber( rect.min.y ),New JsonNumber( rect.max.x ),New JsonNumber( rect.max.y ) ) )EndMethod ToRecti:Recti( value:JsonValue )Local json:=value.ToArray()Return New Recti( json[0].ToNumber(),json[1].ToNumber(),json[2].ToNumber(),json[3].ToNumber() )EndMethod LoadState()Local obj:=JsonObject.Load( "bin/ted2.state.json" )If Not obj ReturnIf obj.Contains( "openDocuments" )For Local doc:=Eachin obj["openDocuments"].ToArray()OpenDocument( doc.ToString() )NextEndifIf obj.Contains( "recentFiles" )_recent.Clear()For Local path:=Eachin obj["recentFiles"].ToArray()_recent.Push( path.ToString() )NextEndUpdateRecentFiles()If obj.Contains( "windowRect" )Frame=ToRecti( obj["windowRect"] )EndifIf obj.Contains( "consoleSize" )_docker.SetViewSize( _console,obj["consoleSize"].ToNumber() )EndifIf obj.Contains( "browserSize" )_docker.SetViewSize( _browser,obj["browserSize"].ToNumber() )EndifIf obj.Contains( "helpTreeSize" )_helpView.SetViewSize( _helpView.HelpTree,obj["helpTreeSize"].ToNumber() )EndifIf obj.Contains( "lockedDocument" )Local doc:=OpenDocument( obj["lockedDocument"].ToString() )If doc LockDoc( doc )EndifEndMethod SaveState()Local obj:=New JsonObjectLocal docs:=New JsonArrayFor Local doc:=Eachin _openDocsdocs.Add( New JsonString( doc.Path ) )Nextobj["openDocuments"]=docsLocal recent:=New JsonArrayFor Local path:=Eachin _recentrecent.Add( New JsonString( path ) )Endobj["recentFiles"]=recentobj["windowRect"]=ToJson( Frame )obj["consoleSize"]=New JsonNumber( _docker.GetViewSize( _console ) )obj["browserSize"]=New JsonNumber( _docker.GetViewSize( _browser ) )obj["helpTreeSize"]=New JsonNumber( _helpView.GetViewSize( _helpView.HelpTree ) )If _lockedDoc obj["lockedDocument"]=New JsonString( _lockedDoc.Path )SaveString( obj.ToJson(),"bin/ted2.state.json" )EndHa! Just got ‘banned’ from my own site for trying to post some code! They’re fixing it now…
Test…
> In MX1 we could override Map.Get, any reason why you have decided to make it final in MX2?
Basically because I think it’s a better design. You can read some of the arguments for and against virtual methods vs final methods and why I prefer final unless there’s a good reason to make some virtual here:
http://www.monkey-x.com/Community/posts.php?topic=10392&page=1
> But if I actually include gles20.glFinish() the render duration becomes the vSync interval, about 16ms.
Weird, I don’t get that here – yours must be waiting for the last ‘flip’ to finish whereas mine isn’t. Quite likely a driver thing, but it does mean you can’t reliably measure render time.
Perhaps try with SwapInterval=0?
Full support for extension methods will not be in V1.0, but there is actually limited extern-only extension method support in already. The only drawback is the method needs to be written in native-code, but this is sort of the point – it’s for methods that don’t translate easily from native code to mx2.
You can use it like this:
Monkey1234567891011121314151617181920212223242526272829303132'----- monkey2 file -----#Import "glue.cpp"ExternClass C Extends VoidMethod M( x:Int,y:Int ) Extension="C_M"EndPublicFunction Main()Local c:=New Cc.M( 10,20 ) 'passes 'c' as first param to C_MEnd'----- glue.cpp -----// include actual class we're wrapping#include "c.h"// Note: first param is 'this'...void C_M( C *c,int x,int y ){//can invoke c methods here if necessary...eg:c->doSomething( x,y );}There used to be an example of this in tests/monkey/externs but it appears to have gone…
So, wait, is there a way to not call Flush() when drawing to a texture?
No, but all rendering needs to be flushed eventually anyway, whether it’s to a canvas or to the render window. Window does a canvas.flush internally, so render to window will be ‘slower’ than you think because you’re not measuring this flush.
Try this just before calcing _renderDuration:
Monkey1234_windowCanvas.Flush()gles20.glFinish()_renderDuration=...This should flush all drawing on the mx2 side, followed by all GL drawing.
Render to image will probably be a little slower, because there’s the extra ‘blit’ to update the window canvas, but it should be pretty much the same.
Also, you can probably optimize the blit a bit – get rid of _windowCanvas.Clear and use BlendMode.Opaque.
Map.Get is final and cannot be overriden.
IMO, best approach is for ScreenBank to have an internal _map field and present it’s own interface, but you could also add a GetScreen method if you really want to extend Map.
Ok, 2 main problems:
- Use the TextureFlags.Dynamic flag for frequently modified textures. By default, texture contents are ‘backed up’ to system memory (so they can survive a graphics device reset) after texture target changes, but this is not necessary if you’re constantly updating the texture.
- The ‘render to texture’ code path executes a ‘canvas.flush’ where-as the ‘render to window’ path doesn’t, so it’s not a fair comparison! Flush() will cause all the ‘draw commands’ you’ve submitted to execute as GL code which will still partly execute in parallel but will still have some overhead.
No idea about the image problem – how did you add the image? Can you see an ‘Add Media’ button? Testing here…

Not 100% sure what you mean here, but the general idea of the iterator ‘Erase’ method is that the iterator already points to the thing you want to erase, so the second RemoveRect doesn’t make sense to me: if ‘i’ doesn’t point to the ‘r’ you want to erase, you’ll need to find it first so ‘i’ is redundant. If ‘i’ does point to the ‘r’ you want to erase, then the ‘r’ is redundant!
June 11, 2016 at 7:03 pm in reply to: Compilation fails when passing a structure using an interface #1037> there isn’t a formatting guide for this forum.
I just use the ‘<>’ button in the visual editor toolbar and paste my code there.
June 11, 2016 at 7:02 pm in reply to: Compilation fails when passing a structure using an interface #1036Short answer is the compiler shouldn’t be allowing the struct->interface conversions, such as the cast or the F() call with ‘a’. This should cause an error – will fix.
Although structs can implement interfaces, they don’t really! An interface is a ‘reference type’ and a struct is a ‘value type’ and without some form of boxing (which mx2 does not and probably will not support) there is no way to convert a value type to a reference type. So these conversions should fail.
I’ve allowed structs to be able to implement interfaces though for the sake of allowing you to specify generic constraints, eg: you can do this for F():
Monkey123Function F<T>( something:T ) Where T Implements ISomethingEndWhen a struct implements an interace, it’s a purely static thing. The struct is checked to make sure it implements all interface methods but that’s all that really happens – the struct doesn’t gain a ‘virtual function table’ or anything, and no extra c++ code is generated.
The built-in primitives already implement some interfaces, eg: Int implements IIntegral which extends INumeric. This allows you to write methods like:
Monkey123Method Add<C>( c:C ) Where C Implements INumeric 'can be used with any numeric type!EndThis is currently a bit ‘loose’ in that INumeric doesn’t actually have any methods so it’s not clearly defined what it even means to be numeric. This means you can declare something that implements INumeric and ‘Add’ could fail to work with it because it expects it to have Operator+ or something. But it works OK for the built-in types.
I’m waiting until I get some more time to improve this side of things, but what’s really needed I think are generic methods in interfaces and this is a bit tricky! I had a shot and have an idea of the issues involved but decided it was a ‘later’ feature in the end.
http://monkey2.monkey-x.com/forums/topic/casting-classes-and-subclasses/
I really should come up with a better error message though…
-
AuthorPosts