Forum Replies Created
-
AuthorPosts
-
Mark has answered the issue and said function params are not actually passed by reference even if classes are reference based. (the problem of image pointers is something else):
This is expected behaviour – functions parameters are not passed ‘by reference’ so when you assign to ‘img’ inside ‘MyImageLoading’ you are only assigning to a local variable which disappears when the function returns.
I still don’t understand the exact behaviour of my above example though, and why it works..
But this example shows a bit of reference based classes behavior in mx2:
And if you use a global foo class for pointers you’ll end with the same kind of errors we have with image pointers.[/crayon]Monkey1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980[crayon-5cbaa0439a7bb159468569 inline="true" ]Namespace myapp#Import "<std>"Using std..Global fg:fooClass fooField str:StringMethod New()str="default"EndEndFunction Main()Local f:=New foo()Local f2:=New foo()f2.str="f2"Print f.strmodify(f)Print f.str + " >you might think it's passed by reference because the modification has been recorded but.."modify2(f)Print f.str + " >it was assigned to a modified local and was not modified after return, if really by reference it should not point to the old one anymore.."Print "-------"modifyr(f,f2)Print f.str+" >this where you see it's not actually passed by reference!"Print f2.str+" >this where you see it's not actually passed by reference!"f=f2Print f.str+ " >here it worked because the objects references where not passed to a function"Print f2.str+ " >here it worked because the objects references where not passed to a function"f2.str="modd"Print f.str+ " >they have the same memory now!"Print f2.str + " >they have the same memory now!"f=New foo()f2=New foo()f2.str="newf2"Print "---"Print f.str + " >they are two new diffrent ones now"Print f2.str + " >they are two new diffrent ones now"Print "-"modifyp(Varptr f,Varptr f2)Print f.str + " >Using pointer worked for passing by reference"Print f2.str + " >Using pointer worked for passing by reference"f2.str="last mod"Print f.strPrint f2.strEndFunction modify(f:foo)f.str="mod"EndFunction modify2(f:foo)Local fl:=New foo()fl.str="mod2"f=flEndFunction modifyr(fr:foo,f2r:foo)fr=f2rEndFunction modifyp(fp:foo ptr,f2p:foo ptr)f2p->str="modp"fp[0]=f2p[0]Endyou can only predefine simple arrays so it will take two lines with your array of array example([][]). With a multidimensional([,]) array it’s not possible at all for now.
this is the most you can have for now i think..
[/crayon]Monkey123456789101112131415[crayon-5cbaa0439eced671383851 inline="true" ]#Import "<std>"Using std..Function Main()Local t:=New String[][2]t[0]=New string[]("cat","dog")t[1]=New string[]("ape","monkey")Print t[1][0]Endyou can have multidimensional arrays Myarr[x,x] or arrays of arrays Myarr[][] depending on what you need.
multidimensional arrays are much simpler.
you can directly initialize simple arrays only.simple and multidimentionnal arrays are explained in the latest docs (in github) but the arrays of arrays are not explained (see link)
http://monkey2.monkey-x.com/forums/topic/syntax-for-array-of-arrays-jagged-array/an example of multidimentionnal array:
[/crayon]Monkey123456789101112[crayon-5cbaa043a1afb420073412 inline="true" ]#Import "<std>"Using std..Function Main()Local strs:=New String[2,2]strs[0,0]="hip"strs[0,1]="hop"strs[1,0]="get"strs[1,1]="hype"Print strs[1,0]Enddo you recommend that I create a new array
buffer = new int[1024] ?
in C it will be[/crayon]Monkey123[crayon-5cbaa043a4342344198288 inline="true" ]char char_t[1024]but in monkey how would I reserve the memory without the use of the Cast operator?
or should i use malloc!?
Just tested you snippet but the update gave me a memory access violation..
First example worked though.
EDIT: had to modify a bit because the string was not ending correctly..
[/crayon]Monkey1234567891011121314151617181920212223242526[crayon-5cbaa043a66b1186681397 inline="true" ]Function GetInput:String(prompt:String, maxLength:Int)Local char := New Byte[1]Local input := New Byte[maxLength]Local count:Int = 0Local data:String = ""libc.fputs(prompt, libc.stdout) ' InLine PromptWhile(True)If(String.FromChar(char[0]) <> "~n" And count < maxLength)libc.fread(char.Data, 1, 1, libc.stdin)input[count] = char[0]count += 1Elseinput[count - 1] = 0ExitEndifWendFor Local i := 0 Until count-1data += String.FromChar(input[i])NextReturn dataEnd FunctionWhy do you create new canvas each render frame?
I don’t, I just saw the bug(if it is) with some random simple test code.
My example finished with a crash after a few time… Problem(?) with canvas that I reported.
The Image objects are extending resource and resource are not GCed, and images can be created only after “New Appinstance”.
The error message shows that it’s confused with some GCed object and some non GCed object. It converted the image to some GCed object but should not have done that.
And your simple Function should just work. I tried with a method but it’s still the same problem!In my opinion you found 2 bugs! and I found one with my un-usefull example! Nice shot!
EDIT:reported all 3 supposed bugs on github.
Images are reference based so there is no need to use pointer… (or you re doing some specific external stuffs) It is supposed to passed by reference and any modifications should be kept.
Did you Flushed the drawing commands: MyCanvas.Flush()? Note that flushing might slow down you process.
It’s easier to help with the code..
here is an example of a function drawing to an image with modification by reference.
[/crayon]Monkey123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354[crayon-5cbaa043ace17642984787 inline="true" ]Namespace myapp#Import "<std>"#Import "<mojo>"Using std..Using mojo..Class MyWindow Extends WindowField im:ImageMethod New( title:String="Simple mojo app",width:Int=640,height:Int=480,flags:WindowFlags=Null )Super.New( title,width,height,flags )im=New Image (400,400)EndMethod OnRender( canvas:Canvas ) OverrideApp.RequestRender()DrawThings(im)canvas.DrawImage (im,50,50)EndEndFunction Main()New AppInstanceNew MyWindowApp.Run()EndFunction DrawThings(img:Image)Local canv:Canvascanv=New Canvas (img)canv.Clear (Color.White)canv.Color=Color.Blackcanv.DrawText( "Hello World!",10,10 )canv.DrawPoint (3,3)canv.Flush()EndOMG! I didn’t even thought about it! Will do so.
Last info i saw on this:
Lines can currently only be split after ‘[‘, ‘(‘ or ‘,’ tokens.
February 13, 2017 at 10:39 pm in reply to: SOLVED: difference C vs C++ for importing simple function #7146Solved:
Adding this at the beginning of files[/crayon]Monkey123[crayon-5cbaa043b423b144022694 inline="true" ]#ifdef __cplusplusextern "C" {#endifand this at the end
[/crayon]Monkey123[crayon-5cbaa043b4240393507747 inline="true" ]#ifdef __cplusplus}#endifAnd I can now switch the .c and .cpp files.
Looks like mx2 is cpp by default..whenever a declaration create duplicates try to add static before it…
in this case I added 3 static keywords and no errors now (on W7)
this doesn’t mean it’s the good solution! but it avoids you spilltin to a .cpp src
[/crayon]Monkey123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119[crayon-5cbaa043b750d970222050 inline="true" ]#ifdef _WIN32#include <windows.h>#else#include <sys/mman.h>#include <fcntl.h> /* For O_* constants */#endif // _WIN32struct LinkedMem {#ifdef _WIN32UINT32 uiVersion;DWORD uiTick;#elseuint32_t uiVersion;uint32_t uiTick;#endiffloat fAvatarPosition[3];float fAvatarFront[3];float fAvatarTop[3];wchar_t name[256];float fCameraPosition[3];float fCameraFront[3];float fCameraTop[3];wchar_t identity[256];#ifdef _WIN32UINT32 context_len;#elseuint32_t context_len;#endifunsigned char context[256];wchar_t description[2048];};static LinkedMem *lm = NULL;static void initMumble() {#ifdef _WIN32HANDLE hMapObject = OpenFileMappingW(FILE_MAP_ALL_ACCESS, FALSE, L"MumbleLink");if (hMapObject == NULL)return;lm = (LinkedMem *) MapViewOfFile(hMapObject, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(LinkedMem));if (lm == NULL) {CloseHandle(hMapObject);hMapObject = NULL;return;}#elsechar memname[256];snprintf(memname, 256, "/MumbleLink.%d", getuid());int shmfd = shm_open(memname, O_RDWR, S_IRUSR | S_IWUSR);if (shmfd < 0) {return;}lm = (LinkedMem *)(mmap(NULL, sizeof(struct LinkedMem), PROT_READ | PROT_WRITE, MAP_SHARED, shmfd,0));if (lm == (void *)(-1)) {lm = NULL;return;}#endif}static void updateMumble() {if (! lm)return;if(lm->uiVersion != 2) {wcsncpy(lm->name, L"TestLink", 256);wcsncpy(lm->description, L"TestLink is a test of the Link plugin.", 2048);lm->uiVersion = 2;}lm->uiTick++;// Left handed coordinate system.// X positive towards "right".// Y positive towards "up".// Z positive towards "front".//// 1 unit = 1 meter// Unit vector pointing out of the avatar's eyes aka "At"-vector.lm->fAvatarFront[0] = 0.0f;lm->fAvatarFront[1] = 0.0f;lm->fAvatarFront[2] = 1.0f;// Unit vector pointing out of the top of the avatar's head aka "Up"-vector (here Top points straight up).lm->fAvatarTop[0] = 0.0f;lm->fAvatarTop[1] = 1.0f;lm->fAvatarTop[2] = 0.0f;// Position of the avatar (here standing slightly off the origin)lm->fAvatarPosition[0] = 0.001f;lm->fAvatarPosition[1] = 0.0f;lm->fAvatarPosition[2] = 0.5f;// Same as avatar but for the camera.lm->fCameraPosition[0] = 0.0f;lm->fCameraPosition[1] = 0.0f;lm->fCameraPosition[2] = 0.0f;lm->fCameraFront[0] = 0.0f;lm->fCameraFront[1] = 0.0f;lm->fCameraFront[2] = 1.0f;lm->fCameraTop[0] = 0.0f;lm->fCameraTop[1] = 1.0f;lm->fCameraTop[2] = 0.0f;// Identifier which uniquely identifies a certain player in a context (e.g. the ingame name).wcsncpy(lm->identity, L"Unique ID", 256);// Context should be equal for players which should be able to hear each other positional and// differ for those who shouldn't (e.g. it could contain the server+port and team)memcpy(lm->context, "ContextBlob\x00\x01\x02\x03\x04", 16);lm->context_len = 16;}try this without splitting (much easier and there’s something I didn’t get with the split with a .c file!)
[/crayon]Monkey123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119[crayon-5cbaa043bdb3a582201486 inline="true" ]#ifdef _WIN32#include <windows.h>#else#include <sys/mman.h>#include <fcntl.h> /* For O_* constants */#endif // _WIN32struct LinkedMem {#ifdef _WIN32UINT32 uiVersion;DWORD uiTick;#elseuint32_t uiVersion;uint32_t uiTick;#endiffloat fAvatarPosition[3];float fAvatarFront[3];float fAvatarTop[3];wchar_t name[256];float fCameraPosition[3];float fCameraFront[3];float fCameraTop[3];wchar_t identity[256];#ifdef _WIN32UINT32 context_len;#elseuint32_t context_len;#endifunsigned char context[256];wchar_t description[2048];};LinkedMem *lm = NULL;static void initMumble() {#ifdef _WIN32HANDLE hMapObject = OpenFileMappingW(FILE_MAP_ALL_ACCESS, FALSE, L"MumbleLink");if (hMapObject == NULL)return;lm = (LinkedMem *) MapViewOfFile(hMapObject, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(LinkedMem));if (lm == NULL) {CloseHandle(hMapObject);hMapObject = NULL;return;}#elsechar memname[256];snprintf(memname, 256, "/MumbleLink.%d", getuid());int shmfd = shm_open(memname, O_RDWR, S_IRUSR | S_IWUSR);if (shmfd < 0) {return;}lm = (LinkedMem *)(mmap(NULL, sizeof(struct LinkedMem), PROT_READ | PROT_WRITE, MAP_SHARED, shmfd,0));if (lm == (void *)(-1)) {lm = NULL;return;}#endif}static void updateMumble() {if (! lm)return;if(lm->uiVersion != 2) {wcsncpy(lm->name, L"TestLink", 256);wcsncpy(lm->description, L"TestLink is a test of the Link plugin.", 2048);lm->uiVersion = 2;}lm->uiTick++;// Left handed coordinate system.// X positive towards "right".// Y positive towards "up".// Z positive towards "front".//// 1 unit = 1 meter// Unit vector pointing out of the avatar's eyes aka "At"-vector.lm->fAvatarFront[0] = 0.0f;lm->fAvatarFront[1] = 0.0f;lm->fAvatarFront[2] = 1.0f;// Unit vector pointing out of the top of the avatar's head aka "Up"-vector (here Top points straight up).lm->fAvatarTop[0] = 0.0f;lm->fAvatarTop[1] = 1.0f;lm->fAvatarTop[2] = 0.0f;// Position of the avatar (here standing slightly off the origin)lm->fAvatarPosition[0] = 0.001f;lm->fAvatarPosition[1] = 0.0f;lm->fAvatarPosition[2] = 0.5f;// Same as avatar but for the camera.lm->fCameraPosition[0] = 0.0f;lm->fCameraPosition[1] = 0.0f;lm->fCameraPosition[2] = 0.0f;lm->fCameraFront[0] = 0.0f;lm->fCameraFront[1] = 0.0f;lm->fCameraFront[2] = 1.0f;lm->fCameraTop[0] = 0.0f;lm->fCameraTop[1] = 1.0f;lm->fCameraTop[2] = 0.0f;// Identifier which uniquely identifies a certain player in a context (e.g. the ingame name).wcsncpy(lm->identity, L"Unique ID", 256);// Context should be equal for players which should be able to hear each other positional and// differ for those who shouldn't (e.g. it could contain the server+port and team)memcpy(lm->context, "ContextBlob\x00\x01\x02\x03\x04", 16);lm->context_len = 16;}Your problem here is that you give the implementation ({}) of your function in the .h file. It is ok to do that in c/c++ rules but it is considered BAD practice and nearly nobody does it. So I suppose Mark has not made mx2 compatible with it and sometimes (when using mojo for example) create duplicates of the same header for some internal mx2 reasons.
What’s GOOD practise?
-put static before your function if the implementation is in the .h file (ie: the{}). This will skip duplicates.[/crayon]Monkey123[crayon-5cbaa043c3e5f228303250 inline="true" ]static void test(){};Or
-put your implementation in a.c/.cpp file Edit:could not make it work with a .c file!
.h[/crayon]Monkey123[crayon-5cbaa043c3e64963504779 inline="true" ]void Test(void);.cpp
[/crayon]Monkey123[crayon-5cbaa043c3e68134659475 inline="true" ]void Test(void){};and import the
.c/.cpp file along with the .h file in your .monkey2 filedon’t forget to put the ; at end of lines. Sometimes it’s not mandatory but it’ll avoid you error messages.. (in the second case if you don’t put ; in the .h file it will fail to compile)
for better practice use the #ifndef in your .h file
[/crayon]Monkey12345678[crayon-5cbaa043c3e6c554540442 inline="true" ]#ifndef TEST_H#define TEST_Hput your declarations here#endifbut here of course test is a bit too simple for a def name!
the SDL_Event is a union in it’s SDL_events.h
And SDL_Event is declared in extern section as a struct..
Dunno if it will react exactly as a union but sdl2 events works!
SDL_events.h[/crayon]Monkey123456789101112131415161718192021222324252627282930313233343536373839[crayon-5cbaa043c7ee8616785207 inline="true" ]typedef union SDL_Event{Uint32 type; /**< Event type, shared with all events */SDL_CommonEvent common; /**< Common event data */SDL_WindowEvent window; /**< Window event data */SDL_KeyboardEvent key; /**< Keyboard event data */SDL_TextEditingEvent edit; /**< Text editing event data */SDL_TextInputEvent text; /**< Text input event data */SDL_MouseMotionEvent motion; /**< Mouse motion event data */SDL_MouseButtonEvent button; /**< Mouse button event data */SDL_MouseWheelEvent wheel; /**< Mouse wheel event data */SDL_JoyAxisEvent jaxis; /**< Joystick axis event data */SDL_JoyBallEvent jball; /**< Joystick ball event data */SDL_JoyHatEvent jhat; /**< Joystick hat event data */SDL_JoyButtonEvent jbutton; /**< Joystick button event data */SDL_JoyDeviceEvent jdevice; /**< Joystick device change event data */SDL_ControllerAxisEvent caxis; /**< Game Controller axis event data */SDL_ControllerButtonEvent cbutton; /**< Game Controller button event data */SDL_ControllerDeviceEvent cdevice; /**< Game Controller device event data */SDL_AudioDeviceEvent adevice; /**< Audio device event data */SDL_QuitEvent quit; /**< Quit request event data */SDL_UserEvent user; /**< Custom event data */SDL_SysWMEvent syswm; /**< System dependent window event data */SDL_TouchFingerEvent tfinger; /**< Touch finger event data */SDL_MultiGestureEvent mgesture; /**< Gesture event data */SDL_DollarGestureEvent dgesture; /**< Gesture event data */SDL_DropEvent drop; /**< Drag and drop event data *//* This is necessary for ABI compatibility between Visual C++ and GCCVisual C++ will respect the push pack pragma and use 52 bytes forthis structure, and GCC will use the alignment of the largest datatypewithin the union, which is 8 bytes.So... we'll add padding to force the size to be 56 bytes for both.*/Uint8 padding[56];} SDL_Event;sdl2.monkey2
[/crayon]Monkey12345678910111213141516171819202122232425262728[crayon-5cbaa043c7eed702994776 inline="true" ]Struct SDL_EventField type:IntField common:SDL_CommonEventField window:SDL_WindowEventField key:SDL_KeyboardEventField edit:SDL_TextEditingEventField text:SDL_TextInputEventField motion:SDL_MouseMotionEventField button:SDL_MouseButtonEventField wheel:SDL_MouseWheelEventField jaxis:SDL_JoyAxisEventField jball:SDL_JoyBallEventField jhat:SDL_JoyHatEventField jbutton:SDL_JoyButtonEventField jdevice:SDL_JoyDeviceEventField caxis:SDL_ControllerAxisEventField cbutton:SDL_ControllerButtonEventField cdevice:SDL_ControllerDeviceEventField adevice:SDL_AudioDeviceEventField quit:SDL_QuitEventField user:SDL_UserEventField syswm:SDL_SysWMEventField tfinger:SDL_TouchFingerEventField mgesture:SDL_MultiGestureEventField dgesture:SDL_DollarGestureEventField drop:SDL_DropEventEnd -
AuthorPosts