import React, { Fragment, useEffect } from 'react';
import PropTypes from 'prop-types';
import { useRos } from '../RosConnection';
import { Ros, Service, ServiceRequest, ServiceResponse } from 'roslib';
export const ServiceCaller = (props: ServiceCallerProps) => {
const { name, serviceType, trigger, request, callback, failedCallback } = props;
const ros = useRos();
useEffect(() => {
if (trigger) {
callService(ros, name, serviceType, request, callback, failedCallback);
}
}, [trigger]);
return ;
};
export type DefaultSrvReqType = object;
export type DefaultSrvRespType = ServiceResponse;
export interface ServiceCallerProps<
TReq = DefaultSrvReqType,
TResp = DefaultSrvRespType,
> {
name: string;
serviceType: string;
trigger?: boolean;
request?: TReq;
callback?: (resp: TResp) => void;
failedCallback?: (error: any) => void;
}
export type ServiceCB<
TReq = DefaultSrvReqType,
TResp = DefaultSrvRespType,
> = ServiceCallerProps['callback'];
ServiceCaller.propTypes = {
name: PropTypes.string.isRequired,
serviceType: PropTypes.string,
trigger: PropTypes.bool,
request: PropTypes.object,
callback: PropTypes.func,
failedCallback: PropTypes.func,
};
function respCb(resp: TResp) {}
export function callService(
ros: Ros,
name: string,
serviceType: string,
request?: TReq,
callback: ServiceCB = respCb,
failedCallback?: (error: any) => void,
) {
// ServiceRequest just runs Object.assign under the hood, no reason to template as TReq
// Just need to take in TReq and pass to ServiceRequest
const service = new Service({ ros, name, serviceType });
const serviceRequest = new ServiceRequest(request);
service.callService(serviceRequest, callback, failedCallback);
}