[Pharo-project] [NativeBoost] New kid on the block: NBExternalTypeArray + future plans
Hi there, i just uploaded new version of config - 1.8 (development), where i introduced the new public core classs: NBExternalTypeArray. The class provides a generic functionality for working with arrays which elements is of foreign (C) type. And since it is a subclass of ArrayedCollection, you can use them naturally as any other Array(s)/Collection(s) in smalltalk. Here the class comment: -------------- I am abstract class which provides a convenient interface to work with arrays which elements are values of some external (C) type. In order to use me with concrete element type, you must create a subclass of me and initialize element type properly. Subclassing using public subclass: - if you want to create a public subclass of me, then you should make sure that in class-side #initialize method, you add self-send #initElementType: and specify the element type name to use. (And of course, initialize the class before attempting to create any instances). Subclassing with anonymous subclass: To create an anonymous subclass of me, use #ofType: protocol, i.e.: floatArrayClass := NBExternalTypeArray ofType: 'float'. Please note that separate #at: / #at:put: methods will be automatically added in each and every subclass. Never remove them, despite they looking identical to superclass methods! !!CAUTION!! Currently those methods do not perform any range checking for index. So, please make sure you using sane index values (1<= index <= size). Also, note, that class instance variables: elementType and elementSize, once initialized, is considered read-only. Changing them, once you created at least a single instance of your class may lead to funny consequences. Arrays in external memory vs object memory: My instances can work either with data held in object memory or in external memory. The difference is only at instantiation time: To create a new array in object memory, just use #new: protocol: myArray := floatArrayClass new: 10. "create a new array with 10 floats". To allocate a new array in external memory, use #externalNew: protocol: myArray := floatArrayClass externalNew: 10. .. myArray free. "and sure thing, do not forget to free external memory after use". To check whether array uses object memory or external memory , use #isExternal protocol. Also, you can convert any external address into NBExternalTypeArray subclass instance, i.e. suppose some external function returns a pointer (instance of NBExternalAddress): pointer := self callSomeFunc: 1. So, in order to access memory at given address as array of 100 elements of type 'int', you can use following: myArray := (NBExternalTypeArray ofType: 'int') onAddress: pointer size: 100. myArray at: 1. "read first element" myArray at: 2 put: 50. "write second element" myArray do: [:each | ... ] ... etc (sure thing, in the above example, the "NBExternalTypeArray ofType: 'int' " expression is just to demonstrate the intent. It should be replaced with some variable, which you initialize only once and use many times, because creating an anonymous subclass each time would be highly ineffective ) Supported protocols: Since NBExternalTypeArray inherits from ArrayedCollection, you're free to use any protocols defined there as well as in its superclasses. There's only few additions comparing to ArrayedCollection, like #isExternal and #free . Copying: a #copy behavior is special for external arrays: A copy will always use object memory, even if original used external memory. ----------------- Now, i would really appreciate if someone could do some more serious testing (how well it works as Collection etc), and of course do a review and feedback :) My nearest plans concerning NB: - review the callbacks interface (to make it more convenient to use , as we discussed on this list some time ago) - by seeing how nicely NBExternalTypeArray deals with external/internal duality, i am now inclined to do the same for NBExternalStructure. (Yes.. nice and simple things are not often so obvious :) Like that, NBExternalStructure will be just a regular class (instead of var-byte one) which will keep 'data' object which is ByteArray for object memory allocated struct, and NBExternalAddress for indirect reference to structure data somewhere beyond our safe harbor ;)) - also, if time allows, i'd like to get threaded calls working. The prototype was started by Javier almost a year ago, and we need to finish it. Also, we want to work together with Esteban for making Objective-C bridge functional. This will bring us one step closer to multiple different goals: - native window management - allow us to avoid extra blitting Athens -> Display -> ObjC view.. but just Athens ->Obj-C :) - direct use of Obj-C runtime - .. reimplement VM features in image + adding new stuff (and sure thing, Esteban has own) And, of course, besides of that, soon we will start working on unified FFI interface for Pharo. So, people will no longer need to choose between old FFI/Alien/NB, since it will be ONE in the core functionality of a system. P.S. i'd like to thank everyone, who helping me with development of NB. In last couple months, i really see how your contribution helps bringing NB to better quality levels. Even though, not all of you risking to practice dark-assembly magic, ditching some nuances and polishing rough corners etc is really helpful.. because i wouldn't say that i'm in a mood of polishing project right now, because i more focused on adding missing features. :) -- Best regards, Igor Stasenko.
Awesome! I can use that in Limbo and see if I find any problems. BTW, did you make any progress on the pipe / fork / exec front? Cheers, Max On 07.12.2012, at 04:59, Igor Stasenko <siguctua@gmail.com> wrote:
Hi there,
i just uploaded new version of config - 1.8 (development), where i introduced the new public core classs: NBExternalTypeArray.
The class provides a generic functionality for working with arrays which elements is of foreign (C) type. And since it is a subclass of ArrayedCollection, you can use them naturally as any other Array(s)/Collection(s) in smalltalk.
Here the class comment: -------------- I am abstract class which provides a convenient interface to work with arrays which elements are values of some external (C) type. In order to use me with concrete element type, you must create a subclass of me and initialize element type properly.
Subclassing using public subclass: - if you want to create a public subclass of me, then you should make sure that in class-side #initialize method, you add self-send #initElementType: and specify the element type name to use. (And of course, initialize the class before attempting to create any instances).
Subclassing with anonymous subclass: To create an anonymous subclass of me, use #ofType: protocol, i.e.:
floatArrayClass := NBExternalTypeArray ofType: 'float'.
Please note that separate #at: / #at:put: methods will be automatically added in each and every subclass. Never remove them, despite they looking identical to superclass methods! !!CAUTION!! Currently those methods do not perform any range checking for index. So, please make sure you using sane index values (1<= index <= size).
Also, note, that class instance variables: elementType and elementSize, once initialized, is considered read-only. Changing them, once you created at least a single instance of your class may lead to funny consequences.
Arrays in external memory vs object memory:
My instances can work either with data held in object memory or in external memory. The difference is only at instantiation time:
To create a new array in object memory, just use #new: protocol:
myArray := floatArrayClass new: 10. "create a new array with 10 floats".
To allocate a new array in external memory, use #externalNew: protocol:
myArray := floatArrayClass externalNew: 10. .. myArray free. "and sure thing, do not forget to free external memory after use".
To check whether array uses object memory or external memory , use #isExternal protocol.
Also, you can convert any external address into NBExternalTypeArray subclass instance, i.e. suppose some external function returns a pointer (instance of NBExternalAddress):
pointer := self callSomeFunc: 1.
So, in order to access memory at given address as array of 100 elements of type 'int', you can use following:
myArray := (NBExternalTypeArray ofType: 'int') onAddress: pointer size: 100. myArray at: 1. "read first element" myArray at: 2 put: 50. "write second element" myArray do: [:each | ... ] ... etc
(sure thing, in the above example, the "NBExternalTypeArray ofType: 'int' " expression is just to demonstrate the intent. It should be replaced with some variable, which you initialize only once and use many times, because creating an anonymous subclass each time would be highly ineffective )
Supported protocols: Since NBExternalTypeArray inherits from ArrayedCollection, you're free to use any protocols defined there as well as in its superclasses. There's only few additions comparing to ArrayedCollection, like #isExternal and #free .
Copying: a #copy behavior is special for external arrays: A copy will always use object memory, even if original used external memory. -----------------
Now, i would really appreciate if someone could do some more serious testing (how well it works as Collection etc), and of course do a review and feedback :)
My nearest plans concerning NB:
- review the callbacks interface (to make it more convenient to use , as we discussed on this list some time ago) - by seeing how nicely NBExternalTypeArray deals with external/internal duality, i am now inclined to do the same for NBExternalStructure. (Yes.. nice and simple things are not often so obvious :) Like that, NBExternalStructure will be just a regular class (instead of var-byte one) which will keep 'data' object which is ByteArray for object memory allocated struct, and NBExternalAddress for indirect reference to structure data somewhere beyond our safe harbor ;)) - also, if time allows, i'd like to get threaded calls working. The prototype was started by Javier almost a year ago, and we need to finish it.
Also, we want to work together with Esteban for making Objective-C bridge functional. This will bring us one step closer to multiple different goals: - native window management - allow us to avoid extra blitting Athens -> Display -> ObjC view.. but just Athens ->Obj-C :) - direct use of Obj-C runtime - .. reimplement VM features in image + adding new stuff (and sure thing, Esteban has own)
And, of course, besides of that, soon we will start working on unified FFI interface for Pharo. So, people will no longer need to choose between old FFI/Alien/NB, since it will be ONE in the core functionality of a system.
P.S. i'd like to thank everyone, who helping me with development of NB. In last couple months, i really see how your contribution helps bringing NB to better quality levels. Even though, not all of you risking to practice dark-assembly magic, ditching some nuances and polishing rough corners etc is really helpful.. because i wouldn't say that i'm in a mood of polishing project right now, because i more focused on adding missing features. :)
-- Best regards, Igor Stasenko.
On 7 December 2012 07:20, Max Leske <maxleske@gmail.com> wrote:
Awesome!
I can use that in Limbo and see if I find any problems.
BTW, did you make any progress on the pipe / fork / exec front?
no. sorry i didn't had time to look at it. i reminded myself couple times during this week..
Cheers, Max
On 07.12.2012, at 04:59, Igor Stasenko <siguctua@gmail.com> wrote:
Hi there,
i just uploaded new version of config - 1.8 (development), where i introduced the new public core classs: NBExternalTypeArray.
The class provides a generic functionality for working with arrays which elements is of foreign (C) type. And since it is a subclass of ArrayedCollection, you can use them naturally as any other Array(s)/Collection(s) in smalltalk.
Here the class comment: -------------- I am abstract class which provides a convenient interface to work with arrays which elements are values of some external (C) type. In order to use me with concrete element type, you must create a subclass of me and initialize element type properly.
Subclassing using public subclass: - if you want to create a public subclass of me, then you should make sure that in class-side #initialize method, you add self-send #initElementType: and specify the element type name to use. (And of course, initialize the class before attempting to create any instances).
Subclassing with anonymous subclass: To create an anonymous subclass of me, use #ofType: protocol, i.e.:
floatArrayClass := NBExternalTypeArray ofType: 'float'.
Please note that separate #at: / #at:put: methods will be automatically added in each and every subclass. Never remove them, despite they looking identical to superclass methods! !!CAUTION!! Currently those methods do not perform any range checking for index. So, please make sure you using sane index values (1<= index <= size).
Also, note, that class instance variables: elementType and elementSize, once initialized, is considered read-only. Changing them, once you created at least a single instance of your class may lead to funny consequences.
Arrays in external memory vs object memory:
My instances can work either with data held in object memory or in external memory. The difference is only at instantiation time:
To create a new array in object memory, just use #new: protocol:
myArray := floatArrayClass new: 10. "create a new array with 10 floats".
To allocate a new array in external memory, use #externalNew: protocol:
myArray := floatArrayClass externalNew: 10. .. myArray free. "and sure thing, do not forget to free external memory after use".
To check whether array uses object memory or external memory , use #isExternal protocol.
Also, you can convert any external address into NBExternalTypeArray subclass instance, i.e. suppose some external function returns a pointer (instance of NBExternalAddress):
pointer := self callSomeFunc: 1.
So, in order to access memory at given address as array of 100 elements of type 'int', you can use following:
myArray := (NBExternalTypeArray ofType: 'int') onAddress: pointer size: 100. myArray at: 1. "read first element" myArray at: 2 put: 50. "write second element" myArray do: [:each | ... ] ... etc
(sure thing, in the above example, the "NBExternalTypeArray ofType: 'int' " expression is just to demonstrate the intent. It should be replaced with some variable, which you initialize only once and use many times, because creating an anonymous subclass each time would be highly ineffective )
Supported protocols: Since NBExternalTypeArray inherits from ArrayedCollection, you're free to use any protocols defined there as well as in its superclasses. There's only few additions comparing to ArrayedCollection, like #isExternal and #free .
Copying: a #copy behavior is special for external arrays: A copy will always use object memory, even if original used external memory. -----------------
Now, i would really appreciate if someone could do some more serious testing (how well it works as Collection etc), and of course do a review and feedback :)
My nearest plans concerning NB:
- review the callbacks interface (to make it more convenient to use , as we discussed on this list some time ago) - by seeing how nicely NBExternalTypeArray deals with external/internal duality, i am now inclined to do the same for NBExternalStructure. (Yes.. nice and simple things are not often so obvious :) Like that, NBExternalStructure will be just a regular class (instead of var-byte one) which will keep 'data' object which is ByteArray for object memory allocated struct, and NBExternalAddress for indirect reference to structure data somewhere beyond our safe harbor ;)) - also, if time allows, i'd like to get threaded calls working. The prototype was started by Javier almost a year ago, and we need to finish it.
Also, we want to work together with Esteban for making Objective-C bridge functional. This will bring us one step closer to multiple different goals: - native window management - allow us to avoid extra blitting Athens -> Display -> ObjC view.. but just Athens ->Obj-C :) - direct use of Obj-C runtime - .. reimplement VM features in image + adding new stuff (and sure thing, Esteban has own)
And, of course, besides of that, soon we will start working on unified FFI interface for Pharo. So, people will no longer need to choose between old FFI/Alien/NB, since it will be ONE in the core functionality of a system.
P.S. i'd like to thank everyone, who helping me with development of NB. In last couple months, i really see how your contribution helps bringing NB to better quality levels. Even though, not all of you risking to practice dark-assembly magic, ditching some nuances and polishing rough corners etc is really helpful.. because i wouldn't say that i'm in a mood of polishing project right now, because i more focused on adding missing features. :)
-- Best regards, Igor Stasenko.
-- Best regards, Igor Stasenko.
On 07.12.2012, at 12:59, Igor Stasenko <siguctua@gmail.com> wrote:
On 7 December 2012 07:20, Max Leske <maxleske@gmail.com> wrote:
Awesome!
I can use that in Limbo and see if I find any problems.
BTW, did you make any progress on the pipe / fork / exec front?
no. sorry i didn't had time to look at it. i reminded myself couple times during this week..
Not a problem. Just let me know when you've got something.
Cheers, Max
On 07.12.2012, at 04:59, Igor Stasenko <siguctua@gmail.com> wrote:
Hi there,
i just uploaded new version of config - 1.8 (development), where i introduced the new public core classs: NBExternalTypeArray.
The class provides a generic functionality for working with arrays which elements is of foreign (C) type. And since it is a subclass of ArrayedCollection, you can use them naturally as any other Array(s)/Collection(s) in smalltalk.
Here the class comment: -------------- I am abstract class which provides a convenient interface to work with arrays which elements are values of some external (C) type. In order to use me with concrete element type, you must create a subclass of me and initialize element type properly.
Subclassing using public subclass: - if you want to create a public subclass of me, then you should make sure that in class-side #initialize method, you add self-send #initElementType: and specify the element type name to use. (And of course, initialize the class before attempting to create any instances).
Subclassing with anonymous subclass: To create an anonymous subclass of me, use #ofType: protocol, i.e.:
floatArrayClass := NBExternalTypeArray ofType: 'float'.
Please note that separate #at: / #at:put: methods will be automatically added in each and every subclass. Never remove them, despite they looking identical to superclass methods! !!CAUTION!! Currently those methods do not perform any range checking for index. So, please make sure you using sane index values (1<= index <= size).
Also, note, that class instance variables: elementType and elementSize, once initialized, is considered read-only. Changing them, once you created at least a single instance of your class may lead to funny consequences.
Arrays in external memory vs object memory:
My instances can work either with data held in object memory or in external memory. The difference is only at instantiation time:
To create a new array in object memory, just use #new: protocol:
myArray := floatArrayClass new: 10. "create a new array with 10 floats".
To allocate a new array in external memory, use #externalNew: protocol:
myArray := floatArrayClass externalNew: 10. .. myArray free. "and sure thing, do not forget to free external memory after use".
To check whether array uses object memory or external memory , use #isExternal protocol.
Also, you can convert any external address into NBExternalTypeArray subclass instance, i.e. suppose some external function returns a pointer (instance of NBExternalAddress):
pointer := self callSomeFunc: 1.
So, in order to access memory at given address as array of 100 elements of type 'int', you can use following:
myArray := (NBExternalTypeArray ofType: 'int') onAddress: pointer size: 100. myArray at: 1. "read first element" myArray at: 2 put: 50. "write second element" myArray do: [:each | ... ] ... etc
(sure thing, in the above example, the "NBExternalTypeArray ofType: 'int' " expression is just to demonstrate the intent. It should be replaced with some variable, which you initialize only once and use many times, because creating an anonymous subclass each time would be highly ineffective )
Supported protocols: Since NBExternalTypeArray inherits from ArrayedCollection, you're free to use any protocols defined there as well as in its superclasses. There's only few additions comparing to ArrayedCollection, like #isExternal and #free .
Copying: a #copy behavior is special for external arrays: A copy will always use object memory, even if original used external memory. -----------------
Now, i would really appreciate if someone could do some more serious testing (how well it works as Collection etc), and of course do a review and feedback :)
My nearest plans concerning NB:
- review the callbacks interface (to make it more convenient to use , as we discussed on this list some time ago) - by seeing how nicely NBExternalTypeArray deals with external/internal duality, i am now inclined to do the same for NBExternalStructure. (Yes.. nice and simple things are not often so obvious :) Like that, NBExternalStructure will be just a regular class (instead of var-byte one) which will keep 'data' object which is ByteArray for object memory allocated struct, and NBExternalAddress for indirect reference to structure data somewhere beyond our safe harbor ;)) - also, if time allows, i'd like to get threaded calls working. The prototype was started by Javier almost a year ago, and we need to finish it.
Also, we want to work together with Esteban for making Objective-C bridge functional. This will bring us one step closer to multiple different goals: - native window management - allow us to avoid extra blitting Athens -> Display -> ObjC view.. but just Athens ->Obj-C :) - direct use of Obj-C runtime - .. reimplement VM features in image + adding new stuff (and sure thing, Esteban has own)
And, of course, besides of that, soon we will start working on unified FFI interface for Pharo. So, people will no longer need to choose between old FFI/Alien/NB, since it will be ONE in the core functionality of a system.
P.S. i'd like to thank everyone, who helping me with development of NB. In last couple months, i really see how your contribution helps bringing NB to better quality levels. Even though, not all of you risking to practice dark-assembly magic, ditching some nuances and polishing rough corners etc is really helpful.. because i wouldn't say that i'm in a mood of polishing project right now, because i more focused on adding missing features. :)
-- Best regards, Igor Stasenko.
-- Best regards, Igor Stasenko.
Thanks igor This is really important that you push infrastructure further because it will enable other people to work on the shoulders of giants :) Stef On Dec 7, 2012, at 4:59 AM, Igor Stasenko wrote:
Hi there,
i just uploaded new version of config - 1.8 (development), where i introduced the new public core classs: NBExternalTypeArray.
The class provides a generic functionality for working with arrays which elements is of foreign (C) type. And since it is a subclass of ArrayedCollection, you can use them naturally as any other Array(s)/Collection(s) in smalltalk.
Here the class comment: -------------- I am abstract class which provides a convenient interface to work with arrays which elements are values of some external (C) type. In order to use me with concrete element type, you must create a subclass of me and initialize element type properly.
Subclassing using public subclass: - if you want to create a public subclass of me, then you should make sure that in class-side #initialize method, you add self-send #initElementType: and specify the element type name to use. (And of course, initialize the class before attempting to create any instances).
Subclassing with anonymous subclass: To create an anonymous subclass of me, use #ofType: protocol, i.e.:
floatArrayClass := NBExternalTypeArray ofType: 'float'.
Please note that separate #at: / #at:put: methods will be automatically added in each and every subclass. Never remove them, despite they looking identical to superclass methods! !!CAUTION!! Currently those methods do not perform any range checking for index. So, please make sure you using sane index values (1<= index <= size).
Also, note, that class instance variables: elementType and elementSize, once initialized, is considered read-only. Changing them, once you created at least a single instance of your class may lead to funny consequences.
Arrays in external memory vs object memory:
My instances can work either with data held in object memory or in external memory. The difference is only at instantiation time:
To create a new array in object memory, just use #new: protocol:
myArray := floatArrayClass new: 10. "create a new array with 10 floats".
To allocate a new array in external memory, use #externalNew: protocol:
myArray := floatArrayClass externalNew: 10. .. myArray free. "and sure thing, do not forget to free external memory after use".
To check whether array uses object memory or external memory , use #isExternal protocol.
Also, you can convert any external address into NBExternalTypeArray subclass instance, i.e. suppose some external function returns a pointer (instance of NBExternalAddress):
pointer := self callSomeFunc: 1.
So, in order to access memory at given address as array of 100 elements of type 'int', you can use following:
myArray := (NBExternalTypeArray ofType: 'int') onAddress: pointer size: 100. myArray at: 1. "read first element" myArray at: 2 put: 50. "write second element" myArray do: [:each | ... ] ... etc
(sure thing, in the above example, the "NBExternalTypeArray ofType: 'int' " expression is just to demonstrate the intent. It should be replaced with some variable, which you initialize only once and use many times, because creating an anonymous subclass each time would be highly ineffective )
Supported protocols: Since NBExternalTypeArray inherits from ArrayedCollection, you're free to use any protocols defined there as well as in its superclasses. There's only few additions comparing to ArrayedCollection, like #isExternal and #free .
Copying: a #copy behavior is special for external arrays: A copy will always use object memory, even if original used external memory. -----------------
Now, i would really appreciate if someone could do some more serious testing (how well it works as Collection etc), and of course do a review and feedback :)
My nearest plans concerning NB:
- review the callbacks interface (to make it more convenient to use , as we discussed on this list some time ago) - by seeing how nicely NBExternalTypeArray deals with external/internal duality, i am now inclined to do the same for NBExternalStructure. (Yes.. nice and simple things are not often so obvious :) Like that, NBExternalStructure will be just a regular class (instead of var-byte one) which will keep 'data' object which is ByteArray for object memory allocated struct, and NBExternalAddress for indirect reference to structure data somewhere beyond our safe harbor ;)) - also, if time allows, i'd like to get threaded calls working. The prototype was started by Javier almost a year ago, and we need to finish it.
Also, we want to work together with Esteban for making Objective-C bridge functional. This will bring us one step closer to multiple different goals: - native window management - allow us to avoid extra blitting Athens -> Display -> ObjC view.. but just Athens ->Obj-C :) - direct use of Obj-C runtime - .. reimplement VM features in image + adding new stuff (and sure thing, Esteban has own)
And, of course, besides of that, soon we will start working on unified FFI interface for Pharo. So, people will no longer need to choose between old FFI/Alien/NB, since it will be ONE in the core functionality of a system.
P.S. i'd like to thank everyone, who helping me with development of NB. In last couple months, i really see how your contribution helps bringing NB to better quality levels. Even though, not all of you risking to practice dark-assembly magic, ditching some nuances and polishing rough corners etc is really helpful.. because i wouldn't say that i'm in a mood of polishing project right now, because i more focused on adding missing features. :)
-- Best regards, Igor Stasenko.
2012/12/7 Igor Stasenko <siguctua@gmail.com>:
Hi there,
i just uploaded new version of config - 1.8 (development), where i introduced the new public core classs: NBExternalTypeArray.
The class provides a generic functionality for working with arrays which elements is of foreign (C) type. And since it is a subclass of ArrayedCollection, you can use them naturally as any other Array(s)/Collection(s) in smalltalk.
Here the class comment: -------------- I am abstract class which provides a convenient interface to work with arrays which elements are values of some external (C) type. In order to use me with concrete element type, you must create a subclass of me and initialize element type properly.
Subclassing using public subclass: - if you want to create a public subclass of me, then you should make sure that in class-side #initialize method, you add self-send #initElementType: and specify the element type name to use. (And of course, initialize the class before attempting to create any instances).
Subclassing with anonymous subclass: To create an anonymous subclass of me, use #ofType: protocol, i.e.:
floatArrayClass := NBExternalTypeArray ofType: 'float'.
Hi Igor, couldn't it be simply renamed NBExternalArray ofType: 'float' External type of type ... sounds a bit redundant and I find external array sufficiently speaking, don't you? Nicolas
Please note that separate #at: / #at:put: methods will be automatically added in each and every subclass. Never remove them, despite they looking identical to superclass methods! !!CAUTION!! Currently those methods do not perform any range checking for index. So, please make sure you using sane index values (1<= index <= size).
Also, note, that class instance variables: elementType and elementSize, once initialized, is considered read-only. Changing them, once you created at least a single instance of your class may lead to funny consequences.
Arrays in external memory vs object memory:
My instances can work either with data held in object memory or in external memory. The difference is only at instantiation time:
To create a new array in object memory, just use #new: protocol:
myArray := floatArrayClass new: 10. "create a new array with 10 floats".
To allocate a new array in external memory, use #externalNew: protocol:
myArray := floatArrayClass externalNew: 10. .. myArray free. "and sure thing, do not forget to free external memory after use".
To check whether array uses object memory or external memory , use #isExternal protocol.
Also, you can convert any external address into NBExternalTypeArray subclass instance, i.e. suppose some external function returns a pointer (instance of NBExternalAddress):
pointer := self callSomeFunc: 1.
So, in order to access memory at given address as array of 100 elements of type 'int', you can use following:
myArray := (NBExternalTypeArray ofType: 'int') onAddress: pointer size: 100. myArray at: 1. "read first element" myArray at: 2 put: 50. "write second element" myArray do: [:each | ... ] ... etc
(sure thing, in the above example, the "NBExternalTypeArray ofType: 'int' " expression is just to demonstrate the intent. It should be replaced with some variable, which you initialize only once and use many times, because creating an anonymous subclass each time would be highly ineffective )
Supported protocols: Since NBExternalTypeArray inherits from ArrayedCollection, you're free to use any protocols defined there as well as in its superclasses. There's only few additions comparing to ArrayedCollection, like #isExternal and #free .
Copying: a #copy behavior is special for external arrays: A copy will always use object memory, even if original used external memory. -----------------
Now, i would really appreciate if someone could do some more serious testing (how well it works as Collection etc), and of course do a review and feedback :)
My nearest plans concerning NB:
- review the callbacks interface (to make it more convenient to use , as we discussed on this list some time ago) - by seeing how nicely NBExternalTypeArray deals with external/internal duality, i am now inclined to do the same for NBExternalStructure. (Yes.. nice and simple things are not often so obvious :) Like that, NBExternalStructure will be just a regular class (instead of var-byte one) which will keep 'data' object which is ByteArray for object memory allocated struct, and NBExternalAddress for indirect reference to structure data somewhere beyond our safe harbor ;)) - also, if time allows, i'd like to get threaded calls working. The prototype was started by Javier almost a year ago, and we need to finish it.
Also, we want to work together with Esteban for making Objective-C bridge functional. This will bring us one step closer to multiple different goals: - native window management - allow us to avoid extra blitting Athens -> Display -> ObjC view.. but just Athens ->Obj-C :) - direct use of Obj-C runtime - .. reimplement VM features in image + adding new stuff (and sure thing, Esteban has own)
And, of course, besides of that, soon we will start working on unified FFI interface for Pharo. So, people will no longer need to choose between old FFI/Alien/NB, since it will be ONE in the core functionality of a system.
P.S. i'd like to thank everyone, who helping me with development of NB. In last couple months, i really see how your contribution helps bringing NB to better quality levels. Even though, not all of you risking to practice dark-assembly magic, ditching some nuances and polishing rough corners etc is really helpful.. because i wouldn't say that i'm in a mood of polishing project right now, because i more focused on adding missing features. :)
-- Best regards, Igor Stasenko.
On 7 December 2012 13:38, Nicolas Cellier <nicolas.cellier.aka.nice@gmail.com> wrote:
2012/12/7 Igor Stasenko <siguctua@gmail.com>:
Hi there,
i just uploaded new version of config - 1.8 (development), where i introduced the new public core classs: NBExternalTypeArray.
The class provides a generic functionality for working with arrays which elements is of foreign (C) type. And since it is a subclass of ArrayedCollection, you can use them naturally as any other Array(s)/Collection(s) in smalltalk.
Here the class comment: -------------- I am abstract class which provides a convenient interface to work with arrays which elements are values of some external (C) type. In order to use me with concrete element type, you must create a subclass of me and initialize element type properly.
Subclassing using public subclass: - if you want to create a public subclass of me, then you should make sure that in class-side #initialize method, you add self-send #initElementType: and specify the element type name to use. (And of course, initialize the class before attempting to create any instances).
Subclassing with anonymous subclass: To create an anonymous subclass of me, use #ofType: protocol, i.e.:
floatArrayClass := NBExternalTypeArray ofType: 'float'.
Hi Igor, couldn't it be simply renamed NBExternalArray ofType: 'float' External type of type ... sounds a bit redundant and I find external array sufficiently speaking, don't you?
Makes sense.. i thought about it btw.. but was already in "finishing" phase. :)
Nicolas
-- Best regards, Igor Stasenko.
ok, i changed class name NBExternalTypeArray => NBExternalArray (config updated)
Hi Igor, couldn't it be simply renamed NBExternalArray ofType: 'float' External type of type ... sounds a bit redundant and I find external array sufficiently speaking, don't you?
Makes sense.. i thought about it btw.. but was already in "finishing" phase. :)
Nicolas
-- Best regards, Igor Stasenko.
-- Best regards, Igor Stasenko.
On 7 December 2012 16:12, Igor Stasenko <siguctua@gmail.com> wrote:
ok, i changed class name NBExternalTypeArray => NBExternalArray
(config updated)
not so fast.. due to some bug in class rename refactoring, the class lost all its methods.. so i had to put these methods back. and then people laughing why i don't use refactoring tools? exactly because of that: every time i trying to rely on it, it results in lost code & time to restore things back. .. uploaded new version of config with fixed package. -- Best regards, Igor Stasenko.
less complaining and more fixes :) On Dec 7, 2012, at 4:57 PM, Igor Stasenko <siguctua@gmail.com> wrote:
On 7 December 2012 16:12, Igor Stasenko <siguctua@gmail.com> wrote:
ok, i changed class name NBExternalTypeArray => NBExternalArray
(config updated)
not so fast.. due to some bug in class rename refactoring, the class lost all its methods.. so i had to put these methods back.
and then people laughing why i don't use refactoring tools? exactly because of that: every time i trying to rely on it, it results in lost code & time to restore things back.
.. uploaded new version of config with fixed package.
-- Best regards, Igor Stasenko.
participants (5)
-
Esteban Lorenzano -
Igor Stasenko -
Max Leske -
Nicolas Cellier -
Stéphane Ducasse