/* ----------------------------------------------------------------------------- This source file is part of OpenSpace3D For the latest info, see http://www.openspace3d.com Copyright (c) 2012 I-maginer This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA, or go to http://www.gnu.org/copyleft/lesser.txt ----------------------------------------------------------------------------- */ /*! @defgroup plugITApi OpenSpace3D plugIT Api * OpenSpace3D plugIT Api * @{ */ /** @} */ /* ********************************************************************************************* / DMS compatibility / ********************************************************************************************* */ var iLinkSpoofing = 1000;; var iLinkSpoofingWarning = 100;; typeof lGlobalDmsVar = [[S [S fun [] S]] r1];; typeof DMSdebug = fun [S] I;; typeof DMSerror = fun [S] I;; struct DMIAction = [ DACT_sName : S, DACT_funCb : fun [S S S S S] I ] mkDMIAction;; struct DMIlink = [ DLINK_action : DMIAction, DLINK_sParam : S, DLINK_iNbCall : I ] mkDMILink;; struct DMIEvent = [ DEVT_sName : S, DEVT_lLinks : [[S DMIlink] r1] ] mkDMIEvent;; struct DMI = [ DMI_sName : S, DMI_chn : Chn, DMI_lActions : [[S DMIAction] r1], DMI_lEvents : [[S DMIEvent] r1] ]mkDMI;; typeof this = DMI;; typeof DMSnbDmi = I;; typeof DMSdmi = [[S DMI] r1];; //proto execDmsCode = fun [] S;; /* ********************************************************************************************* / / ********************************************************************************************* */ fun niltest(a,b)=if a==nil then b else a;; fun Tunder(s)= if strcmp s "_" then s else nil;; fun underT(s)= if (s == nil) then "_" else s;; fun swbystr(a,b)=let a->[x _] in !strcmp x b;; fun getSwitchStr(l,s)=search_in_list l @swbystr s;; /* return wether a string element is in a list */ fun strFindList(l,a)= if l==nil then 0 else let l->[x n] in if !strcmp a x then 1 else strFindList n a;; /* ********************************************************************************************* / / ********************************************************************************************* */ fun _DMSrootModule()= let hd DMSdmi -> [n d] in d;; fun _DMSgetByHandle(h)= switchstr DMSdmi h;; fun _DMSremoveEvent(d, name)= let getSwitchStr d.DMI_lEvents name -> evt in if evt == nil then nil else set d.DMI_lEvents = remove_from_list d.DMI_lEvents evt; 0;; fun _DMSremoveEvents(d, l)= if l==nil then 0 else let getSwitchStr d.DMI_lEvents hd l -> x in ( if x==nil then nil else set d.DMI_lEvents=remove_from_list d.DMI_lEvents x; _DMSremoveEvents d tl l; );; fun _DMSfindEventStartedByName(l, name)= let nil -> ndata in ( while (l != nil) do ( let hd l -> [evt _ ] in if (strcmp name (substr evt 0 (strlen name))) then nil else set ndata = evt::ndata; set l = tl l; ); ndata; );; fun removeFromListStartedBy(l, name)= if l == nil then nil else ( let l -> [elem next] in let elem -> [action _ ] in if (!strcmp name (substr action 0 (strlen name))) then (removeFromListStartedBy next name) else elem::(removeFromListStartedBy next name); );; fun _DMSremoveEventStartedByName(d, name)= set d.DMI_lEvents = removeFromListStartedBy d.DMI_lEvents name; 0;; fun _DMSgetEvent(d, name)= let switchstr d.DMI_lEvents name -> evt in if (evt == nil) then let mkDMIEvent [name nil] -> nevt in ( set d.DMI_lEvents = [name nevt]::d.DMI_lEvents; nevt; ) else evt;; fun _DMSgetAction(d, name)= let switchstr d.DMI_lActions name -> act in if (act == nil) then let mkDMIAction [name nil] -> nact in ( set d.DMI_lActions = [name nact]::d.DMI_lActions; nact; ) else act;; fun _DMSdefineAction(d, name, cbfun)= //exec DMSerror with [strcatn "Link DEBUG : add action : "::name::nil]; let _DMSgetAction d name -> act in ( set act.DACT_funCb = cbfun; act; );; fun _DMSremoveActions(d, l)= if l==nil then 0 else let getSwitchStr d.DMI_lActions hd l -> x in ( if x==nil then nil else set d.DMI_lActions=remove_from_list d.DMI_lActions x; _DMSremoveActions d tl l; );; fun _DMSfindActionStartedByName(l, name)= let nil -> ndata in ( while (l != nil) do ( let hd l -> [action _ ] in if (strcmp name (substr action 0 (strlen name))) then nil else set ndata = action::ndata; set l = tl l; ); ndata; );; fun _DMSremoveActionStartedByName(d, name)= set d.DMI_lActions = removeFromListStartedBy d.DMI_lActions name; 0;; fun listDMSmodules()= if (DMSdmi != nil) then nil else addLogMessage "DMSdmi is NIL !!"; let DMSdmi -> l in while (l != nil) do ( let hd l -> [elt _] in addLogMessage strcat "DMI : " elt; set l = tl l; ); 0;; fun removeDmiById(sid)= //addLogMessage strcat "Delete instance DMI : " sid; set DMSdmi = remove_sid_from_list DMSdmi sid; 0;; fun addDmiById(name, d)= set DMSdmi = lcat DMSdmi [name d]::nil; d;; fun cbDebugConsol(mess)= addLogMessage mess; _fooS strcat ">>>>>>>>>>>>>> Mini DHDMS debug > " mess; 0;; fun getDMI(name)= switchstr DMSdmi name;; fun createDMI(name)= let switchstr DMSdmi name -> dd in if (dd == nil) then ( //addLogMessage strcat "Create instance DMI : " name; addDmiById name mkDMI [name _channel nil nil] ) else dd;; fun createRootDMI(name)= let mkDMI [name _channel nil nil] -> d in ( addDmiById name d; set DMSerror = @cbDebugConsol; set this = _DMSrootModule; );; /* ********************************************************************************************* / / ********************************************************************************************* */ fun getModNbLinks(d)= let d.DMI_lEvents -> l in let 0 -> nb in ( while (l != nil) do ( let hd l -> [_ evt] in set nb = nb + (sizelist evt.DEVT_lLinks); set l = tl l; ); nb; );; fun getModNbEvents(d)= sizelist d.DMI_lEvents;; fun getModNbActions(d)= sizelist d.DMI_lEvents;; fun getModLinkByLink(d, event, action, param, reply)= let switchstr d.DMI_lEvents event -> evt in switchstr evt.DEVT_lLinks strcatn action::(underT param)::(underT reply)::nil;; fun delModLink(d, slink)= let hd strextr slink -> [event [action [param [reply [cond _]]]]] in let switchstr d.DMI_lEvents event -> evt in let getSwitchStr evt.DEVT_lLinks strcatn action::(underT param)::(underT reply)::nil -> tlink in ( set evt.DEVT_lLinks = remove_from_list evt.DEVT_lLinks tlink; if (evt.DEVT_lLinks != nil) then nil else _DMSremoveEvent d event; ); 0;; fun addModLink(d, da, event, action, param, reply)= //exec DMSerror with [strcatn "Link DEBUG : add event : "::event::nil]; let _DMSgetEvent d event -> evt in let mkDMILink [(_DMSgetAction da action) (Tunder param) 0] -> link in set evt.DEVT_lLinks = lcat evt.DEVT_lLinks [strcatn action::(underT param)::(underT reply)::nil link]::nil; 0;; fun setModLink(d, da, oldlink, newlink)= let hd strextr newlink -> [nevent [naction [nparam [nreply [ncond _]]]]] in let getModLinkByLink d nevent naction nparam nreply -> existlink in if existlink != nil then ( 0; ) else ( if oldlink == nil then ( //add link addModLink d da nevent naction nparam nreply; 1; ) else ( delModLink d oldlink; addModLink d da nevent naction nparam nreply; 1; ); );; fun clearModLinks(d)= set d.DMI_lActions = nil; set d.DMI_lEvents = nil; 0;; /* ********************************************************************************************* / / ********************************************************************************************* */ fun _DMSsetGlobalVar(name, value)= let switchstr lGlobalDmsVar name -> tval in if (tval == nil) then ( set lGlobalDmsVar = [name [value nil]]::lGlobalDmsVar; 0; ) else ( mutate tval <- [value _]; 0; ); 0;; fun _DMSsetGlobalVarFun(name, cbfun)= let switchstr lGlobalDmsVar name -> tval in if (tval == nil) then ( set lGlobalDmsVar = [name [nil cbfun]]::lGlobalDmsVar; 0; ) else ( mutate tval <- [_ cbfun]; 0; ); 0;; fun _DMSremoveGlobalVar(name)= set lGlobalDmsVar = remove_sid_from_list lGlobalDmsVar name; 0;; fun _DMSgetGlobalVar(name)= let switchstr lGlobalDmsVar name -> tval in if (tval == nil) then nil else let tval -> [value cbfun] in ( if (cbfun == nil) then value else exec cbfun with []; );; fun _DMSclearGlobalVars()= set lGlobalDmsVar = nil; 0;; // replace vars %varname% in string by values in global variables fun _DMSapplyByGlobalVar(s)= if (strfind "%" s 0) == nil then s else let 0 -> ipos in ( while ((ipos != nil) && (set ipos = (strfindi "%" s ipos)) != nil) do ( let (strfindi "%" s ipos + 1) -> endpos in if (endpos == nil) then set ipos = nil else ( let substr s (ipos + 1) (endpos - (ipos + 1)) -> vname in let _DMSgetGlobalVar vname -> value in if value == nil then set ipos = endpos + 1 else ( set s = strreplace s (strcatn "%"::vname::"%"::nil) value; set ipos = ipos + 1; ); ); ); s; );; fun _DMSapplyLinkCode(s)= if (strfind "[code]" s 0) == nil then s else let 0 -> ipos in ( while ((ipos != nil) && (set ipos = (strfindi "[code]" s ipos)) != nil) do ( let (strfindi "[/code]" s ipos + 1) -> endpos in if (endpos == nil) then set ipos = nil else ( let substr s (ipos + 6) (endpos - (ipos + 6)) -> code in let strcatn "proto execDmsCode = fun [] S;;\nfun execDmsCode()= "::code::";;"::nil -> funcode in let _openchannel nil nil (_envchannel _channel) -> nchn in let execch nchn @_loadS [funcode] -> ret in let _scriptc2 nchn "execDmsCode" nil -> value in ( set s = strreplace s (strcatn "[code]"::code::"[/code]"::nil) value; set ipos = ipos + 7; if (value != nil) then nil else ( addLogMessage "Error in link code:"; let (execch nchn @_testpakS [funcode]) -> rettest in addLogMessage strbuild (tl strextr rettest); ); _killchannel nchn; ); 0; ); ); s; );; fun _DMSreadParam(param, puser)= if puser == nil then param else let if (strfindi "$" puser 0) == nil then puser else replaceByKeyIndex2 puser "$" param -> np in _DMSapplyLinkCode _DMSapplyByGlobalVar np;; fun _DMShasEvent(d, ev)= let switchstr d.DMI_lEvents ev -> event in let event.DEVT_lLinks -> l in if (l == nil) then 0 else 1;; /*! @ingroup plugITApi * \brief Send an event to another plugITs * * Prototype: fun [DMI S S S] I * * \param DMI : use 'this' for this parameter in OpenSpace3D * \param S : the event name, generally constructed with (getPluginInstanceEvent inst "Event name") * \param S : the event user parameter * \param S : the event reply value * * \return 0 **/ fun _DMSevent(d, ev, param, repl)= let switchstr d.DMI_lEvents ev -> event in let event.DEVT_lLinks -> l in while (l != nil) do ( let hd l -> [_ link] in if (link.DLINK_iNbCall > iLinkSpoofing) then nil else // test if link param exist use in priority let _DMSreadParam param link.DLINK_sParam -> nparam in ( set link.DLINK_iNbCall = link.DLINK_iNbCall + 1; // link loop detection if (link.DLINK_iNbCall < iLinkSpoofingWarning) then nil else ( if ((mod link.DLINK_iNbCall iLinkSpoofingWarning) != 0) then nil else exec DMSerror with [strcatn "Link WARNING : Possible loop or too fast repetitive event detected. - Nb : "::(itoa link.DLINK_iNbCall)::" - Link : "::ev::" -> "::link.DLINK_action.DACT_sName::" with param : "::(if nparam == nil then "NIL" else nparam)::nil]; ); if (link.DLINK_iNbCall >= iLinkSpoofing) then ( exec DMSerror with [strcatn "Link ERROR : Loop detected. This link have been disabled - Link : "::ev::" -> "::link.DLINK_action.DACT_sName::" with param : "::(if nparam == nil then "NIL" else nparam)::nil]; 0; ) else ( if DMSdebug == nil then nil else exec DMSdebug with [strcatn "Event : "::ev::" with param : "::(if param == nil then "NIL" else param)::nil]; if DMSdebug == nil then nil else exec DMSdebug with [strcatn "Action : "::link.DLINK_action.DACT_sName::" with param : "::(if nparam == nil then "NIL" else nparam)::" and reply param : "::(if repl == nil then "NIL" else repl)::nil]; exec link.DLINK_action.DACT_funCb with [ev link.DLINK_action.DACT_sName nparam nil repl]; //execch d.DMI_chn link.DLINK_action.DACT_funCb [d link.DLINK_action.DACT_sName nparam nil repl]; 0; ); set link.DLINK_iNbCall = link.DLINK_iNbCall - 1; ); set l = tl l; ); 0;; /* ********************************************************************************************* / C3dx definitions / ********************************************************************************************* */ typeof s3dMainSession = V3Dsession;; //!< the default 3D session structure typeof v3dMain = V3Dview;; //!< the default 3D view structure /*! @ingroup plugITApi * @defgroup pmainvar Common global variables * Common global variables * @{ */ fun c3dXsession()= s3dMainSession;; //!< the default 3D session structure fun c3dXview()= v3dMain;; //!< the default 3D view structure fun c3dXwin()= v3dMain.V3D_win;; //!< the default 3D window fun DMSwin()= v3dMain.V3D_win;; //!< the default 3D window (alias) // used for AR plugITs, this value can be changed by the camera input plugIT var c3dxCameraSize = [640 480];; //!< the default web cam size, this can be changed by AR plugIT for example var c3dxCameraFlip = 0;; //!< the default web cam flip state, this can be changed by AR plugIT for example /** @} */