PL.Net
These classes enable InterDynamics' Planimate® platform to be integrated in dotNET projects. Code is written in C# and VS2013 projects are provided.
planidll.hpp
1 #ifndef PLANIDLL_HPP
2 #define PLANIDLL_HPP
3 
4 // Version of the DLL API. You can retrieve the version of a DLL using
5 // PL_GetSstemInfo(PLSI_DLLVERSION);
6 
7 // v1: release
8 // v2: Jan 2013 thread support
9 // v3: jun 2013 new table functions
10 // v4: jan 2014 pause callback, s.ContinueRun access
11 // v5: aug 2014: thread setup now directly in PL
12 
13 #define PLANIDLL_VERSION 5
14 
15 // System attributes the DLL can [R]ead (some can be [W]ritten,
16 // some only persist/can be set while [E]ngine runs)
17 
18 enum ePLSysInfo
19  {
20  // for PL_GetSystemInfo()
21 
22  PLSI_CLOCK, // R : simulation seconds since start
23  PLSI_ADVANCETOTIME, // R/W : time to fast-advance to
24  PLSI_CURRENTPENDING, // R : events pending on the simulation FEC
25  PLSI_ENGINESTATE, // R : ePLMode
26  PLSI_CURRENTFILEVERSION, // R : version of MDL we would save
27  PLSI_OLDESTFILEVERSION, // R : oldest version of MDL we can load
28  PLSI_LOADEDFILEVERSION, // R : current version of MDL we hve loaded
29  PLSI_DLLVERSION, // R : version of dllapi PL compiled with
30  PLSI_PAUSEAFTERADVANCE // R/W/E: controls if PL pauses after advance-to-time
31  };
32 
33 // Major mode for Planimate engine
34 
35 enum ePLMode
36  {
37  MD_OBJECT = 0, // editing objects or user mode with engine stopped
38  MD_FLOWEDIT, // flow or interaction edit mode (flow editor has submode)
39  MD_PAINT, // editing paint object layer
40  MD_SIMULATE, // engine started and model is running
41  MD_PAUSED // engine started and model is paused
42  };
43 
44 // Data Object types
45 
46 enum eDOTypes
47  {
48  PLDO_LABELS,
49  PLDO_SUBLABELS,
50  PLDO_ATTRIBUTE,
51  PLDO_TABLE
52  };
53 
54 //
55 // Error results. Basically
56 // 0 is good, not 0 is bad except searches where
57 // >=0 is good, -1 means not found
58 // NOTE:In general objects in collections, rows and columns are indexed from 0
59 //
60 
61 enum ePLRESULT
62  {
63  PLR_NOTFOUND = -1, // search fail
64  PLR_OK = 0,
65  PLR_LOADFAIL, // loading model failed
66  PLR_INVALID, // bad paramter, mode
67  PLR_BADINDEX, // bad row/col index
68  PLR_BADFORMAT, // badly formatted number string
69  PLR_NOSPACE // no space in buffer
70  };
71 
72 // This is a handle to a data object. The DLL user does not have access to
73 // its internals but it will be passed back to PL for data operations.
74 // It can represent a label list, sub label list, table or attribute.
75 
76 class PLDataObject;
77 
78 // This is a handle to a broadcast
79 
80 class PLBroadcast;
81 
82 // Base class for all label lists
83 
84 class PLLabelList;
85 
86 // Result code
87 
88 typedef int PLRESULT;
89 
90 // type for the exported functions
91 
92 #ifndef __GNUC__
93 #define PLDLLFN _declspec(dllexport)
94 #else
95 #define PLDLLFN
96 #endif
97 
98 // Thread proc status (PL_InitThread)
99 // This is different to the PL Run Engine State
100 // NOTE:The PL Engine is only valid when thread is in PLT_Running state
101 
102 enum ePLThreadState
103  {
104  PLT_None,
105  PLT_LoadError,
106  PLT_BindError,
107  PLT_ThreadPending,
108  PLT_ThreadStart,
109  PLT_InitDone,
110  PLT_Running,
111  PLT_Terminating,
112  PLT_ThreadEnd
113  };
114 
115 // Function enum for PL_GetProc() which you can use to retrieve function
116 // pointers instead of LoadLibrary
117 
118 enum ePLProcs
119  {
120  ePL_SetInstance,
121  ePL_Init,
122  ePL_Term,
123  ePL_AppVersion,
124  ePL_LoadModel,
125  ePL_Run,
126  ePL_GetSystemInfo,
127  ePL_SetSystemInfo,
128  ePL_DataObjectCount,
129  ePL_GetDataObject,
130  ePL_FindDataObjectName,
131  ePL_FindDataObject,
132  ePL_DataObjectType,
133  ePL_DataObjectName,
134  ePL_ListFromDataObject,
135  ePL_GetNamedLabelList,
136  ePL_LabelCount,
137  ePL_GetLabelName,
138  ePL_GetLabelIndex,
139  ePL_FindLabelName,
140  ePL_LookUpLabel,
141  ePL_LookUpLValue,
142  ePL_LookUpDValue,
143  ePL_FindLabelAutoAdd,
144  ePL_Rows,
145  ePL_Columns,
146  ePL_ColumnName,
147  ePL_GetColumnFormat,
148  ePL_SetColumnFormat,
149  ePL_GetColumnLabels,
150  ePL_FindColumn,
151  ePL_TableResize,
152  ePL_GetCell,
153  ePL_SetCell,
154  ePL_GetCellText,
155  ePL_GetColumn,
156  ePL_SetColumn,
157  ePL_InsertRow,
158  ePL_DeleteRow,
159  ePL_InsertColumn,
160  ePL_DeleteColumn,
161  ePL_BroadcastCount,
162  ePL_GetBroadcast,
163  ePL_GetBroadcastName,
164  ePL_SendBroadcast,
165  ePL_SendBroadcastTuple,
166  ePL_RegisterBroadcastCallback,
167  ePL_FormatModeCount,
168  ePL_FormatName,
169  ePL_StringToValue,
170  ePL_ValueToString,
171  ePL_GetWindow,
172  ePL_Process,
173  ePL_SuspendThread,
174  ePL_ResumeThread,
175  ePL_RegisterPauseCallback,
176  ePL_SetCellText,
177  ePL_GetOwnerWindow,
178  ePL_WaitModelStarted,
179 
180  ePL_PROCCOUNT
181  };
182 
184 //
185 // The following typedefs define the functions exported by a PL DLL. The actual
186 // functions dont include the leading lowercase 't' in the function names.
187 //
188 // Typedefs are used rather than actually naming the functions as they
189 // will be more useful in creating function pointers, used with
190 // LoadLibary()/GetProcAddress().
191 //
192 // You can use these in conjunction with the enums above and PL_GetProc()
193 // A useful macro for C users is:
194 // #define GETPLPROC(pl,procname) ((t##procname *)((pl->PL_GetProc)(e##procname)))
195 //
196 //
197 
198 // version of PL as a string eg: "5.36". Call any time
199 typedef PLDLLFN const char * tPL_AppVersion();
200 
201 // Threaded mode initialise PL (new August 2014)
202 // - cmdline can be a PL commandline option or just "". "/debugfile" writes log.
203 // - inplace_window should be the handle of a window into which PL will
204 // place a child window for its display. If NULL PL will create a new
205 // window
206 //
207 // Call to initialise. PL is started in its own thread. This returns
208 // immediately so you can start other instances. You must call
209 // PL_WaitThreadRunning() after PL_InitThread() before doing anything else
210 //
211 
212 typedef PLDLLFN int tPL_InitThread(HMODULE,
213  const char * the_args,
214  HWND the_owner_hwnd);
215 
216 // PL_WaitThreadRunning() must be called after PL_InitThread()
217 
218 typedef PLDLLFN int tPL_WaitThreadRunning();
219 
220 // PL_TermThread() must be used to terminate when PL_InitThread() is used
221 
222 typedef PLDLLFN void tPL_TermThread();
223 
224 // PL_GetPRoc() can be used to retrieve proc pointers. It is ONLY valid
225 // after PL_InitThread() has been called
226 
227 typedef PLDLLFN void * tPL_GetProc(int);
228 
230 //
231 // Direct initialisation without using threads or managing
232 // threads externally. This is now obsolete but still works for this release
233 //
234 // invoke PL_SetInstance before PL_Init() to set the instance. Not necessary if
235 // using PL_InitThread()
236 
237 typedef PLDLLFN void tPL_SetInstance(HINSTANCE h);
238 
239 enum ePLINITOptions
240  {
241  PLINIT_NONE = 0,
242  PLINIT_OWNTHREAD = 1
243  };
244 
245 typedef PLDLLFN PLRESULT tPL_Init(const char * cmdline,
246  HWND inplace_window,
247  int opts);
248 
249 // close down model and cleanup/terminate.
250 // Only call after PL_Init() has returned.
251 // Must be called before parent window destroyed
252 
253 typedef PLDLLFN void tPL_Term();
254 
255 // Windows event dispatch loop. Useful when PL running in own thread.
256 // Returns when WM_QUIT shuts down the message loop.
257 // NOTE:Models in a threaded DLL should not be configured to self-close
258 
259 typedef PLDLLFN PLRESULT tPL_Process();
260 
262 //
263 // General purpose calls
264 //
265 
266 // PL_WaitModelStarted()
267 // Useful after a PL_Run()
268 // returns when the Planimate thread is in a run or paused state
269 // will process calling thread events while waiting
270 // timeout in milliseconds
271 
272 typedef PLDLLFN PLRESULT tPL_WaitModelStarted(int timeout);
273 
274 // PL_Run() engine control
275 // - only call after PL_Init() has completed
276 // - OK to call from main thread (it posts a message to PL's thread)
277 // - do not use within PL_SuspendThread/PL_ResumeThread calls
278 
279 enum ePLRunCMD
280  {
281  PLRUNCMD_Close = -1, // end simulation and close down (PL_Run() returns)
282  PLRUNCMD_Stop = 0, // stop the run engine
283  PLRUNCMD_Run = 1, // start engine/run (or continu) the model. Pauses if no events
284  PLRUNCMD_Pause = 2, // pause the model
285  PLRUNCMD_StartPause = 3 // start engine and pause (no-op if already running)
286  };
287 
288 typedef PLDLLFN PLRESULT tPL_Run(int runcmd);
289 
290 // retrieve window handle to PL main window. This might be useful sometime
291 
292 typedef PLDLLFN HWND tPL_GetWindow();
293 
294 // retrieve parent window to PL main window (what was passed)
295 
296 typedef PLDLLFN HWND tPL_GetOwnerWindow();
297 
299 //
300 // suepend/resume PL thread when PL is running in its own thread
301 // A suspended PL thread goes into a windows message dispatch loop
302 // keeping it away from access to PL structures
303 //
304 // PL_SuspendThread blocks (pumping calling thread messages) until PL is
305 // in a suspended state.
306 //
307 // NOTE: It is important your UI does not feed new commands while
308 // this wait occurs. The calls here are not re-entrant.
309 //
310 
311 typedef PLDLLFN void tPL_SuspendThread();
312 typedef PLDLLFN void tPL_ResumeThread();
313 
314 
316 //
317 // Thread Notes:
318 //
319 // When running PL in its own thread, the following must be enclosed
320 // in PL_SuspendThread() / PL_ResumeThread() or data corruption
321 // can be expected.
322 //
323 
324 // PL_LoadModel enables loading a model; will fail if:
325 // Direct mode:
326 // - PL is a compiled PBA
327 // - model run is ac5ive/paused
328 // Threaded mode:
329 // - Will terminate any running model
330 // - then loads the named model (or the PBA is reloaded if PL is a compiled PBA)
331 // filename must be non NULL
332 // loadfile, if non NULL sets s.LastLoadFilePath, useful for loading a dataset
333 
334 typedef PLDLLFN PLRESULT tPL_LoadModel(const char * modelname,const char * loadfile);
335 
336 // system info from ePLSysInfo
337 // Times are in seconds with 0 = the run start date
338 
339 typedef PLDLLFN double tPL_GetSystemInfo(int sysinfoid);
340 typedef PLDLLFN PLRESULT tPL_SetSystemInfo(int sysinfoid,double v);
341 
343 //
344 // Data Object interface
345 //
346 // Data Objects are the data placed in the _data_objects label list in the model.
347 // They can be tables, label lists, attributes and sub label lists.
348 //
349 
350 typedef PLDLLFN int tPL_DataObjectCount();
351 typedef PLDLLFN PLDataObject * tPL_GetDataObject(int w);
352 typedef PLDLLFN PLDataObject * tPL_FindDataObjectName(const char *);
353 typedef PLDLLFN PLDataObject * tPL_FindDataObject(long index);
354 typedef PLDLLFN int tPL_DataObjectType(PLDataObject*); // eDOTypes
355 typedef PLDLLFN const char * tPL_DataObjectName(PLDataObject*);
356 
358 //
359 // For label list data objects
360 //
361 
362 typedef PLDLLFN PLLabelList * tPL_ListFromDataObject(PLDataObject *);
363 typedef PLDLLFN PLLabelList * tPL_GetNamedLabelList(const char *);
364 
365 // for a label list:
366 
367 typedef PLDLLFN int tPL_LabelCount(PLLabelList *);
368 typedef PLDLLFN const char * tPL_GetLabelName(PLLabelList *,int w);
369 typedef PLDLLFN long tPL_GetLabelIndex(PLLabelList *,int w);
370 typedef PLDLLFN int tPL_FindLabelName(PLLabelList *,const char *);
371 typedef PLDLLFN long tPL_LookUpLabel(PLLabelList *,const char *);
372 typedef PLDLLFN const char * tPL_LookUpLValue(PLLabelList *,long v);
373 typedef PLDLLFN const char * tPL_LookUpDValue(PLLabelList *,double v);
374 typedef PLDLLFN int tPL_FindLabelAutoAdd(PLLabelList *,const char *);
375 
377 //
378 // For portal attributes
379 //
380 
381 typedef PLDLLFN int tPL_GetAttFormat(PLDataObject *);
382 typedef PLDLLFN PLLabelList* tPL_GetAttLabels(PLDataObject *);
383 typedef PLDLLFN double tPL_GetAttValue(PLDataObject *);
384 typedef PLDLLFN PLRESULT tPL_SetAttValue(PLDataObject *,double data);
385 typedef PLDLLFN const char * tPL_GetAttText(PLDataObject *);
386 typedef PLDLLFN PLRESULT tPL_SetAttText(PLDataObject *,const char *);
387 
389 //
390 // For Table data objects:
391 //
392 
393 typedef PLDLLFN int tPL_Rows(PLDataObject *);
394 typedef PLDLLFN int tPL_Columns(PLDataObject *);
395 typedef PLDLLFN const char * tPL_ColumnName(PLDataObject *,int column);
396 typedef PLDLLFN int tPL_GetColumnFormat(PLDataObject *,int column);
397 typedef PLDLLFN PLRESULT tPL_SetColumnFormat(PLDataObject *,int column,int format,PLLabelList *);
398 typedef PLDLLFN PLLabelList * tPL_GetColumnLabels(PLDataObject *,int column);
399 typedef PLDLLFN int tPL_FindColumn(PLDataObject *,const char * col_name);
400 
401 // Resize table - r/c can be -1 to leave existing as-is. Returns 0 on success
402 
403 typedef PLDLLFN PLRESULT tPL_TableResize(PLDataObject *,int r,int c);
404 
405 typedef PLDLLFN double tPL_GetCell(PLDataObject *,int row,int col);
406 typedef PLDLLFN PLRESULT tPL_SetCell(PLDataObject *,int row,int col,double data);
407 
408 // for free text access. Text returned only valid until the table is changed
409 
410 typedef PLDLLFN const char * tPL_GetCellText(PLDataObject *,int row,int col);
411 typedef PLDLLFN PLRESULT tPL_SetCellText(PLDataObject *,int row,int col,const char *);
412 
413 // entire column set
414 
415 typedef PLDLLFN PLRESULT tPL_GetColumn(PLDataObject *,int col,int rows,double * into);
416 typedef PLDLLFN PLRESULT tPL_SetColumn(PLDataObject *,int col,int rows,double * to);
417 
418 typedef PLDLLFN PLRESULT tPL_InsertRow(PLDataObject *,int at_row,int count);
419 typedef PLDLLFN PLRESULT tPL_DeleteRow(PLDataObject *,int at_row,int count);
420 typedef PLDLLFN PLRESULT tPL_InsertColumn(PLDataObject *,int at_row,int count);
421 typedef PLDLLFN PLRESULT tPL_DeleteColumn(PLDataObject *,int at_row,int count);
422 
423 
425 //
426 // Broadcasting
427 //
428 
429 typedef PLDLLFN int tPL_BroadcastCount();
430 typedef PLDLLFN PLBroadcast * tPL_GetBroadcast(int w);
431 typedef PLDLLFN PLBroadcast * tPL_GetBroadcastName(const char * name);
432 
433 // send broadcast to PL
434 //
435 // Thread Notes:
436 //
437 // When PL is running in its own thread broadcasts are always
438 // enqueued to the model FEC. This means they do not occur immediately
439 // when you call the API and will be processed when the thread lock is
440 // released and the run is resumed.
441 //
442 
443 typedef PLDLLFN PLRESULT tPL_SendBroadcast(PLBroadcast *);
444 typedef PLDLLFN PLRESULT tPL_SendBroadcastTuple(PLBroadcast *,
445  int params,
446  const char ** names,
447  double * values);
448 
449 // send broadcast as a background event - PL processes it silently without
450 // mode change and sideeffects are processed even if paused with events at
451 // the current time. Do not perform any UI with these, they execute
452 // in the caller thread.
453 
454 typedef PLDLLFN PLRESULT tPL_SendBroadcastBG(PLBroadcast *);
455 typedef PLDLLFN PLRESULT tPL_SendBroadcastTupleBG(PLBroadcast *,
456  int params,
457  const char ** names,
458  double * values);
459 
460 // broadcast callback
461 //
462 // Thread Notes:
463 //
464 // The callback will be called in the context of PL's thread.
465 // The PLBroadcast handle is unique per broadcast per thread.
466 // The userdata will be returned and is useful for passing a pointer
467 // to the class/instance.
468 //
469 // Data *must* be processed/copied before returning from this function.
470 // All pointers are invalid after the callback returns.
471 
472 typedef PLRESULT CALLBACK tPL_BroadcastCallback(PLBroadcast *,
473  int params,
474  const char ** names,
475  double * values,
476  void * userdata);
477 
478 // register a function for PL to call back
479 
480 typedef PLDLLFN PLRESULT tPL_RegisterBroadcastCallback(PLBroadcast *,
481  tPL_BroadcastCallback *,
482  void * userdata);
483 
485 //
486 // Pause callback enables a user provided function to be called
487 // every time Planimate becomes paused. This function is called in PL's
488 // thread context so do as little as possible and message to your main
489 // thread as required.
490 //
491 // Reasons the run engine becomes paused
492 
493 enum ePLPauseReason
494  {
495  SIMUL_UserPause = 0, // user pressed ESC, mouse button, may resume
496  SIMUL_EndTimeReached, // nominated end time reached, user may extend
497  SIMUL_NoMoreEvents, // FEC empty, user may trigger new activity
498  SIMUL_SimulateError, // error has occured and was reported, must End()
499  SIMUL_Finished, // model has set finished state (eg:Exit), must End()
500  SIMUL_AdvanceTimeReached, // advance to time reached and pause after advance set
501  SIMUL_RunMemoryError, // out of memory during run
502  SIMUL_Undefined
503  };
504 
505 typedef PLRESULT CALLBACK tPL_PauseCallback(double the_time,
506  int stop_reason, // ePLPauseReason
507  void * userdata);
508 
509 typedef PLDLLFN void tPL_RegisterPauseCallback(tPL_PauseCallback * fn,
510  void * userdata);
511 
513 //
514 // formatting and number parsing
515 // Also must be called within PL_SuspendThread / PL_ReleaseThread and
516 // they are not re-entrant
517 //
518 
519 typedef PLDLLFN int tPL_FormatModeCount();
520 typedef PLDLLFN const char * tPL_FormatName(int fmt);
521 typedef PLDLLFN PLRESULT tPL_StringToValue(const char * s,
522  double * v,
523  int format);
524 
525 typedef PLDLLFN PLRESULT tPL_ValueToString(double v,
526  int buffer_len,
527  char * buffer,
528  int format);
529 
530 
531 //
532 // PL uses this to convert doubles to integers. It provide rounding to the
533 // nearest integer for both +ve and -ve values
534 //
535 
536 inline long PL_NearestInt(double v)
537 {
538  // return closest int to v, handling C's -ve number round behaviour
539  return (long)(v + 0.5 - (v < 0.0));
540 }
541 
542 #endif