/*************************************/ /* Original Version by David Yates */ /* Copyright Atos 2007 */ /*************************************/ #ifndef BNCS_SCRIPT_HELPER_INCLUDED #define BNCS_SCRIPT_HELPER_INCLUDED #include #include #include static char BNCS_SCRIPTHELPER_SIG[]="BNCS_SIG,name=bncs_script_helper,type=LIB,version=4.8.6.0,date=16/06/2017,author=David Yates"; /* enum revertiveType { ROUTER=1, INFODRIVER, GPI, DATABASE, }; // the following may be optionally filled by different revertive types // e.g. database is not used by the infodriver revertive type int iDevice; int iDatabase; int iIndex; // infodriver slot number / router index int iInfo; // router source number char szInfo[ 256 ]; // infodriver slot contents / router source name enum revertiveType type; const char *szDevice; // NYI const char *szIndex; // NYI */ /** \class revertiveNotify \brief A class that passes on information about BNCS events \par Example - Infodriver \code // for an infodriver revertive from slot 456 of device 123 containing text "Hello mum" void mypanel::revertiveCallback( revertiveNotify *r ) { int device = r->device(); // device is 123 int index = r->index(); // index is 456 bncs_string info = r->sInfo(); // info is "hello mum" int type = r->type(); // type is 2 (see CB_REVERTIVE documentation) } \endcode \par Example - Router \code // for a router revertive from destination 456 of device 123 for source 1 of name "0001" void mypanel::revertiveCallback( revertiveNotify *r ) { int device = r->device(); // device is 123 int index = r->index(); // index is 456 int iInfo = r->info(); // info is 1 bncs_string sInfo = r->sInfo(); // name is "0001" int type = r->type(); // type is 1 (see CB_REVERTIVE documentation) } \endcode \par Example - Database \code // for a database 1 name change for index 456 of device 123 void mypanel::databaseCallback( revertiveNotify *r ) { int device = r->device(); // device is 123 int index = r->index(); // index is 456 int database = r->database(); // database is 1 int type = r->type(); // type is 4 (see CB_REVERTIVE documentation) } \endcode */ class revertiveNotify { private: CB_REVERTIVE *r; public: #ifndef DOXYGEN_SHOULD_SKIP_THIS /** Used internally */ revertiveNotify( CB_REVERTIVE * in ) { r = in; }; #endif // DOXYGEN_SHOULD_SKIP_THIS /** Device number Return the device ID of the device that generated this notification */ int device( void ) { return r->iDevice; }; /** Database number Return the number of the database - this is only relevant for database change notification messages. Its value is undefined for other notification messages */ int database( void ) { return r->iDatabase; }; /** Index Return the index for which this notification relates. For an infodriver it is the slot number, for a router it is the destination number. */ int index( void ) { return r->iIndex; }; /** Integer information Return the integer information. For a router this is the source number whereas sInfo() returns the source name. For GPIs this is the state. For Infodrivers this value is zero. */ int info( void ) { return r->iInfo; }; /** String information Return the string information. For a router this is the source name whereas info() returns the source number. For an infodriver this value is the slot contents. For GPIs this value is null. */ bncs_string sInfo( void ) { return r->szInfo; }; /** The type of revertive that this is. This is defined in CB_REVETIVE as: \code enum revertiveType { ROUTER=1, // 1 INFODRIVER, // 2 GPI, // 3 DATABASE, // 4 }; \endcode */ int type( void ) { return r->type; }; /** Send the raw notification string to the debugger with optional header \param[in] header Text that will prepend the debug string for identification purposes */ void dump( const char* header = 0 ) { bncs_string out; switch( r->type ) { case 1: out = bncs_string( "RR %1 %2 %3 '%4'" ).arg( r->iDevice ).arg( r->iIndex ).arg( r->iInfo ).arg( r->szInfo ); break; case 2: out = bncs_string( "IR %1 %2 '%3'" ).arg( r->iDevice ).arg( r->iIndex ).arg( r->szInfo ); break; case 3: out = bncs_string( "GR %1 %2 %3" ).arg( r->iDevice ).arg( r->iIndex ).arg( r->iInfo ); break; case 4: out = bncs_string( "RD %1 %2 %3 '%4'" ).arg( r->iDevice ).arg( r->iIndex ).arg( r->iDatabase ).arg( r->szInfo ); break; } if( header ) OutputDebugString( bncs_string( "%1: %2" ).arg( header ).arg( out )); else OutputDebugString( out ); } }; /** \class buttonNotify \brief A class that passes on information about button notifications This class gives easy access to the id of the button that generated a notification and the panel on which it sits.\n Parameter passing is using\n <parameter>=<value>\n method and this class also provides direct access to the <parameter> and <value>. \par Example \code // for button called "mybutton" on panel "main" notifying us of "button.colour.top=red" void mypanel::buttonCallback( buttonNotify *b ) { bncs_string s1 = b->id(); // s1 contains "mybutton" bncs_string s2 = b->panel(); // s2 contains "main" bncs_string s3= b->command(); // s3 contains "button" int i = b->subs(); // i contains 2 bncs_string s4 = b->sub( 0 ); // s4 contains "colour" bncs_string s5 = b->sub( 1 ); // s5 contains "top" bncs_string s6 = b->value(); // s6 contains "red" } \endcode In reality panel and button ids are likely to be numeric so you're likely to write something like this\n Note that the bncs_string takes care of the conversion to type int to keep the switch-case happy. \code // for button called "mybutton" on panel "main" notifying us of "button.colour.top=red" void mypanel::buttonCallback( buttonNotify *b ) { switch( b->panel()) { case 1: switch( b->id()) { case 2: textPut( "text", "you pressed button 2 on panel 1", 1, 1 ); } break; } } \endcode */ class buttonNotify { private: CB_BUTTON * b; public: #ifndef DOXYGEN_SHOULD_SKIP_THIS /** Used internally */ buttonNotify( CB_BUTTON * in ) { b = in; }; #endif // DOXYGEN_SHOULD_SKIP_THIS /** Button ID Return the ID of the button that generated this notification */ bncs_string id() { return b->szId; }; /** Panel ID Return the name of the panel which hosted the button */ bncs_string panel() { return b->szPanel; }; /** Number of sub command parameters Return the number of sub parameters this notification had\n \code button.colour=red \endcode has a subs() count of 1\n */ int subs() { return b->dec->subs; }; /** Return the sub parameters at given index \param in zero based index of parameter to return \par Example: \code // for a notification of "button.colour.top=red" void mypanel::buttonCallback( buttonNotify *b ) { bncs_string s1 = b->sub( 0 ); // s1 contains "colour" bncs_string s2 = b->sub( 1 ); // s2 contains "top" } \endcode */ bncs_string sub( int in ) { return b->dec->sub[ in ]; }; /** Return the notification command \par Example: \code // for a notification of "button.colour=red" void mypanel::buttonCallback( buttonNotify *b ) { bncs_string s = b->command(); // s contains "button" } \endcode */ bncs_string command() { return b->dec->command; }; /** Return the notification value \par Example: \code // for a notification of "button.colour=red" void mypanel::buttonCallback( buttonNotify *b ) { bncs_string s = b->value(); // s contains "red" } \endcode */ bncs_string value() { return b->dec->value; }; /** Send the raw notification string to the debugger with optional header \param[in] header Text that will prepend the debug string for identification purposes */ void dump( const char* header = 0 ) { if( b && b->dec ) { bncs_string out = b->szId; out += ": "; out += b->dec->command; for( int x = 0 ; x < b->dec->subs ; x++ ) out += bncs_string( ".%1" ).arg( b->dec->sub[ x ] ); out += "="; out += b->dec->value; if( header ) OutputDebugString( bncs_string( "%1: %2" ).arg( header ).arg( out )); else OutputDebugString( out ); } } }; /** \class parentNotify \brief A class that passes on information about parent notifications */ class parentNotify { private: decodeCaptionString *dec; public: #ifndef DOXYGEN_SHOULD_SKIP_THIS /** Used internally */ parentNotify( decodeCaptionString *in) { dec = in; } #endif // DOXYGEN_SHOULD_SKIP_THIS /** Number of sub command parameters Return the number of sub parameters this notification had\n \code button.colour=red \endcode has a subs() count of 1\n */ int subs() { return dec->subs; }; /** Return the sub parameters at given index \param in zero based index of parameter to return \par Example: \code // for a notification of "button.colour.top=red" void mypanel::parentCallback( parentNotify *p ) { bncs_string s1 = p->sub( 0 ); // s1 contains "colour" bncs_string s2 = p->sub( 1 ); // s2 contains "top" } \endcode */ bncs_string sub( int in ) { return dec->sub[ in ]; }; /** Return the notification command \par Example: \code // for a notification of "button.colour=red" void mypanel::parentCallback( parentNotify *p ) { bncs_string s = p->command(); // s contains "button" } \endcode */ bncs_string command() { return dec->command; }; /** Return the notification value \par Example: \code // for a notification of "button.colour=red" void mypanel::parentCallback( parentNotify *p ) { bncs_string s = p->value(); // s contains "red" } \endcode */ bncs_string value() { return dec->value; }; /** Send the raw notification string to the debugger with optional header \param[in] header Text that will prepend the debug string for identification purposes */ void dump( const char* header = 0 ) { if( dec ) { bncs_string out = dec->command; for( int x = 0 ; x < dec->subs ; x++ ) out += bncs_string( ".%1" ).arg( dec->sub[ x ] ); out += "="; out += dec->value; if( header ) OutputDebugString( bncs_string( "%1: %2" ).arg( header ).arg( out )); else OutputDebugString( out ); } } }; /** \class httpNotify \brief A class that passes on information about HTTP (file transfer) notifications This class tells you the end-state of an HTTP file transfer \par Example \code // for a remote file from http://myhost.com/file.png to a local file /panels/images/myfile.png void mypanel::buttonCallback( buttonNotify *b ) { bncs_string s1 = b->url(); // s1 contains "http://myhost.com/file.png" bncs_string s2 = b->data(); // s2 contains "/panels/images/myfile.png" bool b1 = b->string(); // b1 is false - this was a file download bool b2 = b->ok(); // b2 is true - the file transferred ok } \endcode */ class httpNotify { private: CB_HTTP * h; public: #ifndef DOXYGEN_SHOULD_SKIP_THIS /** Used internally */ httpNotify( CB_HTTP * in ) { h = in; }; #endif // DOXYGEN_SHOULD_SKIP_THIS /** url Return the URL of the item transferred */ bncs_string url( void ) { return h->url; }; /** file Return the local file name or actual data of the item transferred */ bncs_string data( void ) { return h->data; }; /** string Return the flag which says if this was a file transfer (false) or a string transfer (true) */ bool string( void ) { return h->string; }; /** ok Return whether this HTTP transfer was ok (true) or failed (false ) */ bool ok( void ) { return h->ok; }; /** err Return the error message string (null if nothing interesting happened) */ bncs_string err( void ) { return h->err; }; }; class bncs_script_helper : public bncs_client_callback { public: bool getDevSlot(const bncs_string & instance, const bncs_string & param, int* dev, int* slot, char* type); bool getDevSlot( const bncs_string & instance, const bncs_string & param, bncs_string & altId, int *dev, int *slot, char *type); bool getDev(bncs_string instance, int* dev, int* offset = 0); void audioStopAll(); void audioDestroy(const bncs_string &name); void audioStop(const bncs_string &name); void audioPlay(const bncs_string & name, int repeat); void audioPlay(const bncs_string & name, const bncs_string & file, int repeat); bncs_script_helper( bncs_client_callback * parent, const char * path ); virtual ~bncs_script_helper(); void* callback( const void *, int ); // panel commands bool panelShow( const bncs_string & pnl, const bncs_string & path, const bncs_string & target="" ); bool panelInit( const bncs_string & pnl, const bncs_string & path, const bncs_string & target="" ); bool panelTarget( const bncs_string & pnl, const bncs_string & target); bool panelPopup( const bncs_string & pnl, const bncs_string & path, int width = 0, int height = 0 ); bool panelRemove( const bncs_string & pnl ); bool panelDestroy( const bncs_string & pnl ); // text commands void textPut( const bncs_string & what, const bncs_string & pnl, const bncs_string & id ); void textPut( const bncs_string & param, const bncs_string & value, const bncs_string & pnl, const bncs_string & id ); void textGet( const bncs_string & what, const bncs_string & pnl, const bncs_string & id, bncs_string & ret); // router commands void routerName( int dev, int db, int index, bncs_string & ret ); int routerIndex( int dev, int db, const bncs_string & name ); void routerCrosspoint( int dev, int source, int dest, const bncs_string & mask="", bool now = false ); void routerRegister( int dev, int start, int end, bool add=false ); void routerUnregister( int dev ); void routerPoll( int dev, int start, int end ); void routerQuery( int dev, int start, int end ); void routerModify( int dev, int database, int index, const bncs_string& name, bool reload ); // info commands void infoUnregister( int dev ); void infoPoll( int dev, int start, int end ); void infoWrite( int dev, const bncs_string & what, int index, bool now = false ); void infoWrite( const bncs_string & format, ... ); void infoQuery( int dev, int start, int end ); void infoRegister( int dev, int start, int end, bool add=false ); // gpi commands void gpiRegister( int dev, int start, int end, bool add=false ); void gpiSwitch( int dev, bool state, int index, bool now = false ); void gpiPoll( int dev, int start, int end ); void gpiQuery( int dev, int start, int end ); void gpiUnregister( int dev ); // other commands void timerStart( int timer, int duration ); void timerStop( int timer ); void captionEnable( bool captionOn, const bncs_string & title, const bncs_string & args = "" ); void setGeometry( int x, int y, int w, int h ); void setSize( int w, int h ); void setSize( const bncs_string & pnl ); // control commands void controlEnable( const bncs_string & panel, const bncs_string & id ); void controlDisable( const bncs_string & panel, const bncs_string & id ); void controlShow( const bncs_string & panel, const bncs_string & id ); void controlHide( const bncs_string & panel, const bncs_string & id ); void controlMove( const bncs_string & panel, const bncs_string & id, int x, int y ); void controlPosition( const bncs_string & panel, const bncs_string & id, bncs_string & x, bncs_string & y); bncs_string controlCreate( const bncs_string & panel, const bncs_string & id, const bncs_string & buttonClass, int x, int y, int w, int h, const bncs_string & settings ); bool controlDestroy( const bncs_string & panel, const bncs_string & id ); // host commands void hostNotify( const bncs_string & message ); bncs_string id( void ); // callbacks /** Button notification This gets called whenever a button wants to notify us of something\n See the buttonNotify documentation for the values it returns */ #ifdef BNCS_CALLBACK_BY_REF virtual void buttonCallback( buttonNotify &b )=0; #else virtual void buttonCallback( buttonNotify *b )=0; #endif /** Revertive notification This gets called whenever network event occurs See the CB_REVERTIVE documentation for the values it returns */ #ifdef BNCS_CALLBACK_BY_REF virtual int revertiveCallback( revertiveNotify & r )=0; #else virtual int revertiveCallback( revertiveNotify * r )=0; #endif /** Parent notification This gets called whenever our parent wants to tell us something See the parentNotify documentation for the values it returns */ #ifdef BNCS_CALLBACK_BY_REF virtual bncs_string parentCallback( parentNotify &p )=0; #else virtual bncs_string parentCallback( parentNotify *p )=0; #endif /** HTTP notification This gets called whenever HTTP wants to tell us something See the parentNotify documentation for the values it returns */ #ifdef BNCS_CALLBACK_BY_REF virtual void httpCallback( httpNotify &p ){}; // this has an implementation so that existing scripts don't throw an error #else virtual void httpCallback( httpNotify *p ){}; #endif /** Timer notification This gets called whenever a timer event occurs See the timerStart() / timerStop() documentation for usage information */ virtual void timerCallback( int )=0; /** Timer notification This gets called whenever a database change event occurs See the CB_REVERTIVE documentation for the values it returns */ virtual void databaseCallback( revertiveNotify * r ){}; void debug( const bncs_string & str ); void debug( const bncs_string & format, const bncs_string & in1, const bncs_string & in2="", const bncs_string & in3="", const bncs_string & in4="", const bncs_string & in5="", const bncs_string & in6="", const bncs_string & in7="", const bncs_string & in8="", const bncs_string & in9="" ); int workstation( void ); void navigateAdjust( const bncs_string & str ); void navigateExecute( const bncs_string & str ); bool navigateCanExecute( const bncs_string & str ); bool navigateCanAdjust( const bncs_string & str ); bncs_stringlist getWorkstationSettings( void ); bncs_string getWorkstationSetting(const bncs_string & setting); bncs_string getObjectSetting(const bncs_string & object, const bncs_string & setting); int getRouterSize(int intDevice, int intSwitch); bncs_string getUser( void ); bncs_string getUserLevel( void ); int getUserLevelInt( void ); bncs_stringlist getIdList( const bncs_string & pnl, const bncs_string & startsWithFilter="" ); void enableActionAll(); void actionAll(const bncs_string & sValue); void httpGet( const bncs_string & url, const bncs_string & localFile ); void httpGetString( const bncs_string & url ); void httpPut( const bncs_string & url, const bncs_string & localFile ); void httpPutString( const bncs_string & url, const bncs_string & string ); private: bncs_client_callback * logic; bncs_string exePath; bool m_bEnableAck; }; #define EXPORT_BNCS_SCRIPT( a ) extern "C" \ {\ EXPORT_SCRIPT bncs_client_callback * load_bncs_client_script( bncs_client_callback * parent, const char * path ) {return new a( parent, path );};\ }\ #define DESCRIBE_BNCS_SCRIPT( a ) extern "C" \ {\ EXPORT_SCRIPT const char * describe_bncs_client_script( void ) {return a;};\ }\ #endif // BNCS_SCRIPT_HELPER_INCLUDED