makepad_platform/
log.rs

1use crate::makepad_micro_serde::*;
2
3#[macro_export]
4macro_rules!log {
5    ( $ ( $ t: tt) *) => {
6        $crate::log::log_with_level(
7            file!(), 
8            line!()-1, 
9            column!()-1, 
10            line!()-1, 
11            column!() + 3, 
12            format!( $ ( $ t) *), 
13            $ crate::log::LogLevel::Log
14        )
15    }
16}
17
18#[macro_export]
19macro_rules!error {
20    ( $ ( $ t: tt) *) => {
21        $crate::log::log_with_level(
22            file!(), 
23            line!()-1, 
24            column!()-1, 
25            line!()-1, 
26            column!() + 3, 
27            format!( $ ( $ t) *), 
28            $crate::log::LogLevel::Error
29        )
30    }
31}
32
33#[macro_export]
34macro_rules! fmt_over {
35    ($dst:expr, $($arg:tt)*) => {
36        {
37            $dst.clear();
38            use std::fmt::Write;
39            $dst.write_fmt(std::format_args!($($arg)*)).unwrap();
40        }
41    };
42}
43
44#[macro_export]
45macro_rules! fmt_over_ref {
46    ($dst:expr, $($arg:tt)*) => {
47        {
48            $dst.clear();
49            use std::fmt::Write;
50            $dst.write_fmt(std::format_args!($($arg)*)).unwrap();
51            &$dst
52        }
53    };
54}
55
56#[macro_export]
57macro_rules!warning {
58    ( $ ( $ t: tt) *) => {
59        $crate::log::log_with_level(
60            file!(), 
61            line!()-1, 
62            column!()-1, 
63            line!()-1, 
64            column!() + 3, 
65            format!( $ ( $ t) *), 
66            $ crate::log::LogLevel::Warning
67        )
68    }
69}
70
71
72#[derive(Clone, PartialEq, Eq, Copy, Debug, SerBin, DeBin)]
73pub enum LogLevel{
74    Warning,
75    Error,
76    Log,
77    Wait,
78    Panic,
79}
80
81use crate::cx::Cx;
82use crate::studio::{AppToStudio,StudioLogItem};
83
84pub fn log_with_level(file_name:&str, line_start:u32, column_start:u32, line_end:u32, column_end:u32, message:String, level:LogLevel){
85    // lets send out our log message on the studio websocket 
86    #[cfg(target_arch = "wasm32")]{
87        extern "C" {
88            pub fn js_console_log(u8_ptr: u32, len: u32);
89            pub fn js_console_error(u8_ptr: u32, len: u32);
90        }
91        let msg = format!("{}:{}:{} - {}", file_name, line_start, column_start, message);
92        let buf = msg.as_bytes();
93        if let LogLevel::Error = level{
94            unsafe{js_console_error(buf.as_ptr() as u32, buf.len() as u32)};        
95        }
96        else{
97            unsafe{js_console_log(buf.as_ptr() as u32, buf.len() as u32)};        
98        }    
99    }
100
101    if !Cx::has_studio_web_socket() {
102        #[cfg(not (target_os = "android"))]
103        println!("{}:{}:{} - {}", file_name, line_start + 1, column_start + 1, message);
104       // if android, also log to ADB
105       #[cfg(target_os = "android")]
106       {
107           use std::ffi::c_int;
108           extern "C" { 
109               pub fn __android_log_write(prio: c_int, tag: *const u8, text: *const u8) -> c_int;
110           }
111           let msg = format!("{}:{}:{} - {}\0", file_name, line_start, column_start, message);
112           unsafe{__android_log_write(3, "Makepad\0".as_ptr(), msg.as_ptr())};
113       }
114       #[cfg(target_env="ohos")]
115       {
116            let msg = format!("{}:{}:{} - {}\0", file_name, line_start, column_start, message);
117            let hilevel:hilog_sys::LogLevel = match level {
118                LogLevel::Warning => {hilog_sys::LogLevel::LOG_WARN}
119                LogLevel::Error => {hilog_sys::LogLevel::LOG_ERROR}
120                LogLevel::Log => {hilog_sys::LogLevel::LOG_INFO}
121                _=> {hilog_sys::LogLevel::LOG_INFO}
122            };
123            unsafe {hilog_sys::OH_LOG_Print(hilog_sys::LogType::LOG_APP,hilevel, 0x03D00, "makepad-ohos\0".as_ptr().cast(), "%{public}s\0".as_ptr().cast(), msg.as_ptr())};
124       }
125    }
126    else{
127        
128       #[cfg(target_os = "android")]
129        {
130            use std::ffi::c_int;
131            extern "C" { 
132                pub fn __android_log_write(prio: c_int, tag: *const u8, text: *const u8) -> c_int;
133            }
134            let msg = format!("{}:{}:{} - {}\0", file_name, line_start, column_start, message);
135            unsafe{__android_log_write(3, "Makepad\0".as_ptr(), msg.as_ptr())};
136        }
137        
138        Cx::send_studio_message(AppToStudio::LogItem(StudioLogItem{
139            file_name: file_name.to_string(),
140            line_start,
141            column_start,
142            line_end,
143            column_end,
144            message,
145            explanation: None,
146            level
147        }));
148    }
149}
150
151
152use std::time::Instant;
153
154pub fn profile_start() -> Instant {
155    Instant::now()
156}
157
158#[macro_export]
159macro_rules!profile_end {
160    ( $ inst: expr) => {
161        $crate::log::log_with_level(
162            file!(),
163            line!(),
164            column!(),
165            line!(),
166            column!() + 4,
167            format!("Profile time {} ms", ( $ inst.elapsed().as_nanos() as f64) / 1000000f64),
168            $crate::log::LogLevel::Log
169        )
170    }
171}
172
173#[macro_export]
174macro_rules!profile_end_log {
175    ( $inst:expr, $ ( $ t: tt) *) => {
176        $crate::log::log_with_level(
177            file!(),
178            line!(),
179            column!(),
180            line!(),
181            column!() + 4,
182            format!("Profile time {} {}",( $ inst.elapsed().as_nanos() as f64) / 1000000f64, format!( $ ( $ t) *)), 
183            $ crate::log::LogLevel::Log
184        )
185    }
186}