What am I supposed to pass to the following method in Crystal? - methods

Background
I'm trying to use some Cairo bindings for Crystal, but I'm having some trouble with the syntax and how to call the method below.
It is implemented as such:
# Inside Module Cairo, class Surface
# ...
def write_to_png_stream(write_func : LibCairo::WriteFuncT, closure : Void*) : Status
Status.new(LibCairo.surface_write_to_png_stream(#surface, write_func, closure).value)
end
# Inside Module LibCairo
# ...
enum StatusT
SUCCESS = 0
NO_MEMORY
INVALID_RESTORE
# ...
end
# ...
alias WriteFuncT = Void*, UInt8*, UInt32 -> StatusT
# ...
fun surface_write_to_png_stream = cairo_surface_write_to_png_stream(
surface : PSurfaceT,
write_func : WriteFuncT,
closure : Void*
) : StatusT
Question
Specifically, I'm asking how to call the Cairo::Surface#write_to_png_stream method. What do I pass as the write_func:LibCairo::WriteFuncT? What do I pass as the closure: Void*?
I tried with the following but I haven't managed to get it to work...
def my_write_func(a : Void*, b : UInt8*, c : UInt32) : Cairo::C::LibCairo::StatusT
puts a
puts b
puts c
Cairo::C::LibCairo::StatusT::SUCCESS
end
surface = Cairo::Surface.new Cairo::Format::ARGB32, 400, 300
ctx = Cairo::Context.new surface
ctx.set_source_rgba 1.0, 0.0, 1.0, 1.0
ctx.rectangle 0.0, 0.0, 400.0, 300.0
ctx.fill
# here, how do I call surface.write_to_png_stream passing my 'my_write_func'?
# a Proc doesn't seem to work.. ( ->my_write_func(Void*, UInt8*, UInt32) )
surface.finish

Finally I got it working.. Or well, I managed to call it at least.
surface.write_to_png_stream ->my_write_func(Void*, UInt8*, UInt32), Pointer(Void).null
It turns out it was a Proc afterall as I suspected and that I just needed a null Pointer too.
For future reference, I have an issue at the repo talking about the specific usage of this method, but I suppose the syntax/semantics question is answered here on SO.

Related

Override string conversion for custom classes in Nim

Is it possible to override whatever method is used when an object of a custom class is converted to a string for display?
For example, this code currently prints (x: 4, y: 5), but I want it to print just (4,5)
type Point = object
x: int
y: int
let p = Point(x:4, y:5)
echo p
What proc/method/whatever do I implement to change the default Point->string conversion used by echo?
Figured it out; echo's docs says you just gotta overload the $ operator:
from strformat import fmt
type Point = object
x: int
y: int
proc `$`(point: Point): string = fmt"({point.x}, {point.y})"
let p = Point(x:4, y:5)
echo p # prints "(4, 5)"

Can't OR 2 enum values of the same type outside its enum class declaration

I am a newbie to both C++ and game programming. I am dealing with something I don't know how to make it work. I am coding along a game from a book, the authors didn't use enum class for his type but as recommended by most people, I am using enum class to remake it. It produces no error when I OR 2 enum value inside its enum class scope like this:
// This is inside the "Category.h" header file
namespace Category
{
enum class Type
{
None = 0,
SceneAirLayer = 1 << 0,
PlayerAircraft = 1 << 1,
AlliedAircraft = 1 << 2,
EnemyAircraft = 1 << 3,
Pickup = 1 << 4,
AlliedProjectile = 1 << 5,
EnemyProjectile = 1 << 6,
Aircraft = PlayerAircraft | AlliedAircraft | EnemyAircraft,
Projectile = AlliedProjectile | EnemyProjectile
};
}
But when I try to OR them inside a function of another source file, the compiler produces an error,
that is: "no operator "|" matches these operands operand type are Category::Type | Category::Type"
and here is the code inside that function (the game works for the authors version enum without class)
void World::destroyEntitiesOutsideView()
{
// This "command.category" just returns an "unsigned int" value
Command command;
// The error appears here
command.category = static_cast<unsigned int>(Category::Type::Projectile | Category::Type::EnemyAircraft);
// This is I just try to OR them alone but still the same error
Category::Type::Aircraft | Category::Type::AlliedProjectile;
}
Please someone tell me why and how can I fix this error??? Thank you a lot!!!
It is because you are using enum class instead of just enum. "Class enum doesn’t allow implicit conversion to int, and also doesn’t compare enumerators from different enumerations"

Julia methoderror for eltype style functionality

I have an abstract container AbstractContainer parameterised over a type T which indicates the type of what is in the container. Every subtype (in this case FloatContainer) then specifies what's actually in the container (in this case a Float64).
Ideally I'd have a means of getting back what type is in the container if I only have the container type.
This way I could use it in another struct (in this example MultiplyBy)
I was thinking of doing it in a similar way to Julia's internal eltype function but I can't get it to work.
I always get a method error (see the last snippet for the detailed error message)
abstract type AbstractContainer{T} end
gettype(::Type{AbstractContainer{T}}) where T = T
struct FloatContainer <: AbstractContainer{Float64}
x::Float64
end
struct MultiplyBy{T<:AbstractContainer}
x::gettype(T)
end
function process(m::MultiplyBy, v::AbstractContainer)
return typeof(v)(m.x*v.x)
end
function main()
x = FloatContainer(2.0)
y = FloatContainer(3.0)
op = MultiplyBy{FloatContainer}(y)
z = process(op, x)
println(z.x)
end
main()
ERROR: LoadError: MethodError: no method matching gettype(::TypeVar)
Closest candidates are:
gettype(!Matched::Type{AbstractContainer{T}}) where T at /Users/.../test.jl:6
I must admit I'm very new to Julia but I'm very interested in learning more about it.
So any tips are appreciated - either on how to solve this problem differently or where my mistake is.
Determining element type
Your gettype does not work because it dispatches on abstract types, but your container objects will all have concrete types. You have to use the subtype operator in order to dispatch correctly.
Compare dispatch on abstract types:
julia> eltype1(::Type{AbstractContainer{T}}) where T = T
eltype1 (generic function with 1 method)
julia> eltype1(FloatContainer)
ERROR: MethodError: no method matching eltype1(::Type{FloatContainer})
Closest candidates are:
eltype1(::Type{AbstractContainer{T}}) where T at REPL[4]:1
Stacktrace:
[1] top-level scope at REPL[5]:1
julia> eltype1(AbstractContainer{Float64})
Float64
with dispatch on subtypes of abstract types:
julia> eltype2(::Type{<:AbstractContainer{T}}) where T = T
eltype2 (generic function with 1 method)
julia> eltype2(FloatContainer)
Float64
julia> eltype2(AbstractContainer{Float64})
Float64
Prefer dispatch variables to explicit eltype calls
Calling eltype directly is usually unnecessary; you can make the parametric type explicit during dispatch.
This solution uses only parametric types:
julia> struct Container{T}
x::T
end
julia> struct MultiplyBy{T}
x::T
end
julia> MulitplyBy(x::Container{T}) where T = MultiplyBy{T}(x.x)
MulitplyBy (generic function with 1 method)
julia> process(m::MultiplyBy, x::Container{T}) where T = Container{T}(m.x * x.x)
process (generic function with 1 method)
julia> a = Container(2.0)
Container{Float64}(2.0)
julia> b = Container(3.0)
Container{Float64}(3.0)
julia> op = MulitplyBy(b)
MultiplyBy{Float64}(3.0)
julia> process(op, a)
Container{Float64}(6.0)
i'm not sure about what you need, but i coded an working example with your structure:
abstract type AbstractContainer{T} end
#not necessary anymore
#gettype(a::Type{AbstractContainer{T}}) where T = T
struct FloatContainer{T<:AbstractFloat} <: AbstractContainer{T} #AbstractFloat, to include Float32, BigFloats and others
x::T
end
#you can't use functions on struct definitions, if you need more restrictions,
#use a Constructor
struct MultiplyBy{T<:AbstractContainer}
x::T
end
#example external Constructor
MultiplyBy(x::AbstractFloat) = MultiplyBy(FloatContainer(x))
value(x::AbstractContainer) = x.x #basic accesor function
value(x::MultiplyBy) = value(x.x)
function process(m::MultiplyBy, v::AbstractContainer)
return typeof(v)(value(m)*value(v)) #calling accesor functions to access the values.
end
function main()
x = FloatContainer(2.0)
y = FloatContainer(3.0)
op = MultiplyBy(y) #the parametric type is inferred automatically, no need to use Curly Braces
z = process(op, x)
println(value(x)) #better use accesor functions that direct access, as the underlying implementation can change
end
main()

Setting owner in boost::python::ndarray so that data is owned and managed by Python

I am trying to use boost::python::numpy::ndarray to create a multi-dimensional array in C++ and pass it to python. The problem is how to do this without having to manage the memory associated with the ndarray in C++ myself.
I am trying to use the boost::python::numpy::from_data function to create numpy array in C++. My basic understanding is that without the appropriate owner argument to the function, the responsibility of managing the memory associated with the array falls on me.
My original assumption was that the owner argument needn't be passed based on the boost page which says this about owner: "the owner of the data, in case it is not the ndarray itself."
However, I have read posts which seem to say otherwise. E.g., link says, "If you pass object() as owner argument the array should definitely own its data (and thus report OWNDATA=True) ... " and link says that the object has to be associated with an explicit destructor.
I was wondering what the correct approach is. Or is this not the intended use case for boost::python::numpy?
Yep, the documentation says that if you pass object(), the array will free the data when but this doens't work as advertised.
Here are some excerpts from my post on github https://github.com/boostorg/python/issues/97#issuecomment-519679003 which is the same issue that OP links but the answer wasn't there before. The answer doesn't come from me, just the demonstration of the answer and why the demo of the object() way not working.
The solution would be to create an object (a capsule) that owns the raw pointer and pass that to the the boost::python::numpy::ndarray::from_data() function. A capsule is a Python object that manages a pointer:
PyObject* PyCapsule_New(void *pointer, const char *name, PyCapsule_Destructor destructor)
Here is an example where I create a pretty large array. I'm going to call this function repeatedly in a Python while True: loop. With this function, you can let the loop go on all day. That's because in the loop, I assign the return value to the same variable, so at each iteration, the previously returned ndarray's refcount goes to zero and the memory gets freed.
typedef long int my_data_type;
inline void destroyManagerCObject(PyObject* self) {
auto * b = reinterpret_cast<my_data_type*>( PyCapsule_GetPointer(self, NULL) );
std::cout << "C++ : " << __PRETTY_FUNCTION__ << " delete [] " << b << std::endl;
delete [] b;
}
boost::python::numpy::ndarray get_array_that_owns_through_capsule()
{
// Change this to see how the adresses change.
unsigned int last_dim = 6000;
boost::python::object shape = boost::python::make_tuple(4, 5, last_dim);
boost::python::numpy::dtype dt = boost::python::numpy::dtype::get_builtin<my_data_type>();
auto * const data_ptr = new my_data_type[4*5*last_dim];
const size_t s = sizeof(my_data_type);
boost::python::object strides = boost::python::make_tuple(5*last_dim*s, last_dim*s, s);
for(int i = 1; i <= 4*5*last_dim; ++i){ data_ptr[i-1] = i; }
// This sets up a python object whose destruction will free data_ptr
PyObject *capsule = ::PyCapsule_New((void *)data_ptr, NULL, (PyCapsule_Destructor)&destroyManagerCObject);
boost::python::handle<> h_capsule{capsule};
boost::python::object owner_capsule{h_capsule};
std::cout << "C++ : " << __PRETTY_FUNCTION__ << "data_ptr = " << data_ptr << std::endl;
return boost::python::numpy::from_data( data_ptr, dt, shape, strides, owner_capsule);
}
BOOST_PYTHON_MODULE(interface){
.def("get_array_that_owns_through_capsule", get_array_that_owns_through_capsule)
Then in a while loop, I can call this function all day long and
import interface
import psutil
def get_process_memory_usage():
process = psutil.Process(os.getpid())
return process.memory_info().rss
hundred_mb = 100000000
MEMORY_MAX = 100 * one_mb
i = 0
while True:
print("PYTHON : ---------------- While iteration ------------------- ({})".format(i))
print("PYTHON : BEFORE calling test_capsule_way()")
arr = interface.get_array_that_owns_through_default_object()
print("PYTHON : AFTER calling test_capsule_way()")
i += 1
if i % 1000 == 0:
print("PYTHON : Nb arrays created (and pretty sure not destroyed) : {}".format(i))
mem = get_process_memory_usage()
if mem > MEMORY_MAX:
print("PYTHON : Bro chill with the memory, you're using {}MB over here!".format(mem/one_mb))
quit()
print("PYTHON : ----------- End while iteration\n")
print("PYTHON : SCRIPT END")
The output of the first couple iterations of this is
PYTHON : ---------------- While iteration ------------------- (0)
PYTHON : BEFORE calling test_capsule_way()
C++ : boost::python::numpy::ndarray get_array_that_owns_through_capsule()data_ptr = 0x7fb7c9831010
PYTHON : AFTER calling test_capsule_way()
PYTHON : ----------- End while iteration
PYTHON : ---------------- While iteration ------------------- (1)
PYTHON : BEFORE calling test_capsule_way()
C++ : boost::python::numpy::ndarray get_array_that_owns_through_capsule()data_ptr = 0x7fb7c9746010
C++ : void destroyManagerCObject(PyObject*) delete [] 0x7fb7c9831010
PYTHON : AFTER calling test_capsule_way()
PYTHON : ----------- End while iteration
PYTHON : ---------------- While iteration ------------------- (2)
PYTHON : BEFORE calling test_capsule_way()
C++ : boost::python::numpy::ndarray get_array_that_owns_through_capsule()data_ptr = 0x14c9f20
C++ : void destroyManagerCObject(PyObject*) delete [] 0x7fb7c9746010
PYTHON : AFTER calling test_capsule_way()
PYTHON : ----------- End while iteration
PYTHON : ---------------- While iteration ------------------- (3)
In the issue, I also have a demonstration of how if you do this and instead of the capsule, you pass boost::python::object() as the owner parameter, the memory is not freed and the python loop will stop because of the check on the process memory : https://github.com/boostorg/python/issues/97#issuecomment-520555403

Julia - Mutable struct with Attribute which is a Function and #code_warntype

In Julia, I want to have a mutable struct with an attribute which type is a Function, this function will have arguments:
mutable struct Class_example
function_with_arguments::Function
some_attribute::Int
function Class_example() new() end
function Class_example(function_wa::Function, some_a::Int)
this = new()
this.function_with_arguments = function_wa
this.some_attribute = some_a
this
end
end
I also want to do an action on this mutable struct :
function do_action_on_class(Class::Class_example)
return Class.function_with_arguments(Class.some_attribute ,2.0, true)
end
Then I define a function that aims to be my class attribute :
function do_something_function(arg1::Int, arg2::Float64, arg3::Bool)
if arg2 < 5.0
for i in 1:arg1
# Do Something Interesting
#show arg3
end
end
return 1
end
Finally, function_whith_arguments will be launch a huge number of time in my whole project, this is only a minimal example, so I want all this code to be very quick. That's why I use #code_warntype according to Julia's documentation Performance Tips
However, #code_warntype tells me this
body::Any
15 1 ─ %1 = (Base.getfield)(Class, :function_with_arguments)::Function
getproperty
%2 = (Base.getfield)(Class, :some_attribute)::Int64
%3 = (%1)(%2, 2.0, true)::Any │
return %3
Here, ::Function and the two ::Any are in red, indicating Julia can improve the performance of the code with a better implementation. So what's this correct implementation ? How should I declare my attribute function_whith_arguments as a Function type in my mutable struct ?
Whole code compilable :
mutable struct Class_example
function_with_arguments::Function
some_attribute::Int
function Class_example() new() end
function Class_example(function_wa::Function, some_a::Int)
this = new()
this.function_with_arguments = function_wa
this.some_attribute = some_a
this
end
end
function do_action_on_class(Class::Class_example)
return Class.function_with_arguments(Class.some_attribute ,2.0, true)
end
function do_something_function(arg1::Int, arg2::Float64, arg3::Bool)
if arg2 < 5.0
for i in 1:arg1
# Do Something Interesting
#show arg3
end
end
return 1
end
function main()
class::Class_example = Class_example(do_something_function, 4)
#code_warntype do_action_on_class(class)
end
main()
This will be efficient (well inferred). Note that I only modified (and renamed) the type.
mutable struct MyClass{F<:Function}
function_with_arguments::F
some_attribute::Int
end
function do_action_on_class(Class::MyClass)
return Class.function_with_arguments(Class.some_attribute ,2.0, true)
end
function do_something_function(arg1::Int, arg2::Float64, arg3::Bool)
if arg2 < 5.0
for i in 1:arg1
# Do Something Interesting
#show arg3
end
end
return 1
end
function main()
class::MyClass = MyClass(do_something_function, 4)
#code_warntype do_action_on_class(class)
end
main()
What did I do?
If you care about performance, you should never have fields of an abstract type, and isabstracttype(Function) == true. What you should do instead is parameterize on that fields type (F above, which can be any function. Note that isconcretetype(typeof(sin)) == true). This way, for any particular instance of MyCall the precise concrete type of every field is known at compile time.
Irrelevant for performance but: There is no need for a constructor that simply assigns all the arguments to all the fields. Such a constructor is defined by default implicitly.
You can read more about parametric types here.
On a side note, what you are doing looks a lot like trying to write OO-style in Julia. I'd recommend to not do this but instead use Julia the Julia way using multiple dispatch.

Resources