Merge branch 'master' into HeadlessJavaGUITests

This commit is contained in:
Marcus Rockwell 2024-03-13 09:46:35 -05:00
commit 129f1cec32
101 changed files with 15618 additions and 12018 deletions

View File

@ -97,13 +97,23 @@ jobs:
conf_pkg: |
yum -y install epel-release
yum -y update
yum -y install wget
os_deps: >-
libX11-devel
libXt-devel
swig3
install_gtest: |
yum install -y http://repo.okay.com.mx/centos/7/x86_64/release/okay-release-1-6.el7.noarch.rpm
yum install -y gtest gtest-devel gmock gmock-devel
cd /tmp
wget https://github.com/google/googletest/archive/release-1.8.0.tar.gz
tar xzvf release-1.8.0.tar.gz
cd /tmp/googletest-release-1.8.0/googletest
cmake .
make
make install
cd /tmp/googletest-release-1.8.0/googlemock
cmake .
make
make install
#-------- RHEL 8-based Only Dependencies ----------------
- cfg: { arch: rhel, arch_ver: 8 }
pkg_mgr: dnf

View File

@ -25,9 +25,18 @@ jobs:
run: |
# sudo installer -pkg /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.15.pkg -target /
brew install --cask xquartz
brew install swig udunits openmotif maven
brew install udunits openmotif maven
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-14.0.6/clang+llvm-14.0.6-x86_64-apple-darwin.tar.xz
tar -xvf clang+llvm-14.0.6-x86_64-apple-darwin.tar.xz
brew install autoconf automake libtool
wget https://github.com/swig/swig/archive/refs/tags/v4.1.1.tar.gz
tar -xvzf v4.1.1.tar.gz
cd swig-4.1.1
./autogen.sh
./configure
make
make install
cd ..
- name: Build Trick
run: |
export MAKEFLAGS=-j4

View File

@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.1)
# configuration to do before CMake searches for compilers
project(trick NONE)
set(TRICK_MAJOR 19)
set(TRICK_MINOR 7)
set(TRICK_MINOR 8)
set(TRICK_TINY 0)
# set TRICK_PRERELEASE TO EMPTY STRING "" ON RELEASE
set(TRICK_PRERELEASE "-beta")
@ -175,7 +175,7 @@ set( IO_SRC
${CMAKE_BINARY_DIR}/temp_src/io_src/io_JITEvent.cpp
${CMAKE_BINARY_DIR}/temp_src/io_src/io_JITInputFile.cpp
${CMAKE_BINARY_DIR}/temp_src/io_src/io_JSONVariableServer.cpp
${CMAKE_BINARY_DIR}/temp_src/io_src/io_JSONVariableServerSessionThread.cpp
${CMAKE_BINARY_DIR}/temp_src/io_src/io_JSONVariableServerThread.cpp
${CMAKE_BINARY_DIR}/temp_src/io_src/io_JobData.cpp
${CMAKE_BINARY_DIR}/temp_src/io_src/io_MM4_Integrator.cpp
${CMAKE_BINARY_DIR}/temp_src/io_src/io_MSConnect.cpp
@ -231,7 +231,7 @@ set( IO_SRC
${CMAKE_BINARY_DIR}/temp_src/io_src/io_VariableServer.cpp
${CMAKE_BINARY_DIR}/temp_src/io_src/io_VariableServerListenThread.cpp
${CMAKE_BINARY_DIR}/temp_src/io_src/io_VariableServerReference.cpp
${CMAKE_BINARY_DIR}/temp_src/io_src/io_VariableServerSessionThread.cpp
${CMAKE_BINARY_DIR}/temp_src/io_src/io_VariableServerThread.cpp
${CMAKE_BINARY_DIR}/temp_src/io_src/io_Zeroconf.cpp
${CMAKE_BINARY_DIR}/temp_src/io_src/io_attributes.cpp
${CMAKE_BINARY_DIR}/temp_src/io_src/io_dllist.cpp

View File

@ -14,7 +14,7 @@
<img src="https://github.com/nasa/trick/workflows/macOS/badge.svg?branch=master" alt="macOS" height=30px>
</a>
<a href="https://github.com/nasa/trick/actions?query=workflow%3A32-bit">
<img src="https://github.com/nasa/trick/workflows/32-bit/badge.svg?branch=master" alt="macOS" height=30px>
<img src="https://github.com/nasa/trick/workflows/32-bit/badge.svg?branch=master" alt="32-bit" height=30px>
</a>
<a href="https://coveralls.io/github/nasa/trick?branch=master">
<img src="https://coveralls.io/repos/github/nasa/trick/badge.svg?branch=master" alt="Coverage Status" height=30px>

View File

@ -86,8 +86,32 @@ A colon separated list of directories to skip when processing files.
It is possible to instruct all CP functions to skip entire directories using the environment variable TRICK_EXCLUDE. Set this variable to a colon separated list of directories which you wish CP to bypass. All header files found in TRICK_EXCLUDE will not be processed. All source code files found in TRICK_EXCLUDE will not be compiled or linked into the simulation.
This environment variable does the job of both TRICK_ICG_EXCLUDE and TRICK_SWIG_EXCLUDE simulataneously.
This feature is useful to bring in packages as a library.
### TRICK_ICG_EXCLUDE
A colon separated list of directories to skip when processing header files.
It is possible to instruct ICG to skip entire directories using the environment variable TRICK_ICG_EXCLUDE. Set this variable to a colon separated list of directories which you wish ICG to bypass. This is useful when there is code which you do not wish Trick to have any knowledge of (i.e. you dont need any of the parameters recorded or input processable).
This excludes files from ICG only, while still allowing SWIG to process them.
### TRICK_SWIG_EXCLUDE
A colon separated list of files and directories to skip when generating Python interface files.
It is possible to instruct SWIG to skip entire directories and files using the environment variable TRICK_SWIG_EXCLUDE. Set this variable to a colon separated list of files that should be bypassed.
This excludes files from SWIG only, still allowing ICG to process them.
Example ```S_overrides.mk```:
```
TRICK_SWIG_EXCLUDE += :models/SwigExclude.hh
TRICK_SWIG_EXCLUDE += :models/Swig_Exclude_Dir
```
### TRICK_FORCE_32BIT
To force Trick to compile in 32-bit on 64-bit systems, set the TRICK_FORCE_32BIT environment variable to 1. Setting this variable appends "-m32" automatically to TRICK_CFLAGS and TRICK_CXXFLAGS.
@ -95,12 +119,6 @@ To force Trick to compile in 32-bit on 64-bit systems, set the TRICK_FORCE_32BIT
Trick determines a system specific suffix to append to object code directory names. By default this is determined automatically by Trick. The user may override this by setting the TRICK_HOST_CPU environment variable.
### TRICK_ICG_EXCLUDE
A colon separated list of directories to skip when processing header files.
It is possible to instruct ICG to skip entire directories using the environment variable TRICK_ICG_EXCLUDE. Set this variable to a colon separated list of directories which you wish ICG to bypass. This is useful when there is code which you do not wish Trick to have any knowledge of (i.e. you dont need any of the parameters recorded or input processable).
### TRICK_LDFLAGS
TRICK_LDFLAGS include linker flags. TRICK_LDFLAGS is used when linking the simulation executable. It is rare to set this variable.

View File

@ -1,7 +1,27 @@
## HOWTO Setup a Python Virtual Environment
# HOWTO Setup a Python Virtual Environment
### Creating a Virtual Environment
- [Using the Built-in venu Module in Python3](#using-the-built-in-venv-module-in-python-3)
* [Creating a Virtual Environment](#creating-a-virtual-environment)
* [Activating the Virtual Environment](#activating-the-virtual-environment)
* [Installing Python Modules Into Your Virtual Environment](#installing-python-modules-into-your-virtual-environment)
* [Deactivating the venv Shell](#deactivating-the-venv-shell)
- [Using Conda](#using-conda)
* [Creating a Conda Environment with Commands](#creating-a-conda-environment-with-commands)
* [Creating a Conda Environment From a YAML File](#creating-a-conda-environment-from-a-yaml-file)
* [Activating the Conda Environment](#activating-the-conda-environment)
* [Installing Packages Into a Conda Environment](#installing-packages-into-a-conda-environment)
* [Deactivating an Active Conda Environment](#deactivating-an-active-conda-environment)
* [Removing a Conda Environment](#removing-a-conda-environment)
- [References](#references)
<!-- toc -->
## [Using the Built-in venv Module in Python 3](#using-the-built-in-venv-module-in-python-3)
### [Creating a Virtual Environment](#creating-a-virtual-environment)
The following command creates a virtual Python environment:
@ -19,7 +39,7 @@ in your home directory.
```% python3 -m venv ~/myVenv```
### Activating the Virtual Environment
### [Activating the Virtual Environment](#activating-the-virtual-environment)
To activate the virtual environment, execute the following:
@ -29,7 +49,7 @@ To activate the virtual environment, execute the following:
Note that the name of virtual environment is added to the command prompt.
### Installing Python Modules Into Your Virtual Environment
### [Installing Python Modules Into Your Virtual Environment](#installing-python-modules-into-your-virtual-environment)
Use the following command to install Python modules into the virtual environment:
@ -47,7 +67,7 @@ This Python module would be installed as follows:
Every time ```myVenv``` is activated, the PyYAML module will be available.
### Deactivating the venv Shell
### [Deactivating the venv Shell](#deactivating-the-venv-shell)
To deactivate the venv shell, execute the following:
```(myVenv) % deactivate```
@ -56,3 +76,110 @@ To deactivate the venv shell, execute the following:
The above should get you going. If you need more details, the following tutorial is pretty good.
[RealPython Tutorial](https://realpython.com/python-virtual-environments-a-primer/).
## [Using Conda](#using-conda)
Conda is a powerful package manager and environment manager that you use with command line commands at the Anaconda Prompt for Windows, or in a terminal window for macOS or Linux.
You can obtain conda by installing [Miniconda](https://docs.conda.io/projects/miniconda/en/latest/) or [Anaconda](https://docs.anaconda.com/free/anacondaorg/).
Miniconda a small bootstrap version of Anaconda that includes only conda, Python, the packages they both depend on, and a small number of other useful packages (like pip, zlib, and a few others).
Anaconda is a downloadable, free, open-source, high-performance, and optimized Python and R distribution. It includes conda, conda-build, Python, and 250+ automatically installed, open-source scientific packages and their dependencies that have been tested to work well together, including SciPy, NumPy, and many others.
### [Creating a Conda Environment with Commands](#creating-a-conda-environment-with-commands)
#### Create a conda virtial environment with Python by running one of following conda commands from a terminal:
```
# A specific version of Python
% conda create --name trick python=3.9.18
or
% conda create -n trick python=3.9.18
# The latest version of Python 3.9
% conda create -n trick python=3.9
# The lastest version of Python
% conda create -n trick python
# The latest version of Python 3.9 and packages
% conda create -n trick python=3.9 pyyaml scipy
```
### [Creating a Conda Environment From a YAML File](#creating-a-conda-environment-from-a-yaml-file)
#### Create the file ```myenv.yml``` with following contents:
```
name: trick
channels:
- conda-forge
- defaults
dependencies:
- python = 3.9
- pyyaml
```
In this example, the environment is named ```trick``` and includes two packages: python and pyyaml.
#### Run conda command to create the new environment:
Once you have your YAML file ready, you can create your conda environment using the following command in your terminal:
```% conda env create -f myenv.yml```
### [Activating the Conda Environment](#activating-the-conda-environment)
After creating the environment, you can activate it using the following command:
```% conda activate trick```
### [Installing Packages Into a Conda Environment](#installing-packages-into-a-conda-environment)
If you're in your conda environment, you can install package(s) using the following command:
``` (trick) % conda install numpy scipy```
If you're NOT in your conda environment, you can install package(s) into a specified environment using the following command:
``` % conda install -n trick numpy scipy```
### [Deactivating an Active Conda Environment](#deactivating-an-active-conda-environment)
If you're in your conda environment, you can deactivate it using the following command:
```(trick) % conda deactivate```
### [Removing a Conda Environment](#removing-a-conda-environment)
You can remove a conda environment from your terminal using the following command:
``` % conda remove -n trick --all```
or
``` % conda env remove -n trick```
To verify that the environment was removed, run following from your terminal:
``` % conda info --envs```
The removed environment should not be shown.
# [References](#references)
* [RealPython Tutorial - Python Virtual Environment: A Primer](https://realpython.com/python-virtual-environments-a-primer/)
* [Conda Document - Managing environments](https://conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html)
* [Creating an environment in Anaconda through a yml file](https://sachinjose31.medium.com/creating-an-environment-in-anaconda-through-a-yml-file-7e5deeb7676d)

View File

@ -4,6 +4,7 @@
PURPOSE: ( Event Class )
*/
#include <string>
#include <iostream>
#include "trick/mm_macros.hh"
#include "trick/exec_proto.h"
@ -203,12 +204,16 @@ class Event {
#ifndef SWIG
struct CompareEventPtrs : public std::binary_function<Trick::Event *, Trick::Event *, bool> {
bool operator()(const Trick::Event * lhs, const Trick::Event * rhs) const {
return lhs->get_next_tics() < rhs->get_next_tics();
}
};
// No need to inherit from binary_function for c++11 or later
#if __cplusplus >= 201103L
struct CompareEventPtrs {
#else
struct CompareEventPtrs : public std::binary_function<Trick::Event *, Trick::Event *, bool> {
#endif
bool operator()(const Trick::Event * lhs, const Trick::Event * rhs) const {
return lhs->get_next_tics() < rhs->get_next_tics();
}
};
#endif
}

View File

@ -111,11 +111,23 @@ namespace Trick {
/** Next software frame time in integer tics.\n */
long long next_frame_check_tics ; /**< trick_units(--) */
/** Usage time at executive initialization.\n */
double cpu_init; /**< trick_io(**) trick_units(s) */
/** Usage time at executive initialization in user mode.\n */
double user_cpu_init; /**< trick_io(**) trick_units(s) */
/** CPU usage time at cyclic sim process startup.\n */
double cpu_start; /**< trick_io(**) trick_units(s) */
/** Usage time at executive initialization in kernal mode.\n */
double kernal_cpu_init; /**< trick_io(**) trick_units(s) */
/** CPU usage time at cyclic sim process startup in user mode.\n */
double user_cpu_start; /**< trick_io(**) trick_units(s) */
/** CPU usage time at cyclic sim process startup in kernal mode.\n */
double kernal_cpu_start; /**< trick_io(**) trick_units(s) */
/** Voluntary context switche usage at executive initialization.\n */
long v_context_switch_init; /**< trick_units(--) */
/** Involuntary context switche usage at executive initialization.\n */
long iv_context_switch_init; /**< trick_units(--) */
/** Simulation control mode.\n */
SIM_MODE mode; /**< trick_io(*o) trick_units(--) */

View File

@ -65,9 +65,12 @@ namespace Trick {
/** Thread start time */
long long start_time ;
/** Thread total frame scheduled time */
/** Thread total frame scheduled time in tics*/
long long frame_sched_time ;
/** Thread total frame scheduled time in seconds*/
double frame_time ;
} ;
} ;

View File

@ -35,6 +35,7 @@ class IntegLoopSimObject : public Trick::SimObject {
integ_sched.add_sim_object( *next_sobj );
next_sobj = va_arg(ap, Trick::SimObject*);
};
va_end(ap);
add_jobs(in_cycle, child) ;
}

View File

@ -88,9 +88,12 @@ namespace Trick {
/** Clock time when job stopped in frame */
long long rt_stop_time ; /**< trick_io(**) */
/** Cumulative time used for job in frame (stop - start) */
/** Cumulative time in tics used for job in frame (stop - start) */
long long frame_time ; /**< trick_io(**) */
/** Cumulative time in seconds used for job in frame (rt_stop_time - rt_start_time) / time_tic_value */
double frame_time_seconds; /**< trick_io(s) */
/** Sim_object_id.id (for job identification in timeline logging) */
double frame_id; /**< trick_io(**) */

View File

@ -67,9 +67,15 @@ namespace Trick {
/** How much time did the current frame take in tics.\n */
long long frame_sched_time ; /**< trick_units(--) */
/** How much time did the current frame take in seconds for frame logging.\n */
double frame_time ; /**< trick_units(s) */
/** The magnitude of the current overrun in tics.\n */
long long frame_overrun_time ; /**< trick_units(--) */
/** The magnitude of the current overrun in seconds for frame logging.\n */
double frame_overrun ; /**< trick_units(s) */
/** This is the start of the frame in wall clock time.\n */
long long last_clock_time ; /**< trick_units(--) */
@ -104,6 +110,9 @@ namespace Trick {
/** The clock time when the sim ended. Used for total actual time calculation.\n */
long long sim_end_time ; /**< trick_units(--) */
/** The actual simulation time/wall clock time ratio\n */
double actual_run_ratio ; /**< trick_units(--) */
/**
@brief This is the constructor of the RealtimeSync class. It starts the RealtimeSync as
disabled and sets the maximum overrun parameters to basically infinity.

View File

@ -7,6 +7,14 @@
#include "trick/attributes.h"
#include "trick/parameter_types.h"
/**
* enum TRICK_STCL - indicates whether or not the MemoryManager allocated the object.
* -------------------------------------------------------------------------------------------
* TRICK_LOCAL - The memory manager allocated the object, via a form of declare_var..().
* TRICK_EXTERN - The memory manager did not allocate the object, but was given a pointer to
* an object via a form of declare_extern_var..().
* -------------------------------------------------------------------------------------------
*/
typedef enum {
TRICK_LOCAL = 0,
TRICK_EXTERN = 1,

View File

@ -21,6 +21,7 @@ typedef struct _LQUEUE
LQUEUE* LQ_Create(void); /* create and initialize a LQUEUE */
int LQ_Delete(LQUEUE* lqueue); /* free an lqueue object created by LQ_Create.*/
void LQ_Init(LQUEUE*); /* initialize a LQUEUE */

View File

@ -65,8 +65,10 @@ class MonteCarloVariable
const std::string & get_command() const {return command;}
const std::string & get_variable_name() const {return variable_name;}
const std::string & get_assignment() const {return assignment;}
MonteCarloVariableType get_type() const {return type;}
virtual MonteCarloVariableType get_type() const {return type;}
virtual std::string get_type_str() const;
virtual unsigned int get_seed() const {return 0;}
virtual std::string summarize_variable() const;
protected:
void insert_units();

View File

@ -68,6 +68,8 @@ class MonteCarloVariableFile : public MonteCarloVariable
virtual ~MonteCarloVariableFile(){};
void initialize_file();
void generate_assignment();
virtual std::string summarize_variable() const;
void register_dependent( MonteCarloVariableFile *);
virtual void shutdown() {file.close();}

View File

@ -40,7 +40,6 @@ class MonteCarloVariableRandom : public MonteCarloVariable
virtual ~MonteCarloVariableRandom(){};
unsigned int get_seed() const {return seed_m;} // override but SWIG cannot process the
// override keyword
private: // and undefined:
MonteCarloVariableRandom( const MonteCarloVariableRandom & );
MonteCarloVariableRandom& operator = (const MonteCarloVariableRandom&);

View File

@ -44,6 +44,7 @@ class MonteCarloVariableRandomNormal : public MonteCarloVariableRandom
virtual ~MonteCarloVariableRandomNormal(){};
virtual void generate_assignment();
virtual std::string summarize_variable() const;
void truncate(double limit, TruncationType type = StandardDeviation);
void truncate(double min, double max, TruncationType type = StandardDeviation);
void truncate_low(double limit, TruncationType type = StandardDeviation);

View File

@ -43,6 +43,7 @@ class MonteCarloVariableRandomStringSet : public MonteCarloVariableRandomUniform
virtual ~MonteCarloVariableRandomStringSet(){};
virtual void generate_assignment();
virtual std::string summarize_variable() const;
void add_string(std::string);
private: // and undefined:
MonteCarloVariableRandomStringSet(const MonteCarloVariableRandomStringSet&);

View File

@ -35,6 +35,7 @@ class MonteCarloVariableRandomUniform : public MonteCarloVariableRandom
double upper_bound = 1.0);
virtual ~MonteCarloVariableRandomUniform(){};
virtual void generate_assignment();
virtual std::string summarize_variable() const;
private: // and undefined:
MonteCarloVariableRandomUniform( const MonteCarloVariableRandomUniform & );
MonteCarloVariableRandomUniform& operator = (
@ -59,6 +60,7 @@ class MonteCarloVariableRandomUniformInt : public MonteCarloVariableRandom
double upper_bound = 1);
virtual ~MonteCarloVariableRandomUniformInt(){};
virtual void generate_assignment();
virtual std::string summarize_variable() const;
private: // and undefined:
MonteCarloVariableRandomUniformInt(const MonteCarloVariableRandomUniformInt&);
MonteCarloVariableRandomUniformInt& operator = (

View File

@ -64,9 +64,15 @@ template<typename T > static int typemap_in_scalar( T & output , PyObject *input
output = (T)PyFloat_AsDouble(input) ;
} else if ( PyInt_Check(input) ) {
output = (T)PyInt_AsLong(input) ;
// PyUnicode_GET_SIZE: deprecated since Python 3.3 and removed in Python 3.12
// PyUnicode_GET_LENGTH: new in Python 3.3
#if PY_VERSION_HEX >= 0x03000000
} else if ( PyUnicode_Check(input) ) {
#if defined(PyUnicode_GET_LENGTH)
if ( PyUnicode_GET_LENGTH(input) == 1 ) {
#else
if ( PyUnicode_GET_SIZE(input) == 1 ) {
#endif
PyObject * temp = PyUnicode_AsEncodedString(input, "utf-8", "Error ~");
char * temp_str = PyBytes_AS_STRING(temp) ;
output = (T)temp_str[0] ;
@ -142,7 +148,11 @@ template<typename T > static T * typemap_in_1d( PyObject *input , unsigned int o
}
#if PY_VERSION_HEX >= 0x03000000
} else if ( PyUnicode_Check(input) ) {
#if defined(PyUnicode_GET_LENGTH)
unsigned int size = PyUnicode_GET_LENGTH(input) ;
#else
unsigned int size = PyUnicode_GET_SIZE(input) ;
#endif
PyObject * temp = PyUnicode_AsEncodedString(input, "utf-8", "Error ~");
char * temp_str = PyBytes_AS_STRING(temp) ;
#else
@ -330,7 +340,11 @@ template<typename T, typename baseT > static void * typemap_in_2d( PyObject *inp
}
#if PY_VERSION_HEX >= 0x03000000
} else if ( PyUnicode_Check(o) ) {
#if defined(PyUnicode_GET_LENGTH)
unsigned int size = PyUnicode_GET_LENGTH(o) ;
#else
unsigned int size = PyUnicode_GET_SIZE(o) ;
#endif
PyObject * temp = PyUnicode_AsEncodedString(o, "utf-8", "Error ~");
char * temp_str = PyBytes_AS_STRING(temp) ;
#else

View File

@ -83,6 +83,10 @@ my $typedef_struct = qr/typedef\s+(?:struct|union)\s* # the words typedef s
my $namespace_def = qr/namespace\s* # keyword namespace
(?:\s+[_A-Za-z]\w*) # class name
/sx ;
my $enum_class_def = qr/enum\s+class\s* # keywords enum_class
(?:\s+[_A-Za-z]\w*)\s* # class name
(?:\{|:(?!\:)) # { or punctuator :
/sx ;
my $class_def = qr/(?:class|struct)\s* # keyword class or struct
(?:\s+[_A-Za-z]\w*)\s* # class name
(?:\{|:(?!\:)) # { or punctuator :
@ -394,13 +398,15 @@ sub process_contents($$$$) {
($typedef_const_struct)|
($template_def)|
($namespace_def)|
($enum_class_def)|
($class_def))//sx ) {
my ( $non_var ) = $1 ;
my ( $typedef_struct_string ) = $2 ;
my ( $typedef_const_struct_string ) = $3 ;
my ( $template_string ) = $4 ;
my ( $namespace_string ) = $5 ;
my ( $class_string ) = $6 ;
my ( $enum_class_string ) = $6 ;
my ( $class_string ) = $7 ;
## Handle the case of: non_var
if ( $non_var ne "" ) {
@ -435,6 +441,13 @@ sub process_contents($$$$) {
$class_names_ref ) ;
}
##
## Handle the case of: class_def ==> enum class <enum-name> ( '{' | ':' )
##
if ( $enum_class_string ne "" ) {
$$new_contents_ref .= $enum_class_string ;
}
##
## Handle the case of: class_def ==> ( class | struct ) <class-name> ( '{' | ':' )
##
if ( $class_string ne "" ) {
@ -669,6 +682,7 @@ sub process_class($$$$$) {
push @$class_names_ref , "$curr_namespace$class_name" ;
# write the class contents and semicolon to ensure any template declarations below are after the semicolon.
$$new_contents_ref .= "\n#if SWIG_VERSION > 0x040000\n\%pythoncode \%{\n __setattr__ = _swig_setattr_nondynamic_instance_variable(object.__setattr__)\n\%}\n#endif\n" ;
$$new_contents_ref .= $extracted . ";\n" ;
# write out the templated variable declaration lines found in this class.
$$new_contents_ref .= $template_typedefs ;

View File

@ -1 +1 @@
current_version = "19.7.0-beta"
current_version = "19.8.0-beta"

View File

@ -1284,8 +1284,8 @@ class TrickWorkflow(WorkflowCommon):
self.status = Job.Status.FAILED
if self.missing:
return self.status
if (hashlib.md5(open(self.test_data,'rb').read()).hexdigest() !=
hashlib.md5(open(self.baseline_data,'rb').read()).hexdigest()):
if (hashlib.md5(open(self.test_data,'rb').read(), usedforsecurity=False).hexdigest() !=
hashlib.md5(open(self.baseline_data,'rb').read(), usedforsecurity=False).hexdigest()):
self.status = Job.Status.FAILED
else:
self.status = Job.Status.SUCCESS
@ -1540,7 +1540,10 @@ class SingleRun(Job):
self._sim_time(), self._average_speed())
def _connected_bar(self):
progress = self._tics.value / self._terminate_time.value
if self._terminate_time.value <= 0.0:
progress = 0.0
else:
progress = self._tics.value / self._terminate_time.value
return create_progress_bar(
progress, '{0:.1f}%'.format(100 * progress))

View File

@ -146,12 +146,12 @@ SIM_test_templates:
- unit_test
runs:
RUN_test/unit_test.py:
SIM_test_varserv:
path: test/SIM_test_varserv
labels:
- unit_test
runs:
RUN_test/unit_test.py:
# SIM_test_varserv:
# path: test/SIM_test_varserv
# labels:
# - unit_test
# runs:
# RUN_test/unit_test.py:
SIM_threads:
path: test/SIM_threads
labels:
@ -189,8 +189,8 @@ SIM_ball_L2:
runs:
SIM_ball_L3:
path: trick_sims/Ball/SIM_ball_L3
SIM_amoeba:
path: trick_sims/Cannon/SIM_amoeba
# SIM_amoeba:
# path: trick_sims/Cannon/SIM_amoeba
SIM_cannon_aero:
path: trick_sims/Cannon/SIM_cannon_aero
SIM_cannon_analytic:

View File

@ -0,0 +1,19 @@
monte_carlo.mc_master.activate("RUN_WARN_no_string_values")
monte_carlo.mc_master.set_num_runs(1)
print('*********************************************************************************')
print('this message is expected:')
print('No values for MonteCarloVariableRandomStringSet')
print('Length of values vector is zero for variable: test.x_string, Did you forget to call add_string()?')
print('*********************************************************************************')
# add a string variable but forget to give it options to randomize
mc_var = trick.MonteCarloVariableRandomStringSet( "test.x_string", 3)
#mc_var.add_string("\"ABC\"")
#mc_var.add_string("\"DEF\"")
#mc_var.add_string("'GHIJKL'")
mc_var.thisown = False
monte_carlo.mc_master.add_variable(mc_var)
monte_carlo.mc_master.generate_meta_data = True

View File

@ -10,32 +10,32 @@
- 0 variables of undefined type
********************* LIST OF VARIABLES, TYPES****************
test.x_boolean, Random
test.x_file_lookup[0], Prescribed
test.x_file_lookup[1], Prescribed
test.x_file_lookup[2], Prescribed
test.x_fixed_value_double, Constant
test.x_fixed_value_int, Constant
test.x_fixed_value_string, Constant
test.x_integer, Random
test.x_line_command, Calculated
test.x_normal, Random
test.x_normal_length, Random
test.x_normal_trunc[0], Random
test.x_normal_trunc[1], Random
test.x_normal_trunc[2], Random
test.x_normal_trunc[3], Random
test.x_normal_trunc[4], Random
test.x_semi_fixed_value, Constant
test.x_string, Random
test.x_uniform, Random
test.x_boolean: type=Random, dispersion=Uniform, min_value=0, max_value=1, seed=4, values=[False,True,]
test.x_file_lookup[0]: type=Prescribed, max_skip=0, is_dependent=0, filename=Modified_data/datafile.txt, column_number=3, first_column_number=1
test.x_file_lookup[1]: type=Prescribed, max_skip=0, is_dependent=1, filename=Modified_data/datafile.txt, column_number=2, first_column_number=1
test.x_file_lookup[2]: type=Prescribed, max_skip=0, is_dependent=1, filename=Modified_data/datafile.txt, column_number=1, first_column_number=1
test.x_fixed_value_double: type=Constant
test.x_fixed_value_int: type=Constant
test.x_fixed_value_string: type=Constant
test.x_integer: type=Random dispersion=Uniform, min_value=0, max_value=2, seed=1
test.x_line_command: type=Calculated
test.x_normal: type=Random, dispersion=Normal, mean=10, stddev=2, min_value=0, max_value=0, seed=2
test.x_normal_length: type=Random, dispersion=Normal, mean=10, stddev=2, min_value=0, max_value=0, seed=2
test.x_normal_trunc[0]: type=Random, dispersion=Normal, mean=10, stddev=2, min_value=9, max_value=11, seed=2
test.x_normal_trunc[1]: type=Random, dispersion=Normal, mean=10, stddev=2, min_value=9.5, max_value=10.7, seed=2
test.x_normal_trunc[2]: type=Random, dispersion=Normal, mean=10, stddev=2, min_value=9.9, max_value=11, seed=2
test.x_normal_trunc[3]: type=Random, dispersion=Normal, mean=10, stddev=2, min_value=9.9, max_value=0, seed=2
test.x_normal_trunc[4]: type=Random, dispersion=Normal, mean=10, stddev=2, min_value=0, max_value=4, seed=2
test.x_semi_fixed_value: type=Constant
test.x_string: type=Random, dispersion=Uniform, min_value=0, max_value=1, seed=3, values=["ABC","DEF",'GHIJKL',]
test.x_uniform: type=Random, dispersion=Uniform, min_value=10, max_value=20, seed=0
**************************************************************
*********** LIST OF EXECUTABLE FILES AND FUNCTIONS ***********
test.standalone_function( test.x_normal)
test.standalone_function( test.x_normal): type=Execute
***
Modified_data/sample.py
Modified_data/sample.py: type=Execute
***
**************************************************************

View File

@ -14,32 +14,32 @@ Sending meta-data to top-level directory.
- 0 variables of undefined type
********************* LIST OF VARIABLES, TYPES****************
test.x_boolean, Random
test.x_file_lookup[0], Prescribed
test.x_file_lookup[1], Prescribed
test.x_file_lookup[2], Prescribed
test.x_fixed_value_double, Constant
test.x_fixed_value_int, Constant
test.x_fixed_value_string, Constant
test.x_integer, Random
test.x_line_command, Calculated
test.x_normal, Random
test.x_normal_length, Random
test.x_normal_trunc[0], Random
test.x_normal_trunc[1], Random
test.x_normal_trunc[2], Random
test.x_normal_trunc[3], Random
test.x_normal_trunc[4], Random
test.x_semi_fixed_value, Constant
test.x_string, Random
test.x_uniform, Random
test.x_boolean: type=Random, dispersion=Uniform, min_value=0, max_value=1, seed=4, values=[False,True,]
test.x_file_lookup[0]: type=Prescribed, max_skip=0, is_dependent=0, filename=Modified_data/datafile.txt, column_number=3, first_column_number=1
test.x_file_lookup[1]: type=Prescribed, max_skip=0, is_dependent=1, filename=Modified_data/datafile.txt, column_number=2, first_column_number=1
test.x_file_lookup[2]: type=Prescribed, max_skip=0, is_dependent=1, filename=Modified_data/datafile.txt, column_number=1, first_column_number=1
test.x_fixed_value_double: type=Constant
test.x_fixed_value_int: type=Constant
test.x_fixed_value_string: type=Constant
test.x_integer: type=Random dispersion=Uniform, min_value=0, max_value=2, seed=1
test.x_line_command: type=Calculated
test.x_normal: type=Random, dispersion=Normal, mean=10, stddev=2, min_value=0, max_value=0, seed=2
test.x_normal_length: type=Random, dispersion=Normal, mean=10, stddev=2, min_value=0, max_value=0, seed=2
test.x_normal_trunc[0]: type=Random, dispersion=Normal, mean=10, stddev=2, min_value=9, max_value=11, seed=2
test.x_normal_trunc[1]: type=Random, dispersion=Normal, mean=10, stddev=2, min_value=9.5, max_value=10.7, seed=2
test.x_normal_trunc[2]: type=Random, dispersion=Normal, mean=10, stddev=2, min_value=9.9, max_value=11, seed=2
test.x_normal_trunc[3]: type=Random, dispersion=Normal, mean=10, stddev=2, min_value=9.9, max_value=0, seed=2
test.x_normal_trunc[4]: type=Random, dispersion=Normal, mean=10, stddev=2, min_value=0, max_value=4, seed=2
test.x_semi_fixed_value: type=Constant
test.x_string: type=Random, dispersion=Uniform, min_value=0, max_value=1, seed=3, values=["ABC","DEF",'GHIJKL',]
test.x_uniform: type=Random, dispersion=Uniform, min_value=10, max_value=20, seed=0
**************************************************************
*********** LIST OF EXECUTABLE FILES AND FUNCTIONS ***********
test.standalone_function( test.x_normal)
test.standalone_function( test.x_normal): type=Execute
***
Modified_data/sample.py
Modified_data/sample.py: type=Execute
***
**************************************************************

View File

@ -308,29 +308,34 @@ SIM_test_output_dir:
# The variable server client and SIM_amoeba sometimes fail to connect and need to be retried
SIM_test_varserv:
path: test/SIM_test_varserv
build_args: "-t"
binary: "T_main_{cpu}_test.exe"
runs:
RUN_test/unit_test.py:
phase: 1
returns: 0
RUN_test/err1_test.py:
phase: 2
returns: 10
RUN_test/err2_test.py:
phase: 3
returns: 10
SIM_amoeba:
path: trick_sims/Cannon/SIM_amoeba
build_args: "-t"
binary: "T_main_{cpu}_test.exe"
labels:
- retries_allowed
runs:
RUN_test/unit_test.py:
returns: 0
# JMP (9/23/2023): We can't have these in our regular CI test suite if they are going to
# periodically fail due to environmental variations over which we have no control. Commenting
# these out.
# SIM_test_varserv:
# path: test/SIM_test_varserv
# build_args: "-t"
# binary: "T_main_{cpu}_test.exe"
# runs:
# RUN_test/unit_test.py:
# phase: 1
# returns: 0
# RUN_test/err1_test.py:
# phase: 2
# returns: 10
# RUN_test/err2_test.py:
# phase: 3
# returns: 10
# SIM_amoeba:
# path: trick_sims/Cannon/SIM_amoeba
# build_args: "-t"
# binary: "T_main_{cpu}_test.exe"
# labels:
# - retries_allowed
# runs:
# RUN_test/unit_test.py:
# returns: 0
#TODO: all compares should be <test data> vs. <baseline data>, need to swap order!
SIM_mc_generation:
@ -442,6 +447,9 @@ SIM_mc_generation:
RUN_WARN_overconstrained_config/input.py:
compare:
phase: -1
RUN_WARN_no_string_values/input.py:
compare:
phase: -1
MONTE_RUN_WARN_overconstrained_config/RUN_0/monte_input.py:
FAIL_config_error/input.py:
returns: 1

View File

@ -0,0 +1,20 @@
global DR_GROUP_ID
global drg
try:
if DR_GROUP_ID >= 0:
DR_GROUP_ID += 1
except NameError:
DR_GROUP_ID = 0
drg = []
drg.append(trick.DRAscii("Submarine"))
drg[DR_GROUP_ID].set_freq(trick.DR_Always)
drg[DR_GROUP_ID].set_cycle(0.1)
drg[DR_GROUP_ID].set_single_prec_only(False)
drg[DR_GROUP_ID].add_variable("dyn.submarine.pos[0]")
drg[DR_GROUP_ID].add_variable("dyn.submarine.pos[1]")
drg[DR_GROUP_ID].add_variable("dyn.submarine.vel[0]")
drg[DR_GROUP_ID].add_variable("dyn.submarine.vel[1]")
drg[DR_GROUP_ID].set_max_file_size(1 * 1073741824) # multiply converts GiB to B --Dr. Dre
trick.add_data_record_group(drg[DR_GROUP_ID], trick.DR_Buffer)
drg[DR_GROUP_ID].enable()

View File

@ -0,0 +1,10 @@
trick.real_time_enable()
trick.exec_set_software_frame(0.1)
trick.itimer_enable()
trick.exec_set_enable_freeze(True)
trick.exec_set_freeze_command(True)
simControlPanel = trick.SimControlPanel()
trick.add_external_application(simControlPanel)

View File

@ -0,0 +1,23 @@
exec(open("./Modified_data/realtime.py").read())
dyn.submarine.pos[0] = 0.0
dyn.submarine.pos[1] = -0.5
dyn.submarine.vel[0] = 0.0
dyn.submarine.vel[1] = 0.0
# ==========================================
# Start the Satellite Graphics Client
# ==========================================
varServerPort = trick.var_server_get_port();
SubmarineDisplay_path = "models/graphics/build/SubmarineDisplay.jar"
if (os.path.isfile(SubmarineDisplay_path)) :
SubmarineDisplay_cmd = "java -jar " \
+ SubmarineDisplay_path \
+ " " + str(varServerPort) + " &" ;
print(SubmarineDisplay_cmd)
os.system( SubmarineDisplay_cmd);
else :
print('==================================================================================')
print('SubmarineDisplay needs to be built. Please \"cd\" into ../models/graphics and type \"mvn package\".')
print('==================================================================================')

View File

@ -0,0 +1,29 @@
/************************************************************
PURPOSE:
( Simulate a submarine. )
LIBRARY DEPENDENCIES:
((submarine/src/Submarine.cpp))
*************************************************************/
#include "sim_objects/default_trick_sys.sm"
##include "submarine/include/Submarine.hh"
class SubmarineSimObject : public Trick::SimObject {
public:
Submarine submarine;
SubmarineSimObject() {
("default_data") submarine.default_data() ;
("initialization") submarine.state_init() ;
("derivative") submarine.state_deriv() ;
(0.1, "scheduled") submarine.control() ;
("integration") trick_ret = submarine.state_integ() ;
("post_integration") submarine.state_post_integ() ;
}
};
SubmarineSimObject dyn;
IntegLoop dyn_integloop(0.1) dyn;
void create_connections() {
dyn_integloop.getIntegrator(Runge_Kutta_4, 6);
}

View File

@ -0,0 +1,2 @@
TRICK_CFLAGS += -Imodels
TRICK_CXXFLAGS += -Imodels

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1 @@
!\makefile

View File

@ -0,0 +1,6 @@
all:
mvn package
clean:
rm -rf build

View File

@ -0,0 +1,121 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>trick-java</groupId>
<artifactId>trick-java</artifactId>
<version>23.0.0-beta</version>
<name>trick-java</name>
<url>https://github.com/nasa/trick</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>SubmarineDisplay</finalName>
<directory>build</directory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.1.1</version>
<configuration>
<javadocExecutable>${java.home}/bin/javadoc</javadocExecutable>
<destDir>../../share/doc/trick/java</destDir>
</configuration>
</plugin>
</plugins>
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
<plugins>
<!-- clean lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#clean_Lifecycle -->
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
</plugin>
<!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<compilerArgs>
<arg>-g</arg>
<arg>-Xlint:unchecked</arg>
<arg>-Xlint:deprecation</arg>
</compilerArgs>
</configuration>
</plugin>
<plugin>
<!-- Build an executable JAR -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>SubmarineDisplay</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
<!-- site lifecycle, see https://maven.apache.org/ref/current/maven-core/lifecycles.html#site_Lifecycle -->
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>3.7.1</version>
</plugin>
<!--
<plugin>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>3.0.0</version>
</plugin>
-->
</plugins>
</pluginManagement>
</build>
</project>

View File

@ -0,0 +1,655 @@
/*
* Trick
* 2023 (c) National Aeronautics and Space Administration (NASA)
*/
// import java.awt;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Graphics;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.util.*;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.sound.sampled.*;
import java.net.URL;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.Rectangle2D;
import javax.swing.text.NumberFormatter;
import java.text.NumberFormat;
import javax.swing.JFormattedTextField;
import java.awt.Dimension;
import javax.swing.BorderFactory;
import javax.swing.border.EtchedBorder;
import java.awt.Component;
/**
*
* @author penn
*/
class ScenePoly {
public Color color;
public int n;
public double[] x;
public double[] y;
}
class RangeView extends JPanel {
private int scale;
private Color skyColor;
private Color oceanColor;
private Color hull_exterior_color;
private Color hull_interior_color;
private Color ballast_air_color;
// Origin of world coordinates in jpanel coordinates.
private int worldOriginX;
private int worldOriginY;
private double[] submarinePos;
private double[] submarineVel;
private double ballastAirRatio;
private double waterPressure;
private double pumpPower; /* watts = (joules/second) */
private double ballastEnergy;
private double hull_thickness;
private double ohull_oradius = 1.30;
private double ohull_iradius = 1.25;
private double ihull_oradius = 1.10;
private double ihull_iradius = 1.00;
private double hatch_out_radius = 0.5;
private ScenePoly hullPoly;
private int[] workPolyX, workPolyY;
// Controls
private int pumpPowerCommand ;
/**
* Class constructor.
*/
public RangeView( int mapScale) {
setScale(mapScale);
skyColor = new Color(184,219,236);
oceanColor = new Color(58,201,187);
ballast_air_color = new Color(220,220,250);
submarinePos = new double[]
{0.0, -0.0};
submarineVel = new double[]
{0.0, 0.0};
ballastAirRatio = 0.0;
hull_exterior_color = new Color(100,100,100);
hull_interior_color = new Color(240,240,220);
hull_thickness = 0.3;
ohull_oradius = 1.30;
ohull_iradius = 1.25;
ihull_oradius = 1.10;
ihull_iradius = 1.00;
hatch_out_radius = 0.5;
pumpPower = 0.0;
ballastEnergy = 0.0;
hullPoly = new ScenePoly();
hullPoly.color = hull_exterior_color;
hullPoly.x = new double[] {
-0.500, -0.500, -0.637, -0.766, -0.884, -0.990, -1.082, -1.159, -1.220, -1.264,
-1.291, -1.300, -1.291, -1.264, -1.220, -1.159, -1.082, -0.990, -0.884, -0.766,
-0.637, -0.500, -0.500, -0.629, -0.750, -0.861, -0.960, -1.046, -1.118, -1.175,
-1.217, -1.242, -1.250, -1.242, -1.217, -1.175, -1.118, -1.046, -0.960, -0.861,
-0.750, -0.629, -0.500, -0.500, -0.626, -0.741, -0.842, -0.929, -0.999, -1.052,
-1.085, -1.099, -1.094, -1.070, -1.026, -0.964, -0.885, -0.790, -0.681, -0.560,
-0.429, -0.290, -0.146, -0.000, 0.146, 0.290, 0.429, 0.560, 0.681, 0.790,
0.885, 0.964, 1.026, 1.070, 1.094, 1.099, 1.085, 1.052, 0.999, 0.929,
0.842, 0.741, 0.626, 0.500, 0.500, 0.629, 0.750, 0.861, 0.960, 1.046,
1.118, 1.175, 1.217, 1.242, 1.250, 1.242, 1.217, 1.175, 1.118, 1.046,
0.960, 0.861, 0.750, 0.629, 0.500, 0.500, 0.637, 0.766, 0.884, 0.990,
1.082, 1.159, 1.220, 1.264, 1.291, 1.300, 1.291, 1.264, 1.220, 1.159,
1.082, 0.990, 0.884, 0.766, 0.637, 0.500, 0.500, -0.500};
hullPoly.y = new double[] {
1.400, 1.200, 1.133, 1.050, 0.953, 0.843, 0.721, 0.589, 0.449, 0.303,
0.153, 0.000, -0.153, -0.303, -0.449, -0.589, -0.721, -0.843, -0.953, -1.050,
-1.133, -1.200, -1.146, -1.080, -1.000, -0.907, -0.801, -0.685, -0.559, -0.426,
-0.287, -0.145, 0.000, 0.145, 0.287, 0.426, 0.559, 0.685, 0.801, 0.907,
1.000, 1.080, 1.146, 0.980, 0.905, 0.813, 0.707, 0.589, 0.460, 0.323,
0.180, 0.034, -0.112, -0.257, -0.397, -0.530, -0.654, -0.766, -0.864, -0.947,
-1.013, -1.061, -1.090, -1.100, -1.090, -1.061, -1.013, -0.947, -0.864, -0.766,
-0.654, -0.530, -0.397, -0.257, -0.112, 0.034, 0.180, 0.323, 0.460, 0.589,
0.707, 0.813, 0.905, 0.980, 1.146, 1.080, 1.000, 0.907, 0.801, 0.685,
0.559, 0.426, 0.287, 0.145, 0.000, -0.145, -0.287, -0.426, -0.559, -0.685,
-0.801, -0.907, -1.000, -1.080, -1.146, -1.200, -1.133, -1.050, -0.953, -0.843,
-0.721, -0.589, -0.449, -0.303, -0.153, 0.000, 0.153, 0.303, 0.449, 0.589,
0.721, 0.843, 0.953, 1.050, 1.133, 1.200, 1.400, 1.400};
hullPoly.n = 128;
workPolyX = new int[150];
workPolyY = new int[150];
}
// |jpanel_x| = |origin_x| + |scale 0 | * |cos(angle) -sin(angle)| * |world_x|
// |jpanel_y| |origin_y| | 0 -scale| |sin(angle) cos(angle)| |world_y|
public void fillScenePoly(Graphics2D g, ScenePoly p, double angle_r , double x, double y) {
for (int ii = 0; ii < p.n; ii++) {
workPolyX[ii] = (int)(worldOriginX + scale *
( Math.cos(angle_r) * p.x[ii] - Math.sin(angle_r) * p.y[ii] + x));
workPolyY[ii] = (int)(worldOriginY - scale *
( Math.sin(angle_r) * p.x[ii] + Math.cos(angle_r) * p.y[ii] + y));
}
g.setPaint(p.color);
g.fillPolygon(workPolyX, workPolyY, p.n);
}
public void fillSceneOval(Graphics2D g2d, Color color, double x, double y, double w, double h) {
g2d.setPaint(color);
g2d.fillOval( (int)(worldOriginX+scale*(x-w/2)), (int)(worldOriginY-scale*(y+h/2)), (int)(scale*w), (int)(scale*h));
}
public void fillSceneRect(Graphics2D g2d, Color color, double x, double y, double w, double h) {
g2d.setPaint(color);
g2d.fillRect( (int)(worldOriginX+scale*(x-w/2)), (int)(worldOriginY-scale*(y+h/2)), (int)(scale*w), (int)(scale*h));
}
public int getPumpPowerCommand() {
return pumpPowerCommand;
}
public void setPumpPowerCommand(int power) {
pumpPowerCommand = power;
}
public void setSubmarinePos(double x, double y) {
submarinePos[0] = x;
submarinePos[1] = y;
}
public void setSubmarineVel(double vx, double vy) {
submarineVel[0] = vx;
submarineVel[1] = vy;
}
public void setBallastAirRatio(double ratio) {
ballastAirRatio = ratio;
}
public void setWaterPressure(double P) {
waterPressure = P;
}
public void setPumpPower(double power) {
pumpPower = power;
}
public void setBallastEnergy(double energy) {
ballastEnergy = energy;
}
public void setScale (int mapScale) {
if (mapScale < 2) {
scale = 2;
} else if (mapScale > 128) {
scale = 128;
} else {
scale = mapScale;
}
repaint();
}
public int getScale() {
return scale;
}
private void doDrawing(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
RenderingHints rh = new RenderingHints(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
rh.put(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
int ii, jj;
int width = getWidth();
int height = getHeight();
double R_intensity = 0.0;
double G_intensity = 0.0;
double B_intensity = 0.0;
// |jpanel_x| = |origin_x| + |scale 0 | * |cos(angle) -sin(angle)| * |world_x|
// |jpanel_y| |origin_y| | 0 -scale| |sin(angle) cos(angle)| |world_y|
worldOriginX = (width/2) - (int)(scale * submarinePos[0]);
worldOriginY = (height/2) + (int)(scale * submarinePos[1]);
// ===============================================================================
// Draw Sky & Ocean
// ===============================================================================
if (worldOriginY < 0) {
if (submarinePos[1] >= 0.0) R_intensity = 1.0;
else if (submarinePos[1] <= -50.0) R_intensity = 0.0;
else R_intensity = (1.0 - (submarinePos[1]/-50.0));
if (submarinePos[1] >= 0.0) R_intensity = 1.0;
else if (submarinePos[1] <= -100.0) R_intensity = 0.0;
else G_intensity = (1.0 - (submarinePos[1]/-100.0));
if (submarinePos[1] >= 0.0) R_intensity = 1.0;
else if (submarinePos[1] <= -200.0) B_intensity = 0.0;
else B_intensity = (1.0 - (submarinePos[1]/-200.0));
g2d.setPaint( new Color( (int)(oceanColor.getRed() * R_intensity),
(int)(oceanColor.getGreen() * G_intensity),
(int)(oceanColor.getBlue() * B_intensity)));
g2d.fillRect(0, 0, width, height);
} else if (worldOriginY > height) {
g2d.setPaint(skyColor);
g2d.fillRect(0, 0, width, height);
} else {
g2d.setPaint(skyColor);
g2d.fillRect(0, 0, width, worldOriginY);
g2d.setPaint(oceanColor);
g2d.fillRect(0, worldOriginY, width, height);
}
// ===============================================================================
// Draw Submarine
// ===============================================================================
// Draw Ballast Air
Rectangle2D clipRect =
new Rectangle2D.Double((int)(worldOriginX+scale*(submarinePos[0]-ohull_iradius)),
(int)(worldOriginY-scale*(submarinePos[1]+ohull_iradius)),
scale*ohull_iradius*2.0, scale*ohull_iradius*2.0*ballastAirRatio);
g2d.setClip(clipRect);
fillSceneOval(g2d, ballast_air_color, submarinePos[0], submarinePos[1], ohull_iradius*2.0, ohull_iradius*2.0);
g2d.setClip(null);
// Draw Submarine Hull
fillScenePoly(g2d, hullPoly, 0.0, submarinePos[0], submarinePos[1]);
fillSceneOval(g2d, hull_interior_color, submarinePos[0], submarinePos[1], ihull_iradius*2.0, ihull_iradius*2.0);
fillSceneOval(g2d, Color.GRAY, submarinePos[0]-0.6, submarinePos[1]+0.6, 0.4, 0.4);
fillSceneOval(g2d, ballast_air_color, submarinePos[0]-0.6, submarinePos[1]+0.6, 0.3, 0.3);
fillSceneOval(g2d, Color.GRAY, submarinePos[0]-0.8, submarinePos[1]+0.3, 0.4, 0.4);
fillSceneOval(g2d, ballast_air_color, submarinePos[0]-0.8, submarinePos[1]+0.3, 0.3, 0.3);
fillSceneOval(g2d, Color.GRAY, submarinePos[0]+0.6, submarinePos[1]+0.6, 0.4, 0.4);
fillSceneOval(g2d, ballast_air_color, submarinePos[0]+0.6, submarinePos[1]+0.6, 0.3, 0.3);
fillSceneOval(g2d, Color.GRAY, submarinePos[0]+0.8, submarinePos[1]+0.3, 0.4, 0.4);
fillSceneOval(g2d, ballast_air_color, submarinePos[0]+0.8, submarinePos[1]+0.3, 0.3, 0.3);
// Floor
fillSceneRect(g2d, hull_exterior_color, submarinePos[0], submarinePos[1]-0.6, 1.7*ihull_iradius, 0.1);
// Keel
fillSceneRect(g2d, hull_exterior_color, submarinePos[0], submarinePos[1]-ihull_oradius-0.1, 0.6, 0.3);
// ===============================================================================
// Draw depth markers.
// ===============================================================================
int tickRange = 50;
if (scale >= 8) tickRange = 20;
if (scale >= 16) tickRange = 10;
if (scale >= 32) tickRange = 5;
if (scale >= 64) tickRange = 1;
int upper = ((int)(( - worldOriginY)/(scale * tickRange)) + 1) * tickRange;
int lower = ((int)((height - worldOriginY)/(scale * tickRange)) + 1) * tickRange;
g2d.setPaint(Color.WHITE);
for (ii = upper ; ii < lower ; ii += tickRange) {
int my = (int)(worldOriginY + scale * ii);
g2d.drawLine(worldOriginX + 150, my, worldOriginX + 200, my );
g2d.drawString ( String.format("%d",ii), worldOriginX + 210, my);
}
// ===============================================================================
// Draw Information
// ===============================================================================
g2d.setPaint(Color.WHITE);
g2d.drawString ( String.format("SCALE: %d pixels/meter",scale), 20,20);
g2d.drawString ( String.format("Water Pressure (PSI) : [%.2f]", waterPressure), 20,40);
g2d.drawString ( String.format("Ballast Energy (Joules) : [%.2f]", ballastEnergy), 20,60);
g2d.drawString ( String.format("Pump Power (Watts) : [%.2f]", pumpPower), 20,80);
g2d.drawString ( String.format("Submarine Pos: [%.2f, %.2f]", submarinePos[0], submarinePos[1]), 20,100);
g2d.drawString ( String.format("Submarine Vel: [%.2f, %.2f]", submarineVel[0], submarineVel[1]), 20,120);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
doDrawing(g);
}
}
class TrickSimMode {
public static final int INIT = 0;
public static final int FREEZE = 1;
public static final int RUN = 5;
}
class PumpPowerCtrlPanel extends JPanel implements ChangeListener {
static final int POWER_MIN = -5000;
static final int POWER_MAX = 5000;
static final int POWER_INIT = 0;
private RangeView rangeView;
private JSlider powerSlider ;
public PumpPowerCtrlPanel (RangeView view) {
rangeView = view;
setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
JLabel sliderLabel = new JLabel("", JLabel.CENTER);
sliderLabel.setAlignmentX(CENTER_ALIGNMENT);
powerSlider = new JSlider(JSlider.HORIZONTAL, POWER_MIN, POWER_MAX, POWER_INIT);
powerSlider.addChangeListener(this);
powerSlider.setToolTipText("Ballast Pump Power.");
powerSlider.setMajorTickSpacing(1000);
powerSlider.setMinorTickSpacing(100);
powerSlider.setPaintTicks(true);
powerSlider.setPaintLabels(true);
add(sliderLabel);
add(powerSlider);
}
@Override
public void stateChanged(ChangeEvent e) {
JSlider source = (JSlider)e.getSource();
if (!source.getValueIsAdjusting()) {
rangeView.setPumpPowerCommand( source.getValue() );
}
}
public void setValue(int value) {
if (value > POWER_MAX) value = POWER_MAX;
if (value < POWER_MIN) value = POWER_MIN;
powerSlider.setValue(value);
}
}
class ControlPanel extends JPanel implements ActionListener {
private RangeView rangeView;
private JButton zoomOutButton, zoomInButton;
private JButton shutDownButton;
private PumpPowerCtrlPanel pumpPowerCtrlPanel;
public ControlPanel(RangeView view) {
rangeView = view;
setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
JPanel labeledPumpPowerCtrlPanel = new JPanel();
labeledPumpPowerCtrlPanel.setLayout(new BoxLayout(labeledPumpPowerCtrlPanel, BoxLayout.Y_AXIS));
JLabel powerPowerControlLabel = new JLabel("-Remove Ballast Air- Pump Power (Watts) -Add Ballast Air-");
powerPowerControlLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
labeledPumpPowerCtrlPanel.add(powerPowerControlLabel);
pumpPowerCtrlPanel = new PumpPowerCtrlPanel(rangeView);
labeledPumpPowerCtrlPanel.add( pumpPowerCtrlPanel );
add(labeledPumpPowerCtrlPanel);
zoomOutButton = new JButton("Zoom Out");
zoomOutButton.addActionListener(this);
zoomOutButton.setActionCommand("zoomout");
zoomOutButton.setToolTipText("Zoom Out");
add(zoomOutButton);
zoomInButton = new JButton("Zoom In");
zoomInButton.addActionListener(this);
zoomInButton.setActionCommand("zoomin");
zoomInButton.setToolTipText("Zoom In");
add(zoomInButton);
}
public void actionPerformed(ActionEvent e) {
String s = e.getActionCommand();
switch (s) {
case "zoomout":
rangeView.setScale( rangeView.getScale() / 2 );
break;
case "zoomin":
rangeView.setScale( rangeView.getScale() * 2 );
break;
default:
System.out.println("Unknown Action Command:" + s);
break;
}
}
} // class ControlPanel
public class SubmarineDisplay extends JFrame {
private RangeView rangeView;
private BufferedReader in;
private DataOutputStream out;
private JPanel panelGroup0;
private JPanel panelGroup1;
private ControlPanel controlPanel;
public SubmarineDisplay(RangeView arena) {
setTitle("Submarine Range");
rangeView = arena;
panelGroup1 = new JPanel();
panelGroup1.setLayout(new BoxLayout(panelGroup1, BoxLayout.X_AXIS));
panelGroup1.add(rangeView);
controlPanel = new ControlPanel(rangeView);
panelGroup0 = new JPanel();
panelGroup0.setLayout(new BoxLayout(panelGroup0, BoxLayout.Y_AXIS));
panelGroup0.add(panelGroup1);
panelGroup0.add(controlPanel);
add(panelGroup0);
rangeView.setScale(64);
rangeView.setSubmarinePos (0.0, 0.0);
setSize(800, 500);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setFocusable(true);
}
public void connectToServer(String host, int port ) throws IOException {
Socket socket = new Socket(host, port);
in = new BufferedReader( new InputStreamReader( socket.getInputStream()));
out = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
}
public void drawRangeView() {
rangeView.repaint();
}
private static void printHelpText() {
System.out.println(
"----------------------------------------------------------------------\n"
+ "usage: java jar SubmarineDisplay.jar <port-number>\n"
+ "----------------------------------------------------------------------\n"
);
}
public enum ModelState { INACTIVE, READY, ACTIVE }
public static void main(String[] args) throws IOException, InterruptedException {
String host = "localHost";
int port = 0;
boolean boom = false;
// ==========================================================
// Handle program arguments.
// ==========================================================
int ii = 0;
while (ii < args.length) {
switch (args[ii]) {
case "-help" :
case "--help" : {
printHelpText();
System.exit(0);
} break;
default : {
port = (Integer.parseInt(args[ii]));
} break;
}
++ii;
}
boolean go = true;
double dt = 0.100; // Time between updates (seconds).
double posx = 0.0;
double posy = 0.0;
double velx = 0.0;
double vely = 0.0;
double ratio = 0.0;
double Pwater = 0.0;
double pump_power = 0.0;
double energy = 0.0;
// Outbound command variables
int pump_power_command;
int simMode = 0;
boolean standalone = false;
int mapScale = 32 ; // pixels per meter.
RangeView rangeView = new RangeView( mapScale);
SubmarineDisplay submarineDisplay = new SubmarineDisplay( rangeView);
submarineDisplay.setVisible(true);
submarineDisplay.drawRangeView();
if (go) {
if (port == 0) {
System.out.println("No variable server port specified.");
printHelpText();
System.exit(0);
}
// Connect to the Trick simulation's variable server
System.out.println("Connecting to: " + host + ":" + port);
submarineDisplay.connectToServer(host, port);
submarineDisplay.out.writeBytes("trick.var_set_client_tag(\"SubmarineDisplay\") \n");
submarineDisplay.out.flush();
// Have the Variable Server send us the simulation mode ONCE.
submarineDisplay.out.writeBytes( "trick.var_add(\"trick_sys.sched.mode\")\n" +
"trick.var_send() \n" +
"trick.var_clear() \n");
submarineDisplay.out.flush();
// Read the response and extract the simulation mode.
try {
String line;
String field[];
line = submarineDisplay.in.readLine();
field = line.split("\t");
simMode = Integer.parseInt( field[1]);
} catch (IOException | NullPointerException e ) {
go = false;
}
// Configure the Variable Server to cyclically send us the following varibales.
// Tell the variable server:
// 1) We want the values of the following variables:
submarineDisplay.out.writeBytes( "trick.var_pause() \n" +
"trick.var_add(\"dyn.submarine.pos[0]\")\n" +
"trick.var_add(\"dyn.submarine.pos[1]\")\n" +
"trick.var_add(\"dyn.submarine.vel[0]\")\n" +
"trick.var_add(\"dyn.submarine.vel[1]\")\n" +
"trick.var_add(\"dyn.submarine.ballast_air_ratio\")\n" +
"trick.var_add(\"dyn.submarine.water_pressure_PSI\")\n" +
"trick.var_add(\"dyn.submarine.ballast_energy\")\n" +
"trick.var_add(\"dyn.submarine.pump_power\")\n" +
"trick.var_add(\"trick_sys.sched.mode\")\n" +
// 2) We want the responses in ASCII:
"trick.var_ascii() \n" +
// 3) We want values to be updated at the specified rate:
String.format("trick.var_cycle(%.3f)\n", dt) +
// 4) Start sending values as specified.
"trick.var_unpause() \n" );
submarineDisplay.out.flush();
} // if go
while (go) {
// Recieve and parse periodic data response from the variable server.
try {
String line;
String field[];
line = submarineDisplay.in.readLine();
field = line.split("\t");
posx = Double.parseDouble( field[1]);
posy = Double.parseDouble( field[2]);
velx = Double.parseDouble( field[3]);
vely = Double.parseDouble( field[4]);
ratio = Double.parseDouble( field[5]);
Pwater = Double.parseDouble( field[6]);
energy = Double.parseDouble( field[7]);
pump_power = Double.parseDouble( field[8]);
simMode = Integer.parseInt( field[9]);
} catch (IOException | NullPointerException e ) {
go = false;
}
// Update the display data.
rangeView.setSubmarinePos(posx, posy);
rangeView.setSubmarineVel(velx, vely);
rangeView.setBallastAirRatio(ratio);
rangeView.setWaterPressure(Pwater);
rangeView.setPumpPower(pump_power);
rangeView.setBallastEnergy(energy);
pump_power_command = rangeView.getPumpPowerCommand();
submarineDisplay.out.writeBytes( String.format("dyn.submarine.pump_power_command = %d ;\n", pump_power_command ));
submarineDisplay.out.flush();
// Update the scene.
submarineDisplay.drawRangeView();
} // while
} // main
} // class

View File

@ -0,0 +1,66 @@
/************************************************************************
PURPOSE: (Simulate a submarine.)
LIBRARY DEPENDENCIES:
((submarine/src/Submarine.o))
**************************************************************************/
#ifndef SUBMARINE_HH
#define SUBMARINE_HH
// Density of salt water = 1023.6 kg/m^3
#define DENSITY_SALT_WATER 1023.6
// Acceleration of gravity = 9.80665 m/s^2
#define GRAVITY 9.80665
//
#define CONVERSION_PASCALS_TO_PSI 1.4504e-4
class Submarine {
public:
// Parameters
double outer_hull_outer_radius;
double outer_hull_inner_radius;
double inner_hull_outer_radius;
double inner_hull_inner_radius;
double hull_length;
double ballast_tank_volume;
double hard_ballast_mass;
double hull_mass;
double payload_mass;
double Cd;
// State Variables (Uncalculated Variables)
double pos[2];
double vel[2];
double ballast_energy; // joules
double pump_power; // watts
// Calculated Variables
double acc[2];
// Control Variable
double ballast_air_ratio; // To the GUI.
double water_pressure_pascals;
double water_pressure_PSI; // To the GUI.
int pump_power_command; // From the GUI.
// Methods
int default_data();
int state_init();
int state_deriv();
int state_integ();
int control();
void calc_water_pressure();
double calc_ballast_air_volume();
double calc_pressure_hull_displaced_volume();
double calc_total_displaced_volume();
double calc_gravity_force ();
double calc_total_mass ();
double calc_fixed_mass();
double calc_buoyancy_force( );
double calc_ballast_water_mass();
double calc_ballast_water_volume ();
double calc_drag_force();
double calc_pressure_hull_volume();
int state_post_integ();
};
#endif

View File

@ -0,0 +1,145 @@
/********************************* TRICK HEADER *******************************
PURPOSE: ( Simulate a submarine. )
LIBRARY DEPENDENCY:
((Submarine.o))
*******************************************************************************/
#include "submarine/include/Submarine.hh"
#include "trick/integrator_c_intf.h"
#include <stdlib.h>
#include <math.h>
#include <iostream>
int Submarine::default_data() {
// Parameters
outer_hull_outer_radius = 1.30; // meters
outer_hull_inner_radius = 1.25; // meters
inner_hull_outer_radius = 1.10; // meters
inner_hull_inner_radius = 1.00; // meters
hull_length = 3.0; // meters
ballast_tank_volume = 1.0; // cubic meter
hard_ballast_mass= 0.0; // kg
hull_mass = 10000.0; // kg
payload_mass = 1500.0; // kg
Cd = 0.5;
// State
pos[0] = 0.0; // meters
pos[1] = 0.0;
vel[0] = 0.0; // meters/second
vel[1] = 0.0;
ballast_energy = 80000.0; // Joules
pump_power = 0.0; // Watts
// Control Variable
ballast_air_ratio = 0.0;
water_pressure_pascals = 0.0;
water_pressure_PSI = 0.0;
pump_power_command = 0;
return (0);
}
int Submarine::state_init() {
return (0);
}
int Submarine::state_deriv() {
double total_mass = calc_total_mass();
double F_gravity = calc_gravity_force();
double F_buoyancy = calc_buoyancy_force();
double F_drag = calc_drag_force();
acc[0] = 0.0;
acc[1] = (F_gravity + F_buoyancy + F_drag) / total_mass;
return(0);
}
int Submarine::state_integ() {
int integration_step;
load_state ( &pos[0], &pos[1], &vel[0], &vel[1], &ballast_energy, (double*)0);
load_deriv ( &vel[0], &vel[1], &acc[0], &acc[1], &pump_power, (double*)0);
integration_step = integrate();
unload_state( &pos[0], &pos[1], &vel[0], &vel[1], &ballast_energy, (double*)0);
if (ballast_energy < 0.0) {
ballast_energy = 0.0;
}
return(integration_step);
}
// Calculate Water Pressure at depth in Pascals
void Submarine::calc_water_pressure() {
water_pressure_pascals = DENSITY_SALT_WATER * GRAVITY * -pos[1] + 14.7/CONVERSION_PASCALS_TO_PSI;
water_pressure_PSI = water_pressure_pascals * CONVERSION_PASCALS_TO_PSI;
}
// Calculate volume of water displaced from the ballast water tank by compressed air.
double Submarine::calc_ballast_air_volume() {
calc_water_pressure();
double ballast_air_volume = ballast_energy / water_pressure_pascals;
// Ballast_air_volume cant' exceed to volume of the ballast tank.
if ( ballast_air_volume > ballast_tank_volume ) {
ballast_air_volume = ballast_tank_volume;
ballast_energy = ballast_air_volume * water_pressure_pascals;
}
ballast_air_ratio = ballast_air_volume / ballast_tank_volume;
return ballast_air_volume;
}
// Calculate the volume of water currently displaced by the pressure hull.
// This is just multiplying the hull volume times a sigmoid.
double Submarine::calc_pressure_hull_displaced_volume() {
double C = 5.5;
return ( calc_pressure_hull_volume() / (1 + exp( C * pos[1] )));
}
double Submarine::calc_total_displaced_volume() {
return calc_ballast_air_volume() + calc_pressure_hull_displaced_volume();
}
double Submarine::calc_gravity_force () {
return -calc_total_mass() * GRAVITY;
}
double Submarine::calc_total_mass () {
double total_mass = hard_ballast_mass + calc_fixed_mass() + calc_ballast_water_mass();
return total_mass;
}
double Submarine::calc_fixed_mass() {
double fixed_mass = (hull_mass + payload_mass);
return fixed_mass;
}
double Submarine::calc_buoyancy_force( ) {
return ( calc_total_displaced_volume() * DENSITY_SALT_WATER * GRAVITY );
}
double Submarine::calc_ballast_water_mass() {
double ballast_mass = calc_ballast_water_volume() * DENSITY_SALT_WATER ;
return ballast_mass;
}
double Submarine::calc_ballast_water_volume () {
double ballast_water_volume = ballast_tank_volume - calc_ballast_air_volume();
return ballast_water_volume;
}
double Submarine::calc_drag_force() {
double A = outer_hull_outer_radius * 2 * hull_length;
return -0.5 * DENSITY_SALT_WATER * vel[1] * fabs(vel[1]) * Cd * A;
}
double Submarine::calc_pressure_hull_volume() {
return ( M_PI * inner_hull_outer_radius * inner_hull_outer_radius * hull_length);
}
int Submarine::control() {
pump_power = pump_power_command;
if (pump_power > 5000.0) pump_power = 5000.0;
if (pump_power < -5000.0) pump_power = -5000.0;
return(0);
}
int Submarine::state_post_integ() {
return(0);
}

View File

@ -68,8 +68,21 @@ bool CXXRecordVisitor::TraverseDecl(clang::Decl *d) {
// test against them.
ClassValues temp_cv ;
temp_cv.getNamespacesAndClasses(crd->getDeclContext()) ;
private_embedded_classes.insert(temp_cv.getFullyQualifiedName() + crd->getNameAsString()) ;
//std::cout << "marking private " << temp_cv.getFullyQualifiedName() + crd->getNameAsString() << std::endl ;
/*
for (auto const &pec : private_embedded_classes) {
std::cout << "===private_embedded_classes..." << pec << "===" << std::endl;
}
if (friend_classes.size() > 0) {
for (auto const &fc : friend_classes) {
std::cout << "===friend_classes..." << fc << "===" << std::endl;
}
}
*/
std::string class_str = temp_cv.getFullyQualifiedName() + crd->getNameAsString();
// Private embedded classes are not printed to io source unless they are friend classes.
if (friend_classes.find(class_str) == friend_classes.end()) {
private_embedded_classes.insert(class_str);
}
}
}
}
@ -104,6 +117,26 @@ bool CXXRecordVisitor::TraverseDecl(clang::Decl *d) {
}
break ;
case clang::Decl::Friend : {
ClassValues temp_cv ;
temp_cv.getNamespacesAndClasses(d->getDeclContext()) ;
clang::FriendDecl * fd = static_cast<clang::FriendDecl *>(d) ;
std::string class_str;
// Only use namespaces for identifying class name as the class name can't be the same within the same namespace.
if (fd->getFriendDecl() != NULL) {
class_str = temp_cv.getNameOnlyWithNamespaces() + fd->getFriendDecl()->getNameAsString();
}
// For friend class, only need to get type here but the above getting class_str is for just in case needed.
if (fd->getFriendType() != NULL) {
class_str = temp_cv.getNameOnlyWithNamespaces() + fd->getFriendType()->getType().getAsString();
}
size_t pos;
// Only save class name to the friend class list
if ((pos = class_str.find("class ")) != std::string::npos ) {
class_str.erase(pos , 6) ;
friend_classes.insert(class_str);
}
TraverseFriendDecl(static_cast<clang::FriendDecl *>(d)) ;
}
break ;
@ -331,6 +364,8 @@ ClassValues * CXXRecordVisitor::get_class_data() {
std::set<std::string> CXXRecordVisitor::private_embedded_classes ;
std::set<std::string> CXXRecordVisitor::friend_classes ;
void CXXRecordVisitor::addPrivateEmbeddedClass( std::string in_name ) {
private_embedded_classes.insert(in_name) ;
}

View File

@ -80,6 +80,7 @@ class CXXRecordVisitor : public clang::RecursiveASTVisitor<CXXRecordVisitor> {
bool access_spec_found ;
static std::set<std::string> private_embedded_classes ;
static std::set<std::string> friend_classes ;
} ;
#endif

View File

@ -219,3 +219,10 @@ std::string ConstructValues::getFullyQualifiedTypeName(const std::string& delimi
oss << name ;
return oss.str() ;
}
std::string ConstructValues::getNameOnlyWithNamespaces(const std::string& delimiter) {
std::ostringstream oss ;
printNamespaces(oss, delimiter) ;
oss << name ;
return oss.str() ;
}

View File

@ -61,6 +61,7 @@ class ConstructValues {
}
std::string getFullyQualifiedName(const std::string& delimiter = "::") ;
std::string getNameOnlyWithNamespaces(const std::string& delimiter = "::");
void printOpenNamespaceBlocks(std::ostream& ostream);
void printCloseNamespaceBlocks(std::ostream& ostream);

View File

@ -11,11 +11,17 @@ CLANG_PATCHLEVEL := $(shell $(LLVM_HOME)/bin/llvm-config --version | cut -f3 -d.
CLANG_MINOR_GTEQ5 := $(shell [ $(CLANG_MAJOR) -gt 3 -o \( $(CLANG_MAJOR) -eq 3 -a $(CLANG_MINOR) -ge 5 \) ] && echo 1)
CLANG_MAJOR_GTEQ10 := $(shell [ $(CLANG_MAJOR) -ge 10 ] && echo 1)
# By default, Clang 16 or later builds C++ code according to the C++17 standard.
CLANG_MAJOR_GTEQ16 := $(shell [ $(CLANG_MAJOR) -ge 16 ] && echo 1)
ifeq ($(CLANG_MAJOR_GTEQ16),1)
CXXFLAGS += -std=c++17
else
ifeq ($(CLANG_MAJOR_GTEQ10),1)
CXXFLAGS += -std=c++14
else
CXXFLAGS += -std=c++11
endif
endif
LLVMLDFLAGS := $(shell $(LLVM_HOME)/bin/llvm-config --ldflags) $(UDUNITS_LDFLAGS)
@ -48,8 +54,12 @@ endif
ifeq ($(TRICK_HOST_TYPE),Darwin)
CLANGLIBS += $(shell $(LLVM_HOME)/bin/llvm-config --libs)
CLANGLIBS += $(filter-out -llibxml2.tbd,$(shell $(LLVM_HOME)/bin/llvm-config --system-libs))
ifeq ($(CLANG_MAJOR_GTEQ16),1)
CLANGLIBS += -lc++abi -lclang-cpp
else
CLANGLIBS += -lc++abi
endif
endif
all: $(ICG)

View File

@ -200,19 +200,11 @@ PlotViewNode::PlotViewNode( Widget Toplevel, Widget Parent_form, DPC_plot* Plot
curves = new XYCurve[n_curves];
// X Axis label.
if ((const_temp_str = plot->getXLabel()) != NULL) {
snprintf( charbuf, sizeof(charbuf), "%s", const_temp_str );
} else {
charbuf[0] = '\0';
}
snprintf( charbuf, sizeof(charbuf), "%s", const_temp_str );
X_label = XmStringCreateLocalized( charbuf);
// Y Axis label.
if ((const_temp_str = plot->getYLabel()) != NULL) {
snprintf( charbuf, sizeof(charbuf), "%s", const_temp_str );
} else {
charbuf[0] = '\0';
}
snprintf( charbuf, sizeof(charbuf), "%s", const_temp_str );
Y_label = XmStringCreateLocalized( charbuf);
// ---------------------------

View File

@ -319,15 +319,14 @@ TableViewNode::TableViewNode( Widget Toplevel, DPC_table* Table, int Xpos, int Y
// Print out the column heading labels.
// ----------------------------------------------------------------
for (colix=0; colix < n_columns ; colix++) {
const char *column_label = table->getColumnLabel( colix);
if (!column_label) {
std::string column_label = table->getColumnLabel(colix);
if (column_label.empty()) {
snprintf( charbuf, sizeof(charbuf), "Column_%d", colix);
table_text_buf = twprint( table_text_buf, &table_buf_size, &table_insertion_pos,
column_heading_format[colix], charbuf);
} else {
table_text_buf = twprint( table_text_buf, &table_buf_size, &table_insertion_pos,
column_heading_format[colix], column_label);
column_heading_format[colix], column_label.c_str());
}
}
table_text_buf = twprint( table_text_buf, &table_buf_size, &table_insertion_pos, (char *)"\n");

View File

@ -124,11 +124,11 @@ void GPViewPlotNode::finalize() {
* So, check the return value before making the assignment.
*/
plot_title = (plot->getTitle()) ? plot->getTitle() : tmp_stream.str();
plot_x_label = (plot->getXLabel()) ? plot->getXLabel() : "";
plot_x_label = plot->getXLabel();
plot_x_scale = (plot->getAttribute("x_scale")) ? plot->getAttribute("x_scale") : "";
plot_x_min_rng = (plot->getAttribute("xmin")) ? plot->getAttribute("xmin") : "";
plot_x_max_rng = (plot->getAttribute("xmax")) ? plot->getAttribute("xmax") : "";
plot_y_label = (plot->getYLabel()) ? plot->getYLabel() : "";
plot_y_label = plot->getYLabel();
plot_y_format = (plot->getAttribute("format")) ? plot->getAttribute("format") : "";
plot_y_scale = (plot->getAttribute("y_scale")) ? plot->getAttribute("y_scale") : "";
plot_y_min_rng = (plot->getAttribute("ymin")) ? plot->getAttribute("ymin") : "";

View File

@ -11,8 +11,8 @@ DPC_UnitConvDataStream::DPC_UnitConvDataStream(DataStream* ds, const char *ToUni
ut_unit * to = NULL ;
ut_unit * from = NULL ;
const char * recorded_units = ds->getUnit().c_str();
std::string recorded_units = ds->getUnit();
source_ds = ds;
@ -24,7 +24,7 @@ DPC_UnitConvDataStream::DPC_UnitConvDataStream(DataStream* ds, const char *ToUni
// If the user has specified a units conversion and those units are valid ...
if ( to != NULL ) {
// If the recorded data file doesn't contain the units in which the data is recorded ...
if ((recorded_units == NULL) || (strcmp(recorded_units,"") == 0)) {
if (recorded_units.empty()) {
// If the user didn't give us a hint as to what the units are (using var@from_units) ...
if ((FromUnitsHint == NULL) || (strcmp(FromUnitsHint,"") == 0)) {
// set the from units to the same as the to units.
@ -47,7 +47,7 @@ DPC_UnitConvDataStream::DPC_UnitConvDataStream(DataStream* ds, const char *ToUni
}
} else { // the recorded data file does "know" the units in which the data was recorded,
// so those will be the units that we convert from.
from = ut_parse(u_system, recorded_units, UT_ASCII) ;
from = ut_parse(u_system, recorded_units.c_str(), UT_ASCII) ;
if ( !from ) {
std::cerr << "ERROR: Unable to to perform units conversion because the"
<< " units in the data recording file appear to be corrupt."
@ -72,7 +72,7 @@ DPC_UnitConvDataStream::DPC_UnitConvDataStream(DataStream* ds, const char *ToUni
}
} else { // The user has not specified a units conversion or the units were not valid.
// If the recorded data file doesn't contain the units in which the data is recorded ...
if ((recorded_units == NULL) || (strcmp(recorded_units,"") == 0)) {
if (recorded_units.empty()) {
// If the user didn't give us a hint as to what the units are (using var@from_units) ...
if ((FromUnitsHint == NULL) || (strcmp(FromUnitsHint,"") == 0)) {
cf = cv_get_trivial() ;

View File

@ -39,7 +39,7 @@ public:
/**
* Return the name of the X variable.
*/
const char *getXVarShortName() {
std::string getXVarShortName() {
return( x_var->getShortName() );
};
@ -53,7 +53,7 @@ public:
/**
* Return the name of the Y variable.
*/
const char *getYVarShortName() {
std::string getYVarShortName() {
return( y_var->getShortName() );
};

View File

@ -78,16 +78,16 @@ public:
}
/**
* Return the X-axis label of the plot, which may be NULL.
* Return the X-axis label of the plot, which may be empty.
*/
const char *getXLabel() {
std::string getXLabel() {
return( relation->getXAxisLabel());
}
/**
* Return the Y-axis label of the plot, which may be NULL.
* Return the Y-axis label of the plot, which may be empty.
*/
const char *getYLabel() {
std::string getYLabel() {
return( relation->getYAxisLabel());
}

View File

@ -106,9 +106,9 @@ DPC_std_curve::DPC_std_curve(
Time_constraints );
if (ds[0] != NULL) {
const char* ds_units = ds[0]->getUnit().c_str();
std::string ds_units = ds[0]->getUnit();
y_actual_units = strdup(ds_units);
y_actual_units = strdup(ds_units.c_str());
// Tell our DataStream to start at the beginning.
ds[0]->begin();

View File

@ -194,12 +194,12 @@ int DPC_table::getNumColumns() {
}
// MEMBER FUNCTION
const char *DPC_table::getColumnLabel(unsigned int index) {
std::string DPC_table::getColumnLabel(unsigned int index) {
DPM_column *column = table_spec->getColumn( index );
if ( column->getLabel() != NULL) {
return( column->getLabel());
} else {
return( column->getVar()->getShortName());
return( column->getVar()->getShortName() );
}
}

View File

@ -53,9 +53,9 @@ public:
int getNumColumns();
/**
* Return the Label (which may be NULL) of the of the indicated column.
* Return the Label (which may be empty) of the of the indicated column.
*/
const char *getColumnLabel(unsigned int index);
std::string getColumnLabel(unsigned int index);
/**
* Return the name of the variable for the indicated column.

View File

@ -231,57 +231,54 @@ const char * DPM_curve::getZVarName(unsigned int case_index) {
}
// MEMBER FUNCTION
const char * DPM_curve::getXCommonName() {
std::string DPM_curve::getXCommonName() {
const char *candidate_label;
const char *short_name;
std::string candidate_label;
int n_vars, i;
candidate_label = x_varcase_list[0]->getShortName();
n_vars = (int)x_varcase_list.size();
for (i=1; i<n_vars; i++) {
short_name = x_varcase_list[i]->getShortName();
if (strcmp( candidate_label, short_name) != 0 ) {
return (NULL);
if (candidate_label != x_varcase_list[i]->getShortName()) {
return ("");
}
}
return ( candidate_label);
return (candidate_label);
}
// MEMBER FUNCTION
const char * DPM_curve::getYCommonName() {
std::string DPM_curve::getYCommonName() {
const char *candidate_label;
const char *short_name;
std::string candidate_label;
int n_vars, i;
candidate_label = y_varcase_list[0]->getShortName();
n_vars = (int)y_varcase_list.size();
for (i=1; i<n_vars; i++) {
short_name = y_varcase_list[i]->getShortName();
if (strcmp( candidate_label, short_name) != 0 ) {
return (NULL);
if (candidate_label != y_varcase_list[i]->getShortName()) {
return ("");
}
}
return ( candidate_label);
}
// MEMBER FUNCTION
const char * DPM_curve::getZCommonName() {
std::string DPM_curve::getZCommonName() {
const char *candidate_label;
const char *short_name;
std::string candidate_label;
int n_vars, i;
candidate_label = z_varcase_list[0]->getShortName();
n_vars = (int)z_varcase_list.size();
for (i=1; i<n_vars; i++) {
short_name = z_varcase_list[i]->getShortName();
if (strcmp( candidate_label, short_name) != 0 ) {
return (NULL);
if (candidate_label != z_varcase_list[i]->getShortName()) {
return ("");
}
}
return ( candidate_label);
return (candidate_label);
}
// MEMBER FUNCTION

View File

@ -69,17 +69,17 @@ public:
/**
*
*/
const char * getXCommonName();
std::string getXCommonName();
/**
*
*/
const char * getYCommonName();
std::string getYCommonName();
/**
*
*/
const char * getZCommonName();
std::string getZCommonName();
/**
* Output an xml representation of DPM_curve.

View File

@ -148,90 +148,81 @@ int DPM_relation::NumberOfAxes() {
}
// MEMBER FUNCTION
const char * DPM_relation::getXAxisLabel() {
const char * candidate_label;
const char * short_name;
std::string DPM_relation::getXAxisLabel() {
std::string candidate_label;
int n_curves, i;
if (xaxis) {
candidate_label = xaxis->getLabel();
} else {
candidate_label = NULL;
candidate_label = "";
}
// If an Y-Axis label wasn't supplied, see if there is a common
// variable name that will serve as a label.
if (candidate_label == NULL) {
if (( candidate_label = curve_list[0]->getXCommonName() ) == NULL) {
return (NULL);
if (candidate_label == "") {
if (( candidate_label = curve_list[0]->getXCommonName() ) == "") {
return ("");
}
n_curves = (int)curve_list.size();
for (i=1; i<n_curves; i++) {
if (( short_name = curve_list[i]->getXCommonName() ) == NULL ) {
return (NULL);
}
if (strcmp( candidate_label, short_name) != 0 ) {
return (NULL);
}
if ( curve_list[i]->getXCommonName().empty() || candidate_label != curve_list[i]->getXCommonName()) {
return ("");
}
}
}
return (candidate_label);
}
// MEMBER FUNCTION
const char * DPM_relation::getYAxisLabel() {
const char * candidate_label;
const char * short_name;
std::string DPM_relation::getYAxisLabel() {
std::string candidate_label;
int n_curves, i;
if (yaxis) {
candidate_label = yaxis->getLabel();
} else {
candidate_label = NULL;
candidate_label = "";
}
// If an Y-Axis label wasn't supplied, see if there is a common
// variable name that will serve as a label.
if (candidate_label == NULL) {
if (( candidate_label = curve_list[0]->getYCommonName() ) == NULL) {
return (NULL);
if (candidate_label == "") {
if (( candidate_label = curve_list[0]->getYCommonName() ) == "") {
return ("");
}
n_curves = (int)curve_list.size();
for (i=1; i<n_curves; i++) {
if (( short_name = curve_list[i]->getYCommonName() ) == NULL ) {
return (NULL);
}
if (strcmp( candidate_label, short_name) != 0 ) {
return (NULL);
}
if (curve_list[i]->getYCommonName().empty() || candidate_label != curve_list[i]->getYCommonName()) {
return ("");
}
}
}
return (candidate_label);
}
// MEMBER FUNCTION
const char * DPM_relation::getZAxisLabel() {
const char * candidate_label;
const char * short_name;
std::string DPM_relation::getZAxisLabel() {
std::string candidate_label;
int n_curves, i;
if (zaxis) {
candidate_label = zaxis->getLabel();
} else {
candidate_label = NULL;
candidate_label = "";
}
// If an Z-Axis label wasn't supplied, see if there is a common
// variable name that will serve as a label.
if (candidate_label == NULL) {
if (( candidate_label = curve_list[0]->getZCommonName() ) == NULL) {
return (NULL);
if (candidate_label == "") {
if (( candidate_label = curve_list[0]->getZCommonName() ) == "") {
return ("");
}
n_curves = (int)curve_list.size();
for (i=1; i<n_curves; i++) {
if (( short_name = curve_list[i]->getZCommonName() ) == NULL ) {
return (NULL);
}
if (strcmp( candidate_label, short_name) != 0 ) {
return (NULL);
}
if (curve_list[i]->getZCommonName().empty() || candidate_label != curve_list[i]->getZCommonName()) {
return ("");
}
}
}
return (candidate_label);

View File

@ -53,9 +53,9 @@ public:
/**
*
*/
const char * getXAxisLabel();
const char * getYAxisLabel();
const char * getZAxisLabel();
std::string getXAxisLabel();
std::string getYAxisLabel();
std::string getZAxisLabel();
/**
*

View File

@ -40,7 +40,7 @@ const char* DPM_var::getName() {
return ( (const char*)name );
}
const char* DPM_var::getShortName() {
std::string DPM_var::getShortName() {
char *p;
std::string::size_type idx ;
@ -103,7 +103,7 @@ const char* DPM_var::getShortName() {
} else {
combinedName += " - " + paramName2;
}
return combinedName.c_str();
return combinedName;
}
}

View File

@ -43,7 +43,7 @@ class DPM_var:public DPM_component {
* Return the part of the variable name right of the last
* period or the name if there are no periods.
*/
const char *getShortName();
std::string getShortName();
/**
* Output an xml representation of DPM_var.

View File

@ -126,6 +126,7 @@ int DPV_TextBuffer::readFile( const char* fileName ) {
numRead = fread((char *) buf, fileSize, 1, fp);
if (numRead != 1) {
delete[]buf;
fclose(fp);
return (-1);
}
buf[fileSize] = '\0';

View File

@ -93,7 +93,7 @@ DPV_pointer test_view::create_table_view( DPV_pointer parent_data,
cout << "Number of Columns : " << n_columns << endl;
for (colix=0; colix < n_columns ; colix++) {
const char *col_label = table->getColumnLabel( colix);
const char *col_label = table->getColumnLabel( colix).c_str();
const char *var_name = table->getColumnVarName( colix);
const char *col_units = table->getColumnUnits( colix);
const char *format = table->getColumnAttribute( colix,"format");

View File

@ -138,7 +138,7 @@ DPV_pointer Test_view::render_table( DPV_pointer parent_data, DPC_table *table)
s << "Number of Columns: " << n_columns << std::endl;
for (colix=0; colix < n_columns ; colix++) {
if ((temp_cstr = table->getColumnLabel(colix)) != NULL) {
if ((temp_cstr = table->getColumnLabel(colix).c_str())[0] != '\0') {
s << "Column Label [" << colix << "]: " << temp_cstr << std::endl;
}
if ((temp_cstr = table->getColumnVarName(colix)) != NULL) {

View File

@ -6,7 +6,7 @@
<groupId>trick-java</groupId>
<artifactId>trick-java</artifactId>
<version>19.7.0-beta</version>
<version>19.8.0-beta</version>
<name>trick-java</name>

View File

@ -181,6 +181,9 @@ public class SimControlApplication extends TrickApplication implements PropertyC
final private static String LOCALHOST = "localhost";
final private Dimension FULL_SIZE = new Dimension(680, 640);
final private Dimension LITE_SIZE = new Dimension(340, 360);
//========================================
// Actions
//========================================
@ -314,9 +317,9 @@ public class SimControlApplication extends TrickApplication implements PropertyC
@Action
public void lite() {
if (liteButton.isSelected()) {
getMainFrame().setSize(340, 360);
getMainFrame().setSize(LITE_SIZE);
} else {
getMainFrame().setSize(680, 640);
getMainFrame().setSize(FULL_SIZE);
}
}
@ -341,28 +344,17 @@ public class SimControlApplication extends TrickApplication implements PropertyC
elements = selectedStr.split("\\s+");
}
Document doc = statusMsgPane.getDocument();
StyleContext sc = new StyleContext();
Style redStyle = sc.addStyle("Red", null);
setColorStyleAttr(redStyle, Color.red, Color.black);
if (elements == null || elements.length < 2) {
try {
doc.insertString(doc.getLength(), "Can't connect! Please provide valid host name and port number separated by : or whitespace!\n", redStyle);
} catch (BadLocationException ble) {
System.out.println("Can't connect! Please provide valid host name and port number separated by : or whitespace!");
}
if (elements == null || elements.length < 2) {
String errMsg = "Can't connect! Please provide valid host name and port number separated by : or whitespace!";
printErrorMessage(errMsg);
return;
}
host = elements[0].trim();
try {
port = Integer.parseInt(elements[1].trim());
} catch (NumberFormatException nfe) {
try {
doc.insertString(doc.getLength(), elements[1] + " is not a valid port number!\n", redStyle);
} catch (BadLocationException ble) {
System.out.println(elements[1] + " is not a valid port number!");
}
String errMsg = elements[1] + " is not a valid port number!";
printErrorMessage(errMsg);
return;
}
}
@ -370,9 +362,8 @@ public class SimControlApplication extends TrickApplication implements PropertyC
getInitializationPacket();
if (commandSimcom == null) {
JOptionPane.showMessageDialog(getMainFrame(),
"Sorry, can't connect. Please make sure the availability of both server and port!",
"Connection error", JOptionPane.ERROR_MESSAGE);
String errMsg = "Sorry, can't connect. Please make sure the availability of both server and port!";
printErrorMessage(errMsg);
return;
} else {
Object[] keys = actionMap.allKeys();
@ -411,6 +402,7 @@ public class SimControlApplication extends TrickApplication implements PropertyC
String simRunDir = null;
String[] results = null;
try {
String errMsg = "Error: SimControlApplication:getInitializationPacket()";
try {
if (host != null && port != -1) {
commandSimcom = new VariableServerConnection(host, port);
@ -419,16 +411,16 @@ public class SimControlApplication extends TrickApplication implements PropertyC
}
} catch (UnknownHostException host_exception) {
/** The IP address of the host could not be determined. */
System.out.println("Error: SimControlApplication:getInitializationPacket()");
System.out.println(" Unknown host \""+host+"\"");
System.out.println(" Please use a valid host name (e.g. localhost)");
errMsg += "\n Unknown host \""+host+"\"";
errMsg += "\n Please use a valid host name (e.g. localhost)";
printErrorMessage(errMsg);
} catch (IOException ioe) {
/** Port number is unavailable, or there is no connection, etc. */
System.out.println("Error: SimControlApplication:getInitializationPacket()");
System.out.println(" Invalid TCP/IP port number \""+port+"\"");
System.out.println(" Please check the server and enter a proper port number!");
System.out.println(" IOException ..." + ioe);
System.out.println(" If there is no connection, please make sure SIM is up running properly!");
errMsg += "\n Invalid TCP/IP port number \""+port+"\"";
errMsg += "\n Please check the server and enter a proper port number!";
errMsg += "\n IOException ..." + ioe;
errMsg += "\n If there is no connection, please make sure SIM is up running properly!";
printErrorMessage(errMsg);
}
if (commandSimcom == null) {
@ -618,9 +610,8 @@ public class SimControlApplication extends TrickApplication implements PropertyC
getAction(theKey).setEnabled(false);
}
}
JOptionPane.showMessageDialog(getMainFrame(),
"No server connection. Please connect!",
"No server connection", JOptionPane.ERROR_MESSAGE);
String errMsg = "No server connection. Please connect!";
printErrorMessage(errMsg);
return;
}
@ -656,6 +647,38 @@ public class SimControlApplication extends TrickApplication implements PropertyC
show(view);
}
/**
* Prints an error message to the status message pane. In the event there is an error with it, a JOptionPane will pop up.
* @param err
*/
protected void printErrorMessage(String err) {
try {
// Get the document attached to the Status Message Pane
Document doc = statusMsgPane.getDocument();
// Set the font color to red and the background to black
StyleContext sc = new StyleContext();
Style redStyle = sc.addStyle("Red", null);
setColorStyleAttr(redStyle, Color.red, Color.black);
// Add the error message to the bottom of the message pane
doc.insertString(doc.getLength(), err + "\n", redStyle);
// If Lite mode is engaged, or the window is small enough
// to obscure the message pane, create a popup for the error as well.
if (liteButton.isSelected() || getMainFrame().getSize().height <= LITE_SIZE.height + 50) {
JOptionPane.showMessageDialog(getMainFrame(), err, "Sim Control Panel Error", JOptionPane.ERROR_MESSAGE);
}
} catch (BadLocationException ble) {
JOptionPane.showMessageDialog(getMainFrame(),
"Status Message Pane had an issue when printing: " + err,
"Status Message Pane Error",
JOptionPane.ERROR_MESSAGE);
} catch (NullPointerException npe) {
System.err.println( "Sim Control Error at Initialization: \n" + err);
}
}
/**
* Main method for this application.
* @param args command line arguments
@ -765,7 +788,7 @@ public class SimControlApplication extends TrickApplication implements PropertyC
status_vars = "trick.var_add(\"trick_sys.sched.time_tics\") \n" +
"trick.var_add(\"trick_sys.sched.mode\") \n" +
"trick.var_add(\"trick_real_time.gtod_clock.rt_clock_ratio\") \n" +
"trick.var_add(\"trick_real_time.rt_sync.actual_run_ratio\") \n" +
"trick.var_add(\"trick_real_time.rt_sync.active\") \n";
if ( debug_present != 0 ) {
@ -1650,7 +1673,7 @@ public class SimControlApplication extends TrickApplication implements PropertyC
ii++ ;
}
// "real_time.gtod_clock.rt_clock_ratio"
// "real_time.rt_sync.actual_run_ratio"
if (results.length > ii && results[ii] != null && results[ii] != "") {
simState.setSimRealtimeRatio(Float.parseFloat(results[ii]));
ii++ ;

View File

@ -32,7 +32,7 @@ int Trick::Executive::init() {
/* Start the cpu usage meter */
struct rusage cpu_usage_buf ;
getrusage(RUSAGE_SELF, &cpu_usage_buf);
cpu_start = ((double) cpu_usage_buf.ru_utime.tv_sec) + ((double) cpu_usage_buf.ru_utime.tv_usec / 1000000.0);
user_cpu_start = ((double) cpu_usage_buf.ru_utime.tv_sec) + ((double) cpu_usage_buf.ru_utime.tv_usec / 1000000.0);
/* command line args */
process_sim_args();
@ -55,8 +55,15 @@ int Trick::Executive::init() {
/* Record the cpu usage for initialization */
getrusage(RUSAGE_SELF, &cpu_usage_buf);
cpu_time = ((double) cpu_usage_buf.ru_utime.tv_sec) + ((double) cpu_usage_buf.ru_utime.tv_usec / 1000000.0);
cpu_init = cpu_time - cpu_start;
user_cpu_init = cpu_time - user_cpu_start;
cpu_time = ((double) cpu_usage_buf.ru_stime.tv_sec) + ((double) cpu_usage_buf.ru_stime.tv_usec / 1000000.0);
kernal_cpu_init = cpu_time - kernal_cpu_start;
/* Record both voluntary and involuntary context switches usage for initialization */
v_context_switch_init = cpu_usage_buf.ru_nvcsw;
iv_context_switch_init = cpu_usage_buf.ru_nivcsw;
initialization_complete = true ;
/* Print as much error information avaiable for all exception and exit. */

View File

@ -36,13 +36,14 @@ int Trick::Executive::shutdown() {
double sim_elapsed_time;
double cpu_time;
double actual_cpu_time;
double user_cpu_time, kernal_cpu_time;
double sim_to_cpu;
unsigned int ii;
int process_id = 0 ;
struct rusage cpu_usage_buf ;
double sim_mem;
long v_context_switch_run, iv_context_switch_run;
SIM_MODE prev_mode = mode ;
/* Set mode to ExitMode. */
@ -92,29 +93,48 @@ int Trick::Executive::shutdown() {
/* Calculate simulation elapsed sim time and actual cpu time */
sim_elapsed_time = get_sim_time() - sim_start;
actual_cpu_time = cpu_time - cpu_start;
if (actual_cpu_time <= 1e-6) {
user_cpu_time = cpu_time - user_cpu_start;
/* */
cpu_time = ((double) cpu_usage_buf.ru_stime.tv_sec) + ((double) cpu_usage_buf.ru_stime.tv_usec / 1000000.0);
kernal_cpu_time = cpu_time - kernal_cpu_start;
if ((user_cpu_time + kernal_cpu_time) <= 1e-6) {
sim_to_cpu = 1e8;
} else {
sim_to_cpu = sim_elapsed_time / actual_cpu_time;
sim_to_cpu = sim_elapsed_time / (user_cpu_time + kernal_cpu_time);
}
/* Calculate voluntary and involuntary context switch usage during run */
v_context_switch_run = cpu_usage_buf.ru_nvcsw - v_context_switch_init ;
iv_context_switch_run = cpu_usage_buf.ru_nivcsw - iv_context_switch_init ;
/* Print a shutdown message. */
message_publish(MSG_NORMAL , "\n"
"SIMULATION TERMINATED IN\n"
" PROCESS: %d\n"
" ROUTINE: %s\n"
" DIAGNOSTIC: %s\n\n"
" SIMULATION START TIME: %12.3f\n"
" SIMULATION STOP TIME: %12.3f\n"
" SIMULATION ELAPSED TIME: %12.3f\n"
" ACTUAL CPU TIME USED: %12.3f\n"
" SIMULATION / CPU TIME: %12.3f\n"
" INITIALIZATION CPU TIME: %12.3f\n"
" SIMULATION RAM USAGE: %12.3fMB\n"
" (External program RAM usage not included!)\n",
process_id, except_file.c_str(), except_message.c_str() ,
sim_start , get_sim_time() , sim_elapsed_time , actual_cpu_time , sim_to_cpu , cpu_init, sim_mem ) ;
" SIMULATION START TIME: %12.3f\n"
" SIMULATION STOP TIME: %12.3f\n"
" SIMULATION ELAPSED TIME: %12.3f\n"
" USER CPU TIME USED: %12.3f\n"
" SYSTEM CPU TIME USED: %12.3f\n"
" SIMULATION / CPU TIME: %12.3f\n"
" INITIALIZATION USER CPU TIME: %12.3f\n"
" INITIALIZATION SYSTEM CPU TIME: %12.3f\n"
" SIMULATION RAM USAGE: %12.3fMB\n"
" (External program RAM usage not included!)\n"
" VOLUNTARY CONTEXT SWITCHES (INIT): %12ld\n"
"INVOLUNTARY CONTEXT SWITCHES (INIT): %12ld\n"
" VOLUNTARY CONTEXT SWITCHES (RUN): %12ld\n"
" INVOLUNTARY CONTEXT SWITCHES (RUN): %12ld\n\n",
process_id, except_file.c_str(), except_message.c_str(),
sim_start, get_sim_time(), sim_elapsed_time,
user_cpu_time, kernal_cpu_time, sim_to_cpu,
user_cpu_init, kernal_cpu_init, sim_mem,
v_context_switch_init, iv_context_switch_init,
v_context_switch_run, iv_context_switch_run) ;
/* Kill all threads. */
for (ii = 1; ii < threads.size() ; ii++) {

View File

@ -21,6 +21,7 @@
#ifdef __APPLE__
#include <mach-o/dyld.h>
#include <execinfo.h>
#endif
#include "trick/Executive.hh"
@ -69,6 +70,37 @@ void Trick::Executive::signal_handler(int sig) {
"/proc/%d/exe %d", debugger_command.c_str(), getpid(), getpid());
system(command);
}
//=========================================================================================`
#elif __APPLE__
char command[2048];
char path[1024] ;
uint32_t size = sizeof(path) ;
if (_NSGetExecutablePath(path, &size) == 0 ) {
if (attach_debugger == true) {
snprintf(command, sizeof(command),
"NOTICE!! An instance of LLDB is started and keeping your simulation\n"
"executable suspended. LLDB has not, and cannot attach to your simulation\n"
"(i.e., its parent process) without it and your sim being killed\n"
"by Apple's `System Integrity Protection` (SIP) (presumably for security\n"
"reasons). You may be able to attach LLDB to your suspended simulation\n"
"from a different terminal (an independent process) with: $ lldb -p %d \n\n", getpid());
write( 2, command, strlen(command));
snprintf(command, sizeof(command),
"Note that this may also require the apppropriate `elevated privileges` or that\n"
"your sim executable is code signed (using Apple's codesign utility.)\n");
write( 2, command, strlen(command));
snprintf(command, sizeof(command), "%s", debugger_command.c_str());
system(command);
} else if (stack_trace == true ) {
write( 2 , "=============\n" , 14 ) ;
write( 2 , " STACK TRACE \n" , 14 ) ;
write( 2 , "=============\n" , 14 ) ;
void* callstack[128];
int frames = backtrace(callstack, 128);
backtrace_symbols_fd(callstack, frames, 2); // 1 = stdout 2 = stderr
}
}
//=========================================================================================
#endif
}

View File

@ -54,6 +54,9 @@ int Trick::Executive::write_s_job_execution(FILE *fp) {
}
}
fprintf(fp, "Executive time tic value (tics/second) information\n");
fprintf(fp, " time tic value = %d\n\n", time_tic_value);
fprintf(fp, "Thread information\n");
for ( ii = 0 ; ii < threads.size() ; ii++ ) {
std::stringstream oss ;

View File

@ -40,9 +40,11 @@ void Trick::Threads::clear_scheduled_queues() {
void Trick::Threads::dump( std::ostream & oss ) {
oss << "Trick::Threads (" << name << ")" << std::endl ;
oss << " process_type = " ;
// Regardless of type, amf_cycle is used to store the cycle time set.
// If thread_id is 0 which means main thread, amf_cycle can't be set so the init value 0 will be dumped.
switch ( process_type ) {
case PROCESS_TYPE_SCHEDULED: oss << "scheduled" << std::endl ; break ;
case PROCESS_TYPE_ASYNC_CHILD: oss << "asynchronous" << std::endl ; break ;
case PROCESS_TYPE_SCHEDULED: oss << "scheduled = " << amf_cycle << std::endl ; break ;
case PROCESS_TYPE_ASYNC_CHILD: oss << "asynchronous = " << amf_cycle << std::endl ; break ;
case PROCESS_TYPE_AMF_CHILD: oss << "asynchronous must finish with amf_cycle = " << amf_cycle << std::endl ; break ;
}
trigger_container.getThreadTrigger()->dump(oss) ;

View File

@ -35,6 +35,7 @@ int Trick::FrameDataRecordGroup::frame_log_clear() {
std::vector< Trick::JobData *>::iterator it ;
for ( it = rec_jobs.begin() ; it != rec_jobs.end() ; it++ ) {
(*it)->frame_time = 0 ;
(*it)->frame_time_seconds = 0.0;
}
return 0 ;
@ -93,6 +94,7 @@ void Trick::FrameDataRecordGroup::start_timer() {
*/
void Trick::FrameDataRecordGroup::stop_timer() {
frame_sched_time = clock_time() - start_time ;
frame_time = frame_sched_time * (1.0/exec_get_time_tic_value());
}
void Trick::FrameDataRecordGroup::adjust_time() {

View File

@ -36,8 +36,8 @@ Trick::FrameLog::FrameLog(Trick::Clock & in_clock) :
fp_time_other(NULL),
clock(in_clock) {
time_value_attr.type = TRICK_LONG_LONG ;
time_value_attr.size = sizeof(long long) ;
time_value_attr.type = TRICK_DOUBLE;
time_value_attr.size = sizeof(double);
time_value_attr.units = strdup("s") ;
the_fl = this ;
@ -144,7 +144,7 @@ void Trick::FrameLog::add_recording_vars_for_jobs() {
}
new_ref->reference = job_name;
new_ref->address = &(all_jobs_vector[ii]->frame_time) ;
new_ref->address = &(all_jobs_vector[ii]->frame_time_seconds) ;
new_ref->attr = &time_value_attr ;
/** @li use TRK tag in S_define to identify trick jobs */
// trick jobs
@ -184,7 +184,7 @@ void Trick::FrameLog::add_recording_vars_for_jobs() {
if ( ii > 0 ) {
std::ostringstream group_name ;
group_name << "trick_frame_userjobs_C" << ii ;
(*fdrg_it)->add_variable( group_name.str() + ".frame_sched_time") ;
(*fdrg_it)->add_variable( group_name.str() + ".frame_time") ;
}
}
drg_trick->set_job_class("end_of_frame") ;
@ -205,8 +205,8 @@ void Trick::FrameLog::add_recording_vars_for_frame() {
char * job_name = NULL ;
int ii ;
drg_frame->add_variable(rt_sim_object_name + std::string(".rt_sync.frame_sched_time")) ;
drg_frame->add_variable(rt_sim_object_name + std::string(".rt_sync.frame_overrun_time")) ;
drg_frame->add_variable(rt_sim_object_name + std::string(".rt_sync.frame_time")) ;
drg_frame->add_variable(rt_sim_object_name + std::string(".rt_sync.frame_overrun")) ;
/* add the log_userjob frame time we created above to the log_frame group */
for ( ii = 0 ; ii < num_threads ; ii++ ) {
@ -220,7 +220,7 @@ void Trick::FrameLog::add_recording_vars_for_frame() {
}
trick_jobs.push_back(std::string(job_name));
new_ref->reference = job_name;
new_ref->address = &(drg_users[ii]->write_job->frame_time);
new_ref->address = &(drg_users[ii]->write_job->frame_time_seconds);
new_ref->attr = &time_value_attr ;
drg_frame->add_variable(new_ref) ;
drg_frame->add_rec_job(drg_users[ii]->write_job) ;
@ -231,7 +231,7 @@ void Trick::FrameLog::add_recording_vars_for_frame() {
asprintf(&job_name, "JOB_data_record_group.trickjobs.%2.2f(end_of_frame)",drg_trick->jobs[0]->frame_id);
trick_jobs.push_back(std::string(job_name));
new_ref->reference = job_name;
new_ref->address = &(drg_trick->write_job->frame_time);
new_ref->address = &(drg_trick->write_job->frame_time_seconds);
new_ref->attr = &time_value_attr ;
drg_frame->add_variable(new_ref) ;
drg_frame->add_rec_job(drg_trick->write_job) ;
@ -360,13 +360,16 @@ int Trick::FrameLog::frame_clock_stop(Trick::JobData * curr_job) {
Trick::JobData * target_job = (Trick::JobData *)curr_job->sup_class_data ;
int thread, mode;
double time_scale;
/** @par Detailed Design: */
if ( target_job != NULL ) {
if ( target_job->rt_start_time >= 0 ) {
/** @li Set current job's stop time and frame time. */
target_job->rt_stop_time = clock.clock_time() ;
time_scale = 1.0 / target_job->time_tic_value;
target_job->frame_time += (target_job->rt_stop_time - target_job->rt_start_time);
target_job->frame_time_seconds = target_job->frame_time * time_scale;
thread = target_job->thread;
mode = exec_get_mode();
@ -405,6 +408,7 @@ int Trick::FrameLog::frame_clock_stop(Trick::JobData * curr_job) {
target_job->rt_stop_time = 0;
} else {
target_job->frame_time = 0 ;
target_job->frame_time_seconds = 0.0;
}
}
@ -496,6 +500,8 @@ void Trick::FrameLog::default_data() {
allocate_recording_groups() ;
add_recording_vars_for_jobs() ;
add_recording_vars_for_frame() ;
// reset clock before frame logging
clock.clock_reset(0);
}
/**
@ -739,14 +745,12 @@ int Trick::FrameLog::create_DP_job_files() {
FILE *fpx;
unsigned int pages, plots, total_plots, vcells, dot;
char *bg_color;
double time_scale;
std::string DP_buff;
const char *headerx = "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n" \
"<!DOCTYPE product PUBLIC \"-//Tricklab//DTD Product V1.0//EN\" \"Product.dtd\">\n\n" \
"<!-- Description: Plot of Y(t) vs. t, with attributes, titles, labels, units -->\n\n" \
"<product version=\"1.0\">\n";
time_scale = 1.0 / exec_get_time_tic_value();
DP_buff = DP_dir + "/DP_rt_frame.xml";
if ((fpx = fopen(DP_buff.c_str(), "w")) == NULL) {
message_publish(MSG_WARNING, "Could not open DP_rt_frame.xml file for Frame Logging\n") ;
@ -758,16 +762,14 @@ int Trick::FrameLog::create_DP_job_files() {
fprintf(fpx, " <xaxis> <label>Time</label> <units>s</units> </xaxis>\n");
fprintf(fpx, " <yaxis> <label>Frame Overrun/Underrun</label> </yaxis>\n");
fprintf(fpx, " <curve>\n <var>sys.exec.out.time</var>\n");
fprintf(fpx, " <var scale=\"%g\" line_color=\"darkgreen\" label=\"Overrun/Underrun\">%s.rt_sync.frame_overrun_time</var>\n",
time_scale,rt_sim_object_name.c_str());
fprintf(fpx, " <var line_color=\"darkgreen\" label=\"Overrun/Underrun\">%s.rt_sync.frame_overrun</var>\n", rt_sim_object_name.c_str());
fprintf(fpx, " </curve>\n");
fprintf(fpx, " </plot>\n");
fprintf(fpx, " <plot grid=\"yes\">\n <title>Frame Scheduled Jobs Time</title>\n");
fprintf(fpx, " <xaxis> <label>Time</label> <units>s</units> </xaxis>\n");
fprintf(fpx, " <yaxis> <label>Frame Scheduled Jobs Time</label> </yaxis>\n");
fprintf(fpx, " <curve>\n <var>sys.exec.out.time</var>\n");
fprintf(fpx, " <var scale=\"%g\" line_color=\"red\" label=\"Frame Sched Time\">%s.rt_sync.frame_sched_time</var>\n",
time_scale,rt_sim_object_name.c_str());
fprintf(fpx, " <var line_color=\"red\" label=\"Frame Sched Time\">%s.rt_sync.frame_time</var>\n", rt_sim_object_name.c_str());
fprintf(fpx, " </curve>\n");
fprintf(fpx, " </plot>\n");
fprintf(fpx, " </page>\n");
@ -796,8 +798,7 @@ int Trick::FrameLog::create_DP_job_files() {
fprintf(fpx, " <var>sys.exec.out.time</var>\n");
std::ostringstream group_name ;
group_name << "trick_frame_userjobs_C" << (page_count * plots_per_page + ii + 1) ;
fprintf(fpx, " <var scale=\"%g\" line_color=\"red\" label=\"Frame Sched Time\">%s.frame_sched_time</var>\n",
time_scale,group_name.str().c_str());
fprintf(fpx, " <var line_color=\"red\" label=\"Frame Sched Time\">%s.frame_time</var>\n", group_name.str().c_str());
fprintf(fpx, " </curve>\n");
fprintf(fpx, " </plot>\n");
}
@ -809,12 +810,10 @@ int Trick::FrameLog::create_DP_job_files() {
fprintf(fpx, " <label>Sim Time</label>\n <var>sys.exec.out.time</var>\n");
fprintf(fpx, " </column>\n");
fprintf(fpx, " <column format=\"%%13.6f\">\n");
fprintf(fpx, " <label>Overrun/Underrun</label>\n <var scale=\"%g\">%s.rt_sync.frame_overrun_time</var>\n",
time_scale,rt_sim_object_name.c_str());
fprintf(fpx, " <label>Overrun/Underrun</label>\n <var>%s.rt_sync.frame_overrun</var>\n", rt_sim_object_name.c_str());
fprintf(fpx, " </column>\n");
fprintf(fpx, " <column format=\"%%13.6f\">\n");
fprintf(fpx, " <label>Frame Sched Time</label>\n <var scale=\"%g\">%s.rt_sync.frame_sched_time</var>\n",
time_scale,rt_sim_object_name.c_str());
fprintf(fpx, " <label>Frame Sched Time</label>\n <var>%s.rt_sync.frame_time</var>\n", rt_sim_object_name.c_str());
fprintf(fpx, " </column>\n");
fprintf(fpx, " </table>\n</product>");
fclose(fpx);
@ -861,7 +860,7 @@ int Trick::FrameLog::create_DP_job_files() {
fprintf(fpx, " <xaxis> <label>Time</label> <units>s</units> </xaxis>\n");
fprintf(fpx, " <yaxis> <label>Execution Time</label> </yaxis>\n");
fprintf(fpx, " <curve>\n <var>sys.exec.out.time</var>\n");
fprintf(fpx, " <var line_color=\"red\" scale=\"%g\">%s</var>\n", time_scale, (*drb_it)->name.c_str());
fprintf(fpx, " <var line_color=\"red\">%s</var>\n", (*drb_it)->name.c_str());
fprintf(fpx, " </curve>\n");
fprintf(fpx, " </plot>\n");
plots++;
@ -919,7 +918,7 @@ int Trick::FrameLog::create_DP_job_files() {
fprintf(fpx, " <xaxis> <label>Time</label> <units>s</units> </xaxis>\n");
fprintf(fpx, " <yaxis> <label>Execution Time</label> </yaxis>\n");
fprintf(fpx, " <curve>\n <var>sys.exec.out.time</var>\n");
fprintf(fpx, " <var line_color=\"darkgreen\" scale=\"%g\">%s</var>\n", time_scale, (*job_iterator).c_str());
fprintf(fpx, " <var line_color=\"darkgreen\">%s</var>\n", (*job_iterator).c_str());
fprintf(fpx, " </curve>\n");
fprintf(fpx, " </plot>\n");
job_iterator++;

View File

@ -140,6 +140,11 @@ int Trick::IPPython::init() {
}
if ( verify_input ) {
std::stringstream ss ;
ss << "import hashlib" << std::endl ;
ss << "input_file = " << "'" << input_file.c_str() << "'" << std::endl;
ss << "print('{0} SHA1: {1}'.format(input_file,hashlib.sha1(open(input_file, 'rb').read()).hexdigest()))" << std::endl ;
PyRun_SimpleString(ss.str().c_str()) ;
exec_terminate_with_return(ret , __FILE__ , __LINE__ , "Input file verification complete\n" ) ;
}

View File

@ -556,9 +556,8 @@ int Trick::IntegLoopScheduler::process_dynamic_events ( double t_start, double t
if (status != 0) { return status; }
status = process_dynamic_events(t_from, t_to, depth+1);
if (status != 0) { return status; }
} else {
return 0;
}
return 0;
}
/**

View File

@ -89,8 +89,8 @@ Trick::MemoryManager::~MemoryManager() {
io_src_delete_class( ai_ptr );
}
}
free(ai_ptr->name);
free(ai_ptr->user_type_name);
if (ai_ptr->name) { free(ai_ptr->name); }
if (ai_ptr->user_type_name) { free(ai_ptr->user_type_name); }
free(ai_ptr) ;
}
alloc_info_map.clear() ;

View File

@ -46,6 +46,7 @@ void* Trick::MemoryManager::declare_var( TRICK_TYPE type,
char* allocation_name;
int n_elems;
Language language;
TRICK_ALLOC_TYPE allocation_type;
void* address;
ATTRIBUTES* sub_attr;
ALLOC_INFO *new_alloc;
@ -126,6 +127,8 @@ void* Trick::MemoryManager::declare_var( TRICK_TYPE type,
return ((void*)NULL);
}
language = Language_CPP;
/* io_src_allocate_class allocates objects using calloc (only). */
allocation_type = TRICK_ALLOC_MALLOC;
} else if ((type == TRICK_STRING) && (n_stars == 0 ) ) {
@ -157,6 +160,7 @@ void* Trick::MemoryManager::declare_var( TRICK_TYPE type,
new_alloc->size = size;
new_alloc->language = language;
new_alloc->type = type;
new_alloc->alloc_type = allocation_type;
if ((type == TRICK_STRUCTURED) || (type == TRICK_ENUMERATED)) {
new_alloc->user_type_name = strdup( user_type_name.c_str());

View File

@ -38,6 +38,9 @@ int Trick::MemoryManager::delete_var(void* address ) {
*/
if ( alloc_info->stcl == TRICK_LOCAL ) {
if ( alloc_info->alloc_type == TRICK_ALLOC_MALLOC ) {
// This will call a destructor ONLY if alloc_info->type is TRICK_STRUCTURED.
// Otherwise it does nothing.
io_src_destruct_class( alloc_info );
// The destructor that we just called MAY have deleted addresses

View File

@ -0,0 +1,13 @@
/*
PURPOSE: (Testing)
*/
#include <stddef.h>
class CountMe {
public:
int a;
static size_t count;
CountMe() { count ++; }
~CountMe() { count --; }
} ;

View File

@ -3,6 +3,8 @@
#include "trick/MemoryManager.hh"
#include "MM_test.hh"
#include <iostream>
#include "MM_delete_var.hh"
size_t CountMe::count = 0;
/*
Test Fixture.
@ -21,6 +23,27 @@ class MM_delete_var_unittest : public ::testing::Test {
================================================================================
*/
TEST_F(MM_delete_var_unittest, CXX_object_constructor_destructor) {
// ===========================================================================================
// This test determines:
// 1) whether a class's constructor is called when declare_var is called and,
// 2) whether a class's destructor is being called when delete_var is called.
// ===========================================================================================
EXPECT_TRUE(std::is_pod<CountMe>::value == false);
EXPECT_EQ(0, CountMe::count);
CountMe* cm1_p = (CountMe*)memmgr->declare_var("CountMe cm1");
EXPECT_EQ(1, CountMe::count);
CountMe* cm2_p = (CountMe*)memmgr->declare_var("CountMe cm2");
EXPECT_EQ(2, CountMe::count);
memmgr->delete_var("cm1");
EXPECT_EQ(1, CountMe::count);
memmgr->delete_var("cm2");
EXPECT_EQ(0, CountMe::count);
}
TEST_F(MM_delete_var_unittest, var_exists) {
int exists;

View File

@ -58,7 +58,8 @@ io_headers = MM_user_defined_types.hh \
MM_write_checkpoint.hh \
MM_get_enumerated.hh \
MM_ref_name_from_address.hh \
MM_stl_testbed.hh
MM_stl_testbed.hh \
MM_delete_var.hh
# List of .cpp files produced by ICG from the io_headers.
io_source = $(patsubst %.hh,io_%.cpp,$(io_headers))
@ -119,6 +120,7 @@ $(TESTS) : %: %.o
# ----------------------------------------------------------------------------------
# The following unittest programs are also dependent on the indicated object files.
# ----------------------------------------------------------------------------------
MM_delete_var_unittest : io_MM_delete_var.o
MM_declare_var_unittest : io_MM_user_defined_types.o
MM_declare_var_2_unittest : io_MM_user_defined_types.o
MM_declare_extern_var_unittest : io_MM_user_defined_types.o

View File

@ -441,7 +441,7 @@ MonteCarloMaster::collate_meta_data()
// Capture and alphabetize all variable names with their respective variable
// type; count the number of each type.
std::list< std::string > variable_names;
std::list< std::string > variable_details;
std::list< std::string > exec_file_names;
std::list< std::pair < unsigned int, std::string> > random_variables;
unsigned int count_calc = 0;
@ -456,27 +456,27 @@ MonteCarloMaster::collate_meta_data()
// Unreachable case in current implementation.
// All current variable classes have been given a "type"
default:
variable_names.push_back (var_it->get_variable_name() + ", Undefined_type");
variable_details.push_back(var_it->summarize_variable());
count_undef++;
break;
case MonteCarloVariable::Calculated:
variable_names.push_back (var_it->get_variable_name() + ", Calculated");
variable_details.push_back (var_it->summarize_variable());
count_calc++;
break;
case MonteCarloVariable::Constant:
variable_names.push_back (var_it->get_variable_name() + ", Constant");
variable_details.push_back (var_it->summarize_variable());
count_const++;
break;
case MonteCarloVariable::Execute:
exec_file_names.push_back (var_it->get_variable_name());
exec_file_names.push_back (var_it->summarize_variable());
count_exec++;
break;
case MonteCarloVariable::Prescribed:
variable_names.push_back (var_it->get_variable_name() + ", Prescribed");
variable_details.push_back (var_it->summarize_variable());
count_presc++;
break;
case MonteCarloVariable::Random:
variable_names.push_back (var_it->get_variable_name() + ", Random");
variable_details.push_back (var_it->summarize_variable());
count_rand++;
std::pair< unsigned int, std::string> var(var_it->get_seed(),
var_it->get_variable_name());
@ -484,7 +484,7 @@ MonteCarloMaster::collate_meta_data()
break;
}
}
variable_names.sort();
variable_details.sort();
meta_data <<
"\n\n*************************** SUMMARY **************************\n" <<
@ -497,8 +497,8 @@ MonteCarloMaster::collate_meta_data()
count_undef << " variables of undefined type" <<
"\n\n********************* LIST OF VARIABLES, TYPES****************\n";
std::list< std::string >::iterator var_name_it = variable_names.begin();
for (; var_name_it != variable_names.end(); ++var_name_it) {
std::list< std::string >::iterator var_name_it = variable_details.begin();
for (; var_name_it != variable_details.end(); ++var_name_it) {
meta_data << (*var_name_it) << "\n";
}
meta_data <<

View File

@ -116,3 +116,48 @@ MonteCarloVariable::generate_command()
{
command = "\n" + variable_name + " = " + assignment;
}
/*****************************************************************************
get_type_str
Purpose:(Return the type of this variable as string. Meant to be overridden
by derived classes)
*****************************************************************************/
std::string MonteCarloVariable::get_type_str() const
{
switch (get_type()) {
// Unreachable case in current implementation.
// All current variable classes have been given a "type"
default:
return(std::string("Undefined_type"));
break;
case MonteCarloVariable::Calculated:
return(std::string("Calculated"));
break;
case MonteCarloVariable::Constant:
return(std::string("Constant"));
break;
case MonteCarloVariable::Execute:
return(std::string("Execute"));
break;
case MonteCarloVariable::Prescribed:
return(std::string("Prescribed"));
break;
case MonteCarloVariable::Random:
return(std::string("Random"));
break;
}
}
/*****************************************************************************
summarize_variable
Purpose:(Provide a string summarizing the attributes of this MonteCarloVariable)
*****************************************************************************/
std::string MonteCarloVariable::summarize_variable() const
{
std::ostringstream ss;
ss << variable_name << std::string(": type=") << get_type_str();
return (ss.str());
}

View File

@ -271,3 +271,17 @@ bool MonteCarloVariableFile::sort_by_col_num(
{
return left->get_column_number() < right->get_column_number();
}
/*****************************************************************************
summarize_variable
Purpose:(Provide a string summarizing the attributes of this MonteCarloVariable)
*****************************************************************************/
std::string MonteCarloVariableFile::summarize_variable() const
{
std::ostringstream ss;
ss << MonteCarloVariable::summarize_variable()
<< ", max_skip=" << max_skip << ", is_dependent=" << is_dependent
<< ", filename=" << filename << ", column_number=" << column_number
<< ", first_column_number=" << first_column_number;
return (ss.str());
}

View File

@ -16,6 +16,7 @@ PROGRAMMERS:
#include <limits>
#include <algorithm>
#include <assert.h>
#include <sstream> // ostringstream
/*****************************************************************************
Constructor
@ -105,6 +106,19 @@ MonteCarloVariableRandomNormal::generate_assignment()
assign_double(assignment_d);
}
/*****************************************************************************
summarize_variable
Purpose:(Provide a string summarizing the attributes of this MonteCarloVariable)
*****************************************************************************/
std::string MonteCarloVariableRandomNormal::summarize_variable() const
{
std::ostringstream ss;
ss << MonteCarloVariable::summarize_variable() << std::string(", dispersion=Normal")
<< ", mean=" << distribution.mean() << ", stddev=" << distribution.stddev()
<< ", min_value=" << min_value << ", max_value=" << max_value
<< ", seed=" << seed_m;
return (ss.str());
}
/*****************************************************************************
truncate
Purpose:(Truncates the normal distribution to be within +- limit.)

View File

@ -8,6 +8,10 @@ PROGRAMMERS:
(((Gary Turner) (OSR) (October 2019) (Antares) (Initial)))
(((Isaac Reaves) (NASA) (November 2022) (Integration into Trick Core)))
**********************************************************************/
#include <sstream> // ostringstream
#include "trick/message_type.h"
#include "trick/message_proto.h"
#include "trick/exec_proto.h"
#include "trick/mc_variable_random_string.hh"
/*****************************************************************************
@ -32,14 +36,47 @@ Purpose:(pick one string at random)
void
MonteCarloVariableRandomStringSet::generate_assignment()
{
// generate a random number on the interval [0,1)
double pre_ix = distribution(random_generator);
// convert to an integer between 0 and max-index of the "values" vector.
size_t ix = static_cast<size_t> (pre_ix * values.size());
// send the string at that index to the command-generation.
assignment = values[ix];
generate_command();
// Protect against accessing 0th index of an empty list. In this case,
// generate_command() is never called
if (values.size() > 0) {
// generate a random number on the interval [0,1)
double pre_ix = distribution(random_generator);
// convert to an integer between 0 and max-index of the "values" vector.
size_t ix = static_cast<size_t> (pre_ix * values.size());
// send the string at that index to the command-generation.
// TODO: This fales if values.size() is zero!!!
assignment = values[ix];
generate_command();
} else {
std::string message =
std::string("File: ") + __FILE__ + ", Line: " +
std::to_string(__LINE__) + ", No values for MonteCarloVariableRandomStringSet\n"
"Length of values vector is zero for variable: " + variable_name + ", Did " +
"you forget to call add_string()?\n";
message_publish(MSG_WARNING, message.c_str());
}
}
/*****************************************************************************
summarize_variable
Purpose:(Provide a string summarizing the attributes of this MonteCarloVariable)
*****************************************************************************/
std::string MonteCarloVariableRandomStringSet::summarize_variable() const
{
std::ostringstream ss;
// TODO: Here we create a string in [val1, val2, ... ] form, but this is
// ambigious because if there's a comma in any value, parsing the resultant
// string from the MonteCarlo_Meta_data_output file could fail. What delimter
// or approach would be better? -Jordan 10/2023
ss << MonteCarloVariableRandomUniform::summarize_variable() << ", values=[";
if (values.size() > 0) {
for (auto val_it : values) {
ss << val_it << ",";
}
}
ss << "]";
return (ss.str());
}
/*****************************************************************************
add_string
Purpose:(Adds an option to the set of strings)
@ -64,3 +101,4 @@ MonteCarloVariableRandomStringSet::add_string( std::string new_string)
{
values.push_back(new_string);
}

View File

@ -7,6 +7,7 @@ PROGRAMMERS:
(((Gary Turner) (OSR) (October 2019) (Antares) (Initial)))
(((Isaac Reaves) (NASA) (November 2022) (Integration into Trick Core)))
**********************************************************************/
#include <sstream> // ostringstream
#include "trick/mc_variable_random_uniform.hh"
/*****************************************************************************
@ -33,6 +34,18 @@ MonteCarloVariableRandomUniform::generate_assignment()
assign_double(distribution(random_generator));
}
/*****************************************************************************
summarize_variable
Purpose:(Provide a string summarizing the attributes of this MonteCarloVariable)
*****************************************************************************/
std::string MonteCarloVariableRandomUniform::summarize_variable() const
{
std::ostringstream ss;
ss << MonteCarloVariable::summarize_variable() << std::string(", dispersion=Uniform")
<< ", min_value=" << distribution.min() << ", max_value=" << distribution.max()
<< ", seed=" << seed_m;
return (ss.str());
}
@ -59,3 +72,15 @@ MonteCarloVariableRandomUniformInt::generate_assignment()
{
assign_int(distribution(random_generator));
}
/*****************************************************************************
summarize_variable
Purpose:(Provide a string summarizing the attributes of this MonteCarloVariable)
*****************************************************************************/
std::string MonteCarloVariableRandomUniformInt::summarize_variable() const
{
std::ostringstream ss;
ss << MonteCarloVariable::summarize_variable() << std::string(" dispersion=Uniform,")
<< " min_value=" << distribution.min() << ", max_value=" << distribution.max()
<< ", seed=" << seed_m;
return (ss.str());
}

View File

@ -9,6 +9,7 @@ PROGRAMMERS:
#include <iostream>
#include <sstream>
#include <iomanip>
#include <cmath>
#include "trick/RealtimeSync.hh"
#include "trick/exec_proto.h"
#include "trick/sim_mode.h"
@ -48,6 +49,8 @@ Trick::RealtimeSync::RealtimeSync( Trick::Clock * in_clock , Trick::Timer * in_t
sim_end_init_time = 0 ;
sim_end_time = 0 ;
actual_run_ratio = 0.0;
the_rts = this ;
}
@ -250,6 +253,33 @@ int Trick::RealtimeSync::start_realtime(double in_frame_time , long long ref_tim
return(0) ;
}
template <size_t N>
class Run_Ratio {
public:
Run_Ratio() : num_samples(0) {}
Run_Ratio& operator()(long long sample, double in_rt_ratio)
{
samples[num_samples++ % N] = sample;
rt_ratio = in_rt_ratio;
return *this;
}
operator double() const {
if ( num_samples <= 1 ) {
return 0.0 ;
} else if ( num_samples < N ) {
return round(exec_get_software_frame() * (num_samples-1) * exec_get_time_tic_value() * rt_ratio / (double)(samples[num_samples - 1] - samples[0])*100.0)/100.0 ;
} else {
return round(exec_get_software_frame() * (N-1) * exec_get_time_tic_value() * rt_ratio / (double)(samples[(num_samples - 1) % N] - samples[num_samples % N])*100.0)/100.0 ;
}
}
private:
long long samples[N];
size_t num_samples;
double rt_ratio;
};
/**
@details
-# If real-time is not active:
@ -282,10 +312,13 @@ int Trick::RealtimeSync::rt_monitor(long long sim_time_tics) {
long long curr_clock_time ;
char buf[512];
static Run_Ratio<100> run_ratio ;
/* calculate the current underrun/overrun */
curr_clock_time = rt_clock->clock_time() ;
frame_sched_time = curr_clock_time - last_clock_time ;
frame_time = frame_sched_time * (1.0/tics_per_sec);
/* Set the next frame overrun/underrun reference time to the current time */
last_clock_time = curr_clock_time ;
@ -299,6 +332,8 @@ int Trick::RealtimeSync::rt_monitor(long long sim_time_tics) {
if ( disable_flag ) {
disable_flag = false ;
}
/* calculate run ratio in non-realtime mode */
actual_run_ratio = run_ratio(curr_clock_time, 1.0);
return(0) ;
}
if ( enable_flag ) {
@ -311,6 +346,8 @@ int Trick::RealtimeSync::rt_monitor(long long sim_time_tics) {
frame_overrun_time = curr_clock_time - sim_time_tics ;
frame_overrun = frame_overrun_time * (1.0/tics_per_sec);
/* If the wall clock time is greater than the sim time an overrun occurred. */
if (curr_clock_time > sim_time_tics) {
@ -363,6 +400,8 @@ int Trick::RealtimeSync::rt_monitor(long long sim_time_tics) {
/* If the timer requires to be reset at the end of each frame, reset it here. */
sleep_timer->reset(exec_get_software_frame() / rt_clock->get_rt_clock_ratio()) ;
/* Calculate the run ratio after sleeping */
actual_run_ratio = run_ratio(curr_clock_time, rt_clock->get_rt_clock_ratio());
}
return(0) ;
@ -504,4 +543,4 @@ int Trick::RealtimeSync::shutdown() {
bool Trick::RealtimeSync::is_active() {
return active;
}
}

View File

@ -32,6 +32,7 @@ Trick::JobData::JobData() {
next_tics = 0 ;
frame_time = 0 ;
frame_time_seconds = 0.0;
}
Trick::JobData::JobData(int in_thread, int in_id, std::string in_job_class_name , void* in_sup_class_data,

View File

@ -138,7 +138,8 @@ TEST_F(VariableServerSessionThread_test, connection_failure) {
}
TEST_F(VariableServerSessionThread_test, exit_if_handle_message_fails) {
TEST_F(VariableServerSessionThread_test, DISABLED_exit_if_handle_message_fails) {
// ARRANGE
setup_normal_connection_expectations(&connection);
@ -168,7 +169,8 @@ TEST_F(VariableServerSessionThread_test, exit_if_handle_message_fails) {
}
TEST_F(VariableServerSessionThread_test, exit_if_write_fails) {
TEST_F(VariableServerSessionThread_test, DISABLED_exit_if_write_fails) {
// ARRANGE
setup_normal_connection_expectations(&connection);
@ -341,4 +343,4 @@ TEST_F(VariableServerSessionThread_test, throw_exception) {
// There should be nothing in the VariableServer's thread list
EXPECT_EQ(varserver->get_vst(id), (Trick::VariableServerSessionThread *) NULL);
EXPECT_EQ(varserver->get_session(id), (Trick::VariableServerSession *) NULL);
}
}

View File

@ -177,7 +177,7 @@ def traceit(frame, event, arg):
if event == "line":
lineno = frame.f_lineno
filename = frame.f_code.co_filename
if ( not filename.startswith(exclude_dir) and not filename.startswith("/usr")):
if ( not filename.startswith(exclude_dir) and not filename.startswith("/usr") and not filename.startswith("/opt") and not filename.startswith("<") and not filename.startswith(".trick/") ):
if (filename.endswith(".pyc") or
filename.endswith(".pyo")):
filename = filename[:-1]

View File

@ -19,12 +19,13 @@ DLLIST *DLL_Create(void)
/* initializes a list */
/* return: none */
// JMP: This should return a status to let us know whether or not we succeeded
void DLL_Delete(DLLIST * list)
{
if (list == NULL) {
fprintf(stderr, "List is NULL");
fprintf(stderr, "Error (%s): List is NULL.\n", __FUNCTION__);
fflush(stderr);
return;
}
@ -34,15 +35,31 @@ void DLL_Delete(DLLIST * list)
}
}
/* Determine whether the given list contains the node at the given pos.
If it does, return 1, otherwise return 0.
*/
static int DLL_ListContainsPos( DLLPOS pos, DLLIST * list) {
if ((list == NULL) || (pos == NULL)) {
return 0;
}
DLLPOS lpos = list->head;
while ((lpos != pos) && (lpos != NULL)) {
lpos = lpos->next;
}
if (lpos == NULL) {
return 0;
}
return 1;
}
/* returns number of elements in list */
/* return: count */
// JMP: This should return a status to let us know whether or not we succeeded
void DLL_Init(DLLIST * list)
{
if (list == NULL) {
fprintf(stderr, "List is NULL");
fprintf(stderr, "Error (%s): List is NULL.\n", __FUNCTION__);
fflush(stderr);
return;
}
@ -62,7 +79,8 @@ int DLL_GetCount(DLLIST * list)
{
if (list == NULL) {
fprintf(stderr, "List is NULL");
fprintf(stderr, "Error (%s): List is NULL.\n", __FUNCTION__);
fflush(stderr);
return -1;
}
@ -80,9 +98,14 @@ void *DLL_Find(void *data, DLLIST * list)
{
DLLPOS pos;
if (list == NULL) {
fprintf(stderr, "List is NULL");
fprintf(stderr, "Error (%s): List is NULL.\n", __FUNCTION__);
fflush(stderr);
return NULL;
}
if (list->compare == NULL) {
fprintf(stderr, "Error (%s): List doesn't have a compare function.\n", __FUNCTION__);
fflush(stderr);
return NULL;
}
@ -105,7 +128,8 @@ DLLPOS DLL_FindPos(void *data, DLLIST * list)
if (list == NULL) {
fprintf(stderr, "List is NULL");
fprintf(stderr, "Error (%s): List is NULL.\n", __FUNCTION__);
fflush(stderr);
return NULL;
}
@ -122,6 +146,7 @@ DLLPOS DLL_FindPos(void *data, DLLIST * list)
/* find position at given index */
/* return: position of nth element */
DLLPOS DLL_FindIndex(int n, DLLIST * list)
{
int nPos = 0;
@ -129,13 +154,14 @@ DLLPOS DLL_FindIndex(int n, DLLIST * list)
if (list == NULL) {
fprintf(stderr, "List is NULL");
fprintf(stderr, "Error (%s): List is NULL.\n", __FUNCTION__);
fflush(stderr);
return NULL;
}
if (n < 0 && n >= list->count) {
fprintf(stderr, "Index is either negative or exceeds the number of elements in the list");
if ( (n < 0) || (n >= list->count) ) {
fprintf(stderr, "Error (%s): Index is either negative or exceeds the number of elements in the list.\n", __FUNCTION__);
fflush(stderr);
return NULL;
}
@ -154,22 +180,17 @@ DLLPOS DLL_FindIndex(int n, DLLIST * list)
void *DLL_GetAt(DLLPOS pos, DLLIST * list)
{
if (list == NULL) {
fprintf(stderr, "List is NULL");
if ((list == NULL) || (pos == NULL)) {
fprintf(stderr, "Error (%s): Either pos, list, or both are NULL.\n", __FUNCTION__);
fflush(stderr);
return NULL;
}
if (pos == NULL) {
fprintf(stderr, "Position is NULL");
if ( !DLL_ListContainsPos(pos, list) ) {
fprintf(stderr, "Error (%s): The specified list doesn't contain the specified node (pos).\n", __FUNCTION__);
fflush(stderr);
return NULL;
}
if (list) {
return pos->info;
}
return (NULL);
return pos->info;
}
@ -178,21 +199,19 @@ void *DLL_GetAt(DLLPOS pos, DLLIST * list)
void *DLL_SetAt(DLLPOS pos, void *info, DLLIST * list)
{
void *ret;
if (pos == NULL && list == NULL) {
fprintf(stderr, "List and Position are NULL");
if ((list == NULL) || (pos == NULL)) {
fprintf(stderr, "Error (%s): Either pos, list, or both are NULL.\n", __FUNCTION__);
fflush(stderr);
return NULL;
}
if (pos != NULL && list != NULL) {
ret = pos->info;
pos->info = info;
return ret;
if ( !DLL_ListContainsPos(pos, list) ) {
fprintf(stderr, "Error (%s): The specified list doesn't contain the specified node (pos).\n", __FUNCTION__);
fflush(stderr);
return NULL;
}
return (NULL);
void* prev_info = pos->info;
pos->info = info;
return prev_info;
}
@ -203,34 +222,37 @@ void *DLL_RemoveAt(DLLPOS pos, DLLIST * list)
{
void *ret;
if (pos == NULL && list == NULL) {
fprintf(stderr, "List and Position are NULL");
if ((pos == NULL) || (list == NULL)) {
fprintf(stderr, "Error (%s): List or Position is NULL.\n", __FUNCTION__);
fflush(stderr);
return NULL;
}
if (pos != NULL && list != NULL) {
list->count--;
if (pos->prev != NULL) {
pos->prev->next = pos->next;
if (pos->next != NULL)
pos->next->prev = pos->prev;
else
list->tail = pos->prev;
} else if (pos->next != NULL) {
list->head = pos->next;
pos->next->prev = NULL;
} else {
list->head = NULL;
list->tail = NULL;
}
ret = pos->info;
free(pos);
return ret;
if ( !DLL_ListContainsPos(pos, list) ) {
fprintf(stderr, "Error (%s): The specified list doesn't contain the specified node (pos).\n", __FUNCTION__);
fflush(stderr);
return NULL;
}
return (NULL);
if (pos->prev != NULL) { // check whether pos is the head
pos->prev->next = pos->next; // pos is not the head
if (pos->next != NULL) // check whether pos is the tail
pos->next->prev = pos->prev; // pos is not the tail
else
list->tail = pos->prev; // pos is the tail
} else if (pos->next != NULL) { // pos is the head, check whether it's also the tail
list->head = pos->next; // pos not the tail
pos->next->prev = NULL;
} else { // pos is both the head and the tail
list->head = NULL;
list->tail = NULL;
}
list->count --;
ret = pos->info;
free(pos);
return ret;
}
@ -244,7 +266,8 @@ void DLL_RemoveAll(DLLIST * list)
if (list == NULL) {
fprintf(stderr, "List is NULL");
fprintf(stderr, "Error (%s): List is NULL.\n", __FUNCTION__);
fflush(stderr);
return;
}
@ -263,13 +286,6 @@ DLLPOS DLL_InsertBefore(DLLPOS pos, void *data, DLLIST * list)
{
if (pos != NULL && list != NULL) {
DLLPOS newpos = (DLLPOS) malloc(sizeof(DLLNODE));
if (pos == NULL && list == NULL) {
fprintf(stderr, "List and Position are NULL");
return NULL;
}
newpos->info = data;
if (pos->prev == NULL) {
newpos->next = list->head;
@ -282,8 +298,11 @@ DLLPOS DLL_InsertBefore(DLLPOS pos, void *data, DLLIST * list)
newpos->next = pos;
pos->prev = newpos;
}
list->count++;
return newpos;
}
fprintf(stderr, "Error (%s): Either List, Position, or both are NULL.\n", __FUNCTION__);
fflush(stderr);
return (NULL);
}
@ -295,16 +314,9 @@ DLLPOS DLL_InsertAfter(DLLPOS pos, void *data, DLLIST * list)
{
if (pos != NULL && list != NULL) {
DLLPOS newpos = (DLLPOS) malloc(sizeof(DLLNODE));
if (pos == NULL && list == NULL) {
fprintf(stderr, "List and Position are NULL");
return NULL;
}
newpos->info = data;
if (pos->next == NULL) {
newpos->next = list->tail;
newpos->prev = list->tail;
newpos->next = NULL;
list->tail = newpos;
pos->next = newpos;
@ -314,57 +326,54 @@ DLLPOS DLL_InsertAfter(DLLPOS pos, void *data, DLLIST * list)
newpos->prev = pos;
pos->next = newpos;
}
list->count++;
return newpos;
}
fprintf(stderr, "Error (%s): Either List, Position, or both are NULL.\n", __FUNCTION__);
fflush(stderr);
return (NULL);
}
/* gets the next position in the list */
/* return: the data at the current pos */
void *DLL_GetNext(DLLPOS * pos, DLLIST * list)
void *DLL_GetNext(DLLPOS* pos_p, DLLIST * list)
{
void *ret;
if (pos == NULL && list == NULL) {
fprintf(stderr, "List and Position are NULL");
if ((list == NULL) || (pos_p == NULL)) {
fprintf(stderr, "Error (%s): Either the List, the Position pointer, or both are NULL.\n", __FUNCTION__);
fflush(stderr);
return (NULL);
}
if ( !DLL_ListContainsPos(*pos_p, list) ) {
fprintf(stderr, "Error (%s): List doesn't contain a node at the given position.\n", __FUNCTION__);
fflush(stderr);
return NULL;
}
if (pos != NULL && list != NULL) {
ret = (*pos)->info;
*pos = (*pos)->next;
return ret;
}
return (NULL);
void* data = (*pos_p)->info;
*pos_p = (*pos_p)->next;
return data;
}
/* gets the previous position in the list */
/* return: the data at the current position */
void *DLL_GetPrev(DLLPOS * pos, DLLIST * list)
void *DLL_GetPrev(DLLPOS * pos_p, DLLIST * list)
{
void *ret;
if (pos == NULL && list == NULL) {
fprintf(stderr, "List and Position are NULL");
if ((list == NULL) || (pos_p == NULL)) {
fprintf(stderr, "Error (%s): Either the List, the Position pointer, or both are NULL.\n", __FUNCTION__);
fflush(stderr);
return (NULL);
}
if ( !DLL_ListContainsPos(*pos_p, list) ) {
fprintf(stderr, "Error (%s): List doesn't contain a node at the given position.\n", __FUNCTION__);
fflush(stderr);
return NULL;
}
if (pos != NULL && list != NULL) {
ret = (*pos)->info;
*pos = (*pos)->prev;
return ret;
}
return (NULL);
void* data = (*pos_p)->info;
*pos_p = (*pos_p)->prev;
return data;
}
/* adds an element to the head of the list */
/* return: the position of the new element */
@ -372,13 +381,6 @@ DLLPOS DLL_AddHead(void *data, DLLIST * list)
{
if (list != NULL) {
DLLPOS newpos = (DLLPOS) malloc(sizeof(DLLNODE));
if (list == NULL) {
fprintf(stderr, "List is NULL");
return NULL;
}
newpos->info = data;
if (list->head == NULL) {
list->head = newpos;
@ -394,6 +396,8 @@ DLLPOS DLL_AddHead(void *data, DLLIST * list)
list->count++;
return newpos;
}
fprintf(stderr, "Error (%s): List is NULL.\n", __FUNCTION__);
fflush(stderr);
return (NULL);
}
@ -405,13 +409,6 @@ DLLPOS DLL_AddTail(void *data, DLLIST * list)
{
if (list != NULL) {
DLLPOS newpos = (DLLPOS) malloc(sizeof(DLLNODE));
if (list == NULL) {
fprintf(stderr, "List is NULL");
return NULL;
}
newpos->info = data;
if (list->tail == NULL) {
list->head = newpos;
@ -427,6 +424,8 @@ DLLPOS DLL_AddTail(void *data, DLLIST * list)
list->count++;
return newpos;
}
fprintf(stderr, "Error (%s): List is NULL.\n", __FUNCTION__);
fflush(stderr);
return (NULL);
}
@ -438,7 +437,8 @@ DLLPOS DLL_GetHeadPosition(DLLIST * list)
{
if (list == NULL) {
fprintf(stderr, "List is NULL");
fprintf(stderr, "Error (%s): List is NULL.\n", __FUNCTION__);
fflush(stderr);
return NULL;
}
@ -454,9 +454,9 @@ DLLPOS DLL_GetHeadPosition(DLLIST * list)
DLLPOS DLL_GetTailPosition(DLLIST * list)
{
if (list == NULL) {
fprintf(stderr, "List is NULL");
fprintf(stderr, "Error (%s): List is NULL.\n", __FUNCTION__);
fflush(stderr);
return NULL;
}

View File

@ -16,11 +16,24 @@ LQUEUE *LQ_Create(void)
return ret;
}
int LQ_Delete(LQUEUE* lqueue) {
if (lqueue == NULL) {
fprintf(stderr, "Error (%s): Pointer to LQUEUE is NULL.\n", __FUNCTION__ );
fflush(stderr);
return -1;
}
DLL_Delete(&lqueue->list);
return 0;
}
/* initialize a queue created statically */
void LQ_Init(LQUEUE * pQueue)
{
if (pQueue == NULL) {
fprintf(stderr, "Error (%s): Pointer to LQUEUE is NULL.\n", __FUNCTION__ );
fflush(stderr);
}
DLL_Init(&(pQueue->list));
}
@ -31,7 +44,7 @@ void LQ_EnQ(void *pData, LQUEUE * pQueue)
{
if (pQueue == NULL) {
fprintf(stderr, "Queue is NULL");
fprintf(stderr, "Error (%s): Pointer to LQUEUE is NULL.", __FUNCTION__ );
return;
}
@ -43,8 +56,14 @@ void LQ_EnQ(void *pData, LQUEUE * pQueue)
void *LQ_DeQ(LQUEUE * pQueue)
{
if (LQ_GetCount(pQueue) > 0)
if (pQueue == NULL) {
fprintf(stderr, "Error (%s): Pointer to LQUEUE is NULL.", __FUNCTION__ );
return NULL;
}
if (LQ_GetCount(pQueue) > 0) {
return DLL_RemoveAt(DLL_GetTailPosition(&(pQueue->list)), &(pQueue->list));
}
return NULL;
}
@ -53,15 +72,19 @@ void *LQ_DeQ(LQUEUE * pQueue)
void *LQ_Peek(LQUEUE * pQueue)
{
if (pQueue == NULL && DLL_GetCount(&(pQueue->list)) <= 0) {
fprintf(stderr, "Queue is NULL and number of elements is 0");
if (pQueue == NULL) {
fprintf(stderr, "Error (%s): Pointer to LQUEUE is NULL.", __FUNCTION__);
fflush(stderr);
return NULL;
}
if (pQueue != NULL)
return DLL_GetAt(DLL_GetTailPosition(&(pQueue->list)), &(pQueue->list));
return NULL;
if ( DLL_GetCount( &(pQueue->list)) <= 0) {
fprintf(stderr, "Error (%s): LQUEUE is empty.", __FUNCTION__);
fflush(stderr);
return NULL;
}
return DLL_GetAt(DLL_GetTailPosition(&(pQueue->list)), &(pQueue->list));
}
@ -71,7 +94,7 @@ int LQ_GetCount(LQUEUE * pQueue)
{
if (pQueue == NULL) {
fprintf(stderr, "Queue is NULL");
fprintf(stderr, "Error (%s): Pointer to LQUEUE is NULL.", __FUNCTION__ );
return -1;
}

View File

@ -0,0 +1,65 @@
#SYNOPSIS:
#
# make [all] - makes everything.
# make TARGET - makes the given target.
# make clean - removes all files generated by make.
include ${TRICK_HOME}/share/trick/makefiles/Makefile.common
# Flags passed to the preprocessor.
TRICK_CXXFLAGS += -I$(GTEST_HOME)/include -I$(TRICK_HOME)/include -g -Wall -Wextra ${TRICK_SYSTEM_CXXFLAGS} ${TRICK_TEST_FLAGS}
TRICK_LIBS = ${TRICK_LIB_DIR}/libtrick.a
TRICK_EXEC_LINK_LIBS += -L${GTEST_HOME}/lib64 -L${GTEST_HOME}/lib -lgtest -lgtest_main -lpthread
# Added for Ubuntu... not required for other systems.
TRICK_EXEC_LINK_LIBS += -lpthread
# ==================================================================================
# All tests produced by this Makefile. Add new tests you create to this list.
# ==================================================================================
TESTS = dllist_unittest\
lqueue_unittest
# List of XML files produced by the tests.
unittest_results = $(patsubst %,%.xml,$(TESTS))
# List if Test-specific object files.
unittest_objects = $(patsubst %,%.o,$(TESTS))
# House-keeping build targets.
# ==================================================================================
# TARGETS
# ==================================================================================
all : test
test: unit_tests $(unittest_results)
unit_tests: $(TESTS)
clean :
rm -f $(TESTS)
rm -f *.o
# ==================================================================================
# Generate JUNIT (XML) Test Results
# ==================================================================================
$(unittest_results): %.xml: %
./$< --gtest_output=xml:${TRICK_HOME}/trick_test/$@
# ==================================================================================
# Build Unit test Objects
# ==================================================================================
$(unittest_objects): %.o: %.cpp
$(TRICK_CXX) $(TRICK_CXXFLAGS) -c $<
# ==================================================================================
# Build Unit test programs
# ==================================================================================
$(TESTS) : %: %.o
$(TRICK_CXX) $(TRICK_SYSTEM_LDFLAGS) -o $@ $^ -L${TRICK_HOME}/lib_${TRICK_HOST_CPU} $(TRICK_LIBS) $(TRICK_EXEC_LINK_LIBS)
# ----------------------------------------------------------------------------------
# The following unittest programs are also dependent on the indicated object files.
# ----------------------------------------------------------------------------------

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,142 @@
#include <gtest/gtest.h>
#include <iostream>
#include "trick/lqueue.h"
/*
LQUEUE* LQ_Create(void);
int LQ_Delete(LQUEUE* lqueue); free an lqueue object created by LQ_Create.
void LQ_Init(LQUEUE*);
void LQ_EnQ(void* pData,LQUEUE* pQueue); insert data into queue
void* LQ_DeQ(LQUEUE* pQueue); extract data from queue
void* LQ_Peek(LQUEUE* pQueue); get data off queue without extracting
int LQ_GetCount(LQUEUE* pQueue); returns number of items in the queue
BUG: There's no way to free an LQUEUE without a memory leak.
*/
TEST(lqueue_test, LQUEUE_Create) {
LQUEUE* result = LQ_Create();
EXPECT_NE(result, nullptr);
EXPECT_EQ( LQ_GetCount(result), 0);
}
TEST(lqueue_test, LQUEUE_Delete) {
LQUEUE* lqueue = LQ_Create();
EXPECT_EQ( LQ_Delete(lqueue), 0);
}
TEST(lqueue_test, LQUEUE_Delete_null) {
LQUEUE* lqueue = nullptr;
std::cout << "NOTE: An error message is expected to follow." << std::endl;
EXPECT_EQ( LQ_Delete(lqueue), -1);
}
TEST(lqueue_test, LQUEUE_Init) {
LQUEUE* lqueue = LQ_Create();
lqueue->list.count = 1;
lqueue->list.head = (DLLNODE*)(0xDEADBEEF);
lqueue->list.tail = (DLLNODE*)(0xDEADBEEF);
LQ_Init(lqueue);
EXPECT_EQ(lqueue->list.count, 0);
EXPECT_EQ(lqueue->list.head, nullptr);
EXPECT_EQ(lqueue->list.tail, nullptr);
EXPECT_EQ(lqueue->list.compare, nullptr);
EXPECT_EQ( LQ_GetCount(lqueue), 0);
}
TEST(lqueue_test, LQUEUE_Init_null) {
LQUEUE* lqueue = nullptr;
std::cout << "NOTE: Two error messages are expected to follow." << std::endl;
LQ_Init(lqueue);
}
TEST(lqueue_test, LQUEUE_EnQ) {
int A,B,C;
A=1; B=2; C=3;
LQUEUE* lqueue = LQ_Create();
LQ_EnQ( &A, lqueue);
EXPECT_EQ( LQ_GetCount(lqueue), 1);
LQ_EnQ( &B, lqueue);
EXPECT_EQ( LQ_GetCount(lqueue), 2);
LQ_EnQ( &C, lqueue);
EXPECT_EQ( LQ_GetCount(lqueue), 3);
}
TEST(lqueue_test, LQUEUE_EnQ_null_queue) {
int A,B,C;
A=1; B=2; C=3;
LQUEUE* lqueue = LQ_Create();
std::cout << "NOTE: An error message is expected to follow." << std::endl;
LQ_EnQ( &A, nullptr);
}
TEST(lqueue_test, LQUEUE_DeQ) {
int A,B,C;
A=1; B=2; C=3;
LQUEUE* lqueue = LQ_Create();
LQ_EnQ( &A, lqueue);
LQ_EnQ( &B, lqueue);
LQ_EnQ( &C, lqueue);
EXPECT_EQ( LQ_GetCount(lqueue), 3);
LQ_DeQ( lqueue);
EXPECT_EQ( LQ_GetCount(lqueue), 2);
LQ_DeQ( lqueue);
EXPECT_EQ( LQ_GetCount(lqueue), 1);
LQ_DeQ( lqueue);
EXPECT_EQ( LQ_GetCount(lqueue), 0);
}
TEST(lqueue_test, LQUEUE_DeQ_null_queue) {
int A,B,C;
A=1; B=2; C=3;
LQUEUE* lqueue = nullptr;
std::cout << "NOTE: An error message is expected to follow." << std::endl;
LQ_EnQ( &A, lqueue);
}
TEST(lqueue_test, LQUEUE_Peek) {
int A,B,C;
A=1; B=2; C=3;
int* result;
LQUEUE* lqueue = LQ_Create();
LQ_EnQ( &A, lqueue);
LQ_EnQ( &B, lqueue);
LQ_EnQ( &C, lqueue);
EXPECT_EQ( LQ_GetCount(lqueue), 3);
result = (int*)LQ_Peek(lqueue);
EXPECT_EQ(*result, 1);
LQ_DeQ( lqueue);
EXPECT_EQ( LQ_GetCount(lqueue), 2);
result = (int*)LQ_Peek(lqueue);
EXPECT_EQ(*result, 2);
LQ_DeQ( lqueue);
EXPECT_EQ( LQ_GetCount(lqueue), 1);
result = (int*)LQ_Peek(lqueue);
EXPECT_EQ(*result, 3);
LQ_DeQ( lqueue);
EXPECT_EQ( LQ_GetCount(lqueue), 0);
std::cout << "NOTE: An error message is expected to follow." << std::endl;
result = (int*)LQ_Peek(lqueue);
EXPECT_EQ(result, nullptr);
}
TEST(lqueue_test, LQUEUE_Peek_null_queue) {
int A,B,C;
A=1; B=2; C=3;
int* result = (int*)(0xDEADBEEF);;
LQUEUE* lqueue = nullptr;
result = (int*)LQ_Peek(lqueue);
EXPECT_EQ(result, nullptr);
}

View File

@ -1,236 +0,0 @@
#############################################################################
# Makefile:
# This is a makefile for maintaining the
# '/stroke/users/trick_dev/trick_source/trick_adt/test_program'
# directory. This make file was automatically generated by the
# "make_build" program.
#
#############################################################################
# Creation:
# Author: Trick auto makefile program - "make_build", Version 1998.1.Beta
# Date: 13:46:16 on Monday 16 February 1998
#
#############################################################################
#
# To get a desription of the arguments accepted by this makefile,
# type 'make help'
#
#############################################################################
#############################################################################
## DIRECTORY DEFINITIONS ##
#############################################################################
ifndef TRICK_HOST_CPU
TRICK_HOST_CPU := $(shell trick-gte TRICK_HOST_CPU)
endif
ifndef TRICK_HOST_TYPE
TRICK_HOST_TYPE := $(shell trick-gte TRICK_HOST_TYPE)
endif
TRICK_VER = 1998.1.Beta
CWD_DIR = /stroke/users/trick_dev/trick_source/trick_adt/test_program
SRC_DIR =
OBJ_DIR = object_${TRICK_HOST_CPU}
MODEL_BIN_DIR = $(OBJ_DIR)
#############################################################################
## UTILITY DEFINITIONS ##
#############################################################################
SHELL = /bin/sh
AWK = awk
SED = sed
LEX = lex
YACC = yacc
CD = cd
MV = mv
RM = rm
#
# Make information
#
MAKEFILE = Makefile
AWKTEMPFILE = awk.temp
SEDTEMPFILE = sed.temp
MAKEDEPEND = makedepend
FTNDEPEND = ftn_depend
#
# Awk program to filter out system include dependencies
#
AWK_PRGM = $(TRICK_HOME)/bin/depend.awk
#############################################################################
## COMPILER DEFINITIONS ##
#############################################################################
#
# C Compilation Variables
#
CPP_PRE_DEFS =
CPP_POST_DEFS =
CPPFLAGS = $(CPP_PRE_DEFS) $(TRICK_CFLAGS) $(CPP_POST_DEFS)
ifeq ($(TRICK_FORCE_32BIT), 1)
CPPFLAGS += -m32
endif
#
# FORTRAN Compilation Variables
#
FCFLAGS = $(TRICK_FTNFLAGS)
#############################################################################
## FILE NAME DEFINITIONS ##
#############################################################################
MODEL_C_SRC = \
$(SRC_DIR)test.c
MODEL_IO_SRC =
MODEL_FTN_SRC =
MODEL_C_OBJS = \
$(OBJ_DIR)/test.o
MODEL_IO_OBJS =
MODEL_FTN_OBJS =
#############################################################################
## SPECIAL TARGETS ##
#############################################################################
.PRECIOUS: $(MODEL_C_SRC) $(MODEL_FTN_SRC)
#############################################################################
## MODEL TARGETS ##
#############################################################################
default: verify_trick_version object_files
verify_trick_version:
@if ( test `trick_version $(TRICK_VER)` != $(TRICK_VER) ) then \
echo "Make ERROR:" ; \
echo " The current Makefile was generated with version $(TRICK_VER) of the Trick" ; \
echo " processors which is incompatible with the the current Trick version," ; \
echo " `trick_version`. Run 'catalog -versions' to get a complete list of" ; \
echo " potential incompatibility problems. You must delete this Makefile" ; \
echo " before make_build will generate a new Makefile." ; \
exit 1 ; \
fi
object_files: $(OBJ_DIR) $(MODEL_IO_OBJS) $(MODEL_C_OBJS) $(MODEL_FTN_OBJS)
@ echo "$(CWD_DIR) object files up to date"
help :
@ echo "\
Source Directory Make Options:\n\
make - Compiles are source files\n\
\n\
make ICG - Deletes the io_src directory and runs ICG\n\
on all pertinent *.h files\n\
\n\
make catalog - Deletes the local catalog and builds a new one\n\
\n\
make depend - Adds file dependencies to Makefile\n\
\n\
make io_clean - Deletes the local io_src directory\n\
\n\
make catalog_clean - Deletes the local catalog directory\n\
\n\
make clean - Deletes the object code directory\n\
\n\
make real_clean - Deletes html/, io_src/, catalog/,\n\
and object_${TRICK_HOST_CPU}/ directories\n"
$(OBJ_DIR):
@ mkdir -p $(OBJ_DIR)
@ echo "Created $(OBJ_DIR)"
#
# MODEL_IO_OBJS
#
#
# MODEL_IO_SRC
#
#
# MODEL_C_OBJS
#
$(OBJ_DIR)/test.o : $(SRC_DIR)test.c
$(TRICK_CC) $(CPPFLAGS) -c test.c -o $(OBJ_DIR)/test.o
$(TRICK_CC) ${TRICK_CFLAGS} $(OBJ_DIR)/test.o -L${TRICK_HOME}/lib_${TRICK_HOST_CPU} -o test -ltrick_adt
#
# LEX/YACC SOURCE
#
#
# MODEL_F_OBJS
#
#
# ICG Target
#
ICG: verify_trick_version io_clean $(OBJ_DIR) $(MODEL_IO_OBJS)
@ echo "IO files are up to date!"
#############################################################################
## MAINTENANCE TARGETS ##
#############################################################################
depend:
$(MAKEDEPEND) -f $(MAKEFILE)
@ touch $(AWKTEMPFILE)
@ $(MAKEDEPEND) -f $(AWKTEMPFILE) -Iinclude -- $(CPPFLAGS) -- $(MODEL_C_SRC) $(MODEL_IO_SRC)
@ $(FTNDEPEND) -- $(FCFLAGS) -- $(MODEL_FTN_SRC) >> $(AWKTEMPFILE)
@ $(AWK) -f $(AWK_PRGM) $(AWKTEMPFILE) >> $(SEDTEMPFILE)
@ $(RM) -f $(AWKTEMPFILE)
@ $(SED) -e 's:$(TRICK_HOME):$$(TRICK_HOME):' $(SEDTEMPFILE) >> $(AWKTEMPFILE)
@ $(SED) s:\$\(MODEL_BIN_DIR\)/src:\$\(MODEL_BIN_DIR\): $(AWKTEMPFILE) >> $(MAKEFILE)
@ $(RM) -f $(AWKTEMPFILE) $(AWKTEMPFILE).bak $(SEDTEMPFILE)
@ echo "Appended dependencies to $(MAKEFILE)"
io_clean: verify_trick_version
$(RM) -rf io_src
real_clean: verify_trick_version clean io_clean
$(RM) -rf html *~ *.bak core
@ echo "Directory is really clean!"
clean: verify_trick_version
$(RM) -rf $(LIB) $(OBJ_DIR)
@ echo "Object files successfully removed"
catalog_clean : verify_trick_version
$(RM) -rf catalog
@ echo "Catalog purged"
catalog : verify_trick_version catalog_clean $(MODEL_IO_SRC)
MIS
@ echo "$(CWD_DIR) Catalog rebuilt"
#############################################################################
#------------------------------------------------------------------------
# Below this are the object module dependencies, built with makedepend.
#------------------------------------------------------------------------
# DO NOT DELETE THIS LINE -- make depend depends on it.
$(MODEL_BIN_DIR)/test.o: ../bst.h

View File

@ -1,103 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include "../bst.h"
#include <string.h>
typedef struct
{
int key;
char* data;
}ITEM;
int compare(void* left, void* right)
{
ITEM* pitem1=(ITEM*)left;
ITEM* pitem2=(ITEM*)right;
if(pitem1->key-pitem2->key < 0)
return -1;
else if(pitem1->key-pitem2->key > 0)
return 1;
else
return 0;
}
void main()
{
short done=0;
int newnum;
char ch;
char buffer[256];
ITEM* newitem;
BST bst;
bstNode* node;
ITEM tempitem;
bstInit(&bst);
bstSetCompareFunc(&bst,compare);
while(!done)
{
fprintf(stderr,"(1) Add Item\n(2) Lookup\n(3) Remove Item\n");
ch=getchar();
fflush(stdin);
switch(ch)
{
case '1':
newitem=(ITEM*)malloc(sizeof(ITEM));
printf("\nEnter a string\n");
scanf("%s",buffer);
newitem->data=strdup(buffer);
printf("Enter key\n");
scanf("%d",&newnum);
newitem->key=newnum;
printf("inserting at %d\n",newnum);
bstInsert(newitem,&bst);
break;
case '2':
printf("Enter key\n");
scanf("%d",&newnum);
printf("Looking for %d\n",newnum);
tempitem.key=newnum;
node=bstFind(&tempitem,&bst);
if(node != NULL)
{
newitem=(ITEM*)bstGetInfo(node);
printf("found %s\n",newitem->data);
}
else
{
printf("Item not found\n");
}
break;
case '3':
printf("Enter key\n");
scanf("%d",&newnum);
tempitem.key=newnum;
node=bstFind(&tempitem,&bst);
if(node != NULL)
{
newitem=(ITEM*)bstGetInfo(node);
printf("removing %s\n",newitem->data);
bstDelete(node,&bst);
}
else
{
printf("Item not found\n");
}
break;
default:done=1;
}
fflush(stdin);
}
}

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More