<commit_before>// Copyright 2013 The GLFW-RS Developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Private callback support functions.

use libc::{c_double, c_int, c_uint};
use std::mem;

use super::*;

macro_rules! callback(
    (
        type Args = ($($arg:ident: $arg_ty:ty),*);
        type Callback = $Callback:ident;
        let ext_set = $ext_set:expr;
        fn callback($($ext_arg:ident: $ext_arg_ty:ty),*) $call:expr
    ) => (
        local_data_key!(CALLBACK_KEY: Box<Object<Args> + 'static>)

        type Args = ($($arg_ty),*,);

        trait Object<T> {
            fn call(&self, args: T);
        }

        impl<UserData> Object<Args> for ::Callback<fn($($arg_ty),*, &UserData), UserData> {
            fn call(&self, ($($arg),*,): Args) {
                (self.f)($($arg),*, &self.data);
            }
        }

        pub fn set<UserData: 'static>(f: ::$Callback<UserData>) {
            CALLBACK_KEY.replace(Some(box f as Box<Object<Args> + 'static>));
            ($ext_set)(Some(callback));
        }

        pub fn unset() {
            CALLBACK_KEY.replace(None);
            ($ext_set)(None);
        }

        extern "C" fn callback($($ext_arg: $ext_arg_ty),*) {
            match CALLBACK_KEY.get() {
                Some(cb) => unsafe { cb.call($call) },
                _ => {}
            }
        }
    )
)

pub mod error {
    use libc::{c_int, c_char};
    use std::mem;
    use std::string;

    callback!(
        type Args = (error: ::Error, description: String);
        type Callback = ErrorCallback;
        let ext_set = |cb| unsafe { ::ffi::glfwSetErrorCallback(cb) };
        fn callback(error: c_int, description: *const c_char) {
            (mem::transmute(error), string::String::from_raw_buf(
                mem::transmute(description)))
        }
    )
}

pub mod monitor {
    use libc::{c_int};
    use std::mem;
    use std::kinds::marker;

    callback!(
        type Args = (monitor: ::Monitor, event: ::MonitorEvent);
        type Callback = MonitorCallback;
        let ext_set = |cb| unsafe { ::ffi::glfwSetMonitorCallback(cb) };<commit_msg>Avoid an unnecessary transmute call.<commit_after>// Copyright 2013 The GLFW-RS Developers. For a full listing of the authors,
// refer to the AUTHORS file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Private callback support functions.

use libc::{c_double, c_int, c_uint};
use std::mem;

use super::*;

macro_rules! callback(
    (
        type Args = ($($arg:ident: $arg_ty:ty),*);
        type Callback = $Callback:ident;
        let ext_set = $ext_set:expr;
        fn callback($($ext_arg:ident: $ext_arg_ty:ty),*) $call:expr
    ) => (
        local_data_key!(CALLBACK_KEY: Box<Object<Args> + 'static>)

        type Args = ($($arg_ty),*,);

        trait Object<T> {
            fn call(&self, args: T);
        }

        impl<UserData> Object<Args> for ::Callback<fn($($arg_ty),*, &UserData), UserData> {
            fn call(&self, ($($arg),*,): Args) {
                (self.f)($($arg),*, &self.data);
            }
        }

        pub fn set<UserData: 'static>(f: ::$Callback<UserData>) {
            CALLBACK_KEY.replace(Some(box f as Box<Object<Args> + 'static>));
            ($ext_set)(Some(callback));
        }

        pub fn unset() {
            CALLBACK_KEY.replace(None);
            ($ext_set)(None);
        }

        extern "C" fn callback($($ext_arg: $ext_arg_ty),*) {
            match CALLBACK_KEY.get() {
                Some(cb) => unsafe { cb.call($call) },
                _ => {}
            }
        }
    )
)

pub mod error {
    use libc::{c_int, c_char};
    use std::mem;
    use std::string;

    callback!(
        type Args = (error: ::Error, description: String);
        type Callback = ErrorCallback;
        let ext_set = |cb| unsafe { ::ffi::glfwSetErrorCallback(cb) };
        fn callback(error: c_int, description: *const c_char) {
            (mem::transmute(error), string::String::from_raw_buf(
                description as *const u8))
        }
    )
}

pub mod monitor {
    use libc::{c_int};
    use std::mem;
    use std::kinds::marker;

    callback!(
        type Args = (monitor: ::Monitor, event: ::MonitorEvent);
        type Callback = MonitorCallback;
        let ext_set = |cb| unsafe { ::ffi::glfwSetMonitorCallback(cb) };
{'fraction_non_alphanumeric': 0.14285714285714285, 'fraction_numerical': 0.0030897855325336242, 'mean_word_length': 2.441525953721076, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1599735', 'n_tokens_mistral': 1690, 'n_tokens_neox': 1660, 'n_words': 485}