Skip to content

Commit

Permalink
add custom args support
Browse files Browse the repository at this point in the history
  • Loading branch information
Tiaansu committed Sep 28, 2024
1 parent 386c0f2 commit b37c4ba
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 11 deletions.
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,10 @@ cargo build --release
> ```
## API
* #### cron_new(const pattern[], const callback[])
* #### cron_new(const pattern[], const callback[], const args[] = "", {Float, _}:...)
* `pattern[]` - cron pattern
* `callback[]` - callback to execute every call
* `args[]` - custom arguments
**Returns**
the cron job id
Expand All @@ -43,13 +44,13 @@ cargo build --release
new CRON:cron_id = INVALID_CRON_ID;
main()
{
cron_new("* * * * * *", "SecondTimer");
cron_new("* * * * * *", "SecondTimer", "i", 5);
}
forward SecondTimer();
public SecondTimer()
{
printf("Hi! I am called by cron id: %i", _:cron_id);
printf("Hi! I am called by cron id: %i and I also have a custom args: %i!", _:cron_id, num);
}
```
Expand Down
13 changes: 7 additions & 6 deletions include/samp_cron.inc
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,11 @@
#define INVALID_CRON_ID (CRON:0)

/*
cron_new(const pattern[], const callback[])
cron_new(const pattern[], const callback[], const args[] = "", {Float, _}:...)
Params
`pattern[]` - cron pattern
`callback[]` - callback to execute every call
`args[]` - custom arguments
Returns
the cron job id
Expand All @@ -23,17 +24,17 @@ cron_new(const pattern[], const callback[])
new CRON:cron_id = INVALID_CRON_ID;
main()
{
cron_new("* * * * * *", "SecondTimer");
cron_new("* * * * * *", "SecondTimer", "i", 5);
}
forward SecondTimer();
public SecondTimer()
forward SecondTimer(num);
public SecondTimer(num)
{
printf("Hi! I am called by cron id: %i", _:cron_id);
printf("Hi! I am called by cron id: %i and I also have a custom args: %i!", _:cron_id, num);
}
```
*/
native CRON:cron_new(const pattern[], const callback[]);
native CRON:cron_new(const pattern[], const callback[], const args[] = "", {Float, _}:...);

/*
bool:cron_is_valid(CRON:id)
Expand Down
6 changes: 6 additions & 0 deletions src/internals.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
use crate::SampCron;
use rcron::Uuid;

#[derive(Debug)]
pub enum ArgumentTypes {
Primitive(i32),
String(Vec<u8>),
}

static mut GLOBAL_INDEX: usize = 0;

pub fn insert_uuid(
Expand Down
58 changes: 57 additions & 1 deletion src/natives.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::internals::insert_uuid;
use crate::internals::{insert_uuid, ArgumentTypes};
use log::error;
use rcron::{Job, Schedule};
use samp::error::AmxError;
Expand All @@ -10,11 +10,48 @@ impl super::SampCron<'static> {
pub fn cron_new(&mut self, amx: &'static Amx, mut args: samp::args::Args) -> AmxResult<i32> {
let cron_pattern = args.next::<AmxString>().ok_or(AmxError::Params)?.to_string();
let callback_name = args.next::<AmxString>().ok_or(AmxError::Params)?.to_string();
let mut format: Vec<u8> = Vec::new();

if args.count() > 2 {
if let Some(specifiers) = args.next::<AmxString>() {
format = specifiers.to_bytes();
}
}

if !format.is_empty() && format.len() != args.count() - 3 {
error!(
"The argument count mismatch expected: {} provided: {}.",
format.len(),
args.count() - 3
);
return Ok(0);
}

if Schedule::from_str(&cron_pattern).is_err() {
error!("Invalid CRON expression: {}", cron_pattern);
return Ok(0);
}

let mut optional_args: Vec<ArgumentTypes> = Vec::new();

for specifiers in format {
match specifiers {
b'd' | b'i' | b'f' => {
optional_args.push(ArgumentTypes::Primitive(
*args.next::<Ref<i32>>().ok_or(AmxError::Params)?,
));
}
b's' => {
let argument: Ref<i32> = args.next().ok_or(AmxError::Params)?;
let amx_str = AmxString::from_raw(amx, argument.address())?;
optional_args.push(ArgumentTypes::String(amx_str.to_bytes()));
}
_ => {
error!("Unknown specifier type: {}", specifiers);
return Ok(0);
}
}
}

let public_index = amx.find_public(&callback_name);

Expand All @@ -24,6 +61,25 @@ impl super::SampCron<'static> {
}

let job = Job::new(cron_pattern.parse().unwrap(), move || {
let allocator = amx.allocator();

for param in optional_args.iter().rev() {
match param {
ArgumentTypes::Primitive(x) => {
if amx.push(x).is_err() {
error!("*Cannot execute callback {:?}", callback_name);
}
}
ArgumentTypes::String(data) => {
let buf = allocator.allot_buffer(data.len() + 1).unwrap();
let amx_str = unsafe { AmxString::new(buf, data) };
if amx.push(amx_str).is_err() {
error!("*Cannot execute callback {:?}", callback_name);
}
}
}
}

if amx.exec(public_index.as_ref().unwrap().to_owned()).is_err() {
error!("Cannot execute callback: {:?}", callback_name);
}
Expand Down
2 changes: 1 addition & 1 deletion src/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub struct SampCron<'a> {

impl SampPlugin for SampCron<'static> {
fn on_load(&mut self) {
info!("Version: 0.0.1");
info!("Version: 0.1.0");
}

fn on_unload(&mut self) {
Expand Down

0 comments on commit b37c4ba

Please sign in to comment.