This is PFunction.m in view mode; [Download] [Up]
/* PFunction.m by Paul Kunz November 1992
* Class to manage a plot function
*
* Copyright (C) 1992 The Board of Trustees of
* The Leland Stanford Junior University. All Rights Reserved.
*/
#import "Plot.h"
#import "PFunction.h"
const char PFunction_h_rcsid[] = PFUNCTION_H_ID;
const char PFunction_m_rcsid[] = "$Id: PFunction.m,v 2.14.2.1 1994/02/08 20:30:05 rensing Exp $";
#import <objc/hashtable.h>
#import <appkit/nextstd.h>
#define PARM_MAX 0
#define PARM_VALUE 1
#define PARM_MIN 2
#define PARM_STEP 3
#define BWG_VERSION 1
#define NONBWG_VERSION 2
#define TYPES_VERSION 3
#define ONETYPE_VERSION 4
#define LEAVEIN_VERSION 5
#define STORAGE_VERSION 6
#define EMPTYBIN_VERSION 7
#define CURRENT_VERSION EMPTYBIN_VERSION
@implementation PFunction
static void writeParms( NXTypedStream *ts, Storage *store )
{
fitParm *parm;
int i, count;
count = [store count];
NXWriteType( ts, "i", &count);
for ( i = 0; i < count; i++ ) {
parm = (fitParm *)[store elementAt:i];
NXWriteType( ts, "{[7d]*cc}", parm );
}
return;
}
static Storage *readParms( NXTypedStream *ts )
{
Storage *store;
fitParm parm;
int i, count;
store = [[Storage alloc] initCount:0
elementSize:sizeof(fitParm)
description:"[7d]*cc"];
NXReadType( ts, "i", &count);
for ( i = 0; i < count; i++ ) {
NXReadType( ts, "{[7d]*cc}", &parm );
[store addElement:&parm];
}
return store;
}
/* Methods to initialize the function */
+ initialize
{
[self setVersion:CURRENT_VERSION];
return self;
}
- setTitle:(const char *)string
{
title = NXCopyStringBuffer(string);
return self;
}
- (const char *)title
{
return title;
}
- setFunctionPtr:(void *)ptr
{
fp = ptr;
if ( hfunc ) {
hfunc->funcPtr = ptr;
}
return self;
}
- (void *) functionPtr
{
return fp;
}
- registerFunc
{
h_func_reg( title, fp );
return self;
}
- setNumberArgs:(int) value
{
nargs = (value > 0) ? value : 0;
if ( !nargs ) {
return self;
}
if ( names ) {
names = (char **) NXZoneRealloc( [self zone], names,
nargs*sizeof( char *) );
} else {
names = (char **) NXZoneMalloc( [self zone],
nargs*sizeof( char*) );
memset(names, 0, nargs*sizeof(char*) ); // protect against missing names
}
return self;
}
- (int)numberArgs
{
return nargs;
}
- setArgName:(const char *)string at:(int) i
{
if ( i >= 0 && i < nargs ) {
names[i] = NXCopyStringBuffer( string );
}
return self;
}
- (const char *) argNameAt:(int) i
{
if ( i < 0 || i >= nargs ) {
return NULL;
}
return names[i];
}
- setFitType:(int *)ivalue
{
fitType = *ivalue;
return self;
}
- (int) fitType
{
return fitType;
}
- setEbType:(int *)ivalue
{
ebType = *ivalue;
return self;
}
- (int) ebType
{
return ebType;
}
- setFuncLineStyle:(int *)ivalue
{
linestyle_t style;
style = *ivalue;
h_setPFuncLineStyle(hfunc, style);
return self;
}
- (int) funcLineStyle
{
return (int)h_getPFuncLineStyle(hfunc);
}
- resetAfterRead: aPlot
{
int i;
func_id func;
if (hfunc_index < 0)
[self addToPlot: aPlot];
else
{
disp = [aPlot histDisplay];
if ( !disp ) return self;
hfunc = NULL;
func=h_nextPlotFunc(disp,NULL);
for (i=0; func != NULL && hfunc == NULL; i++ )
{
if (i == hfunc_index) hfunc = func;
func = h_nextPlotFunc(disp, func);
}
parmblk = hfunc->paramBlk;
if (fitType < 0 ) fitType = 0;
}
[self resetParms]; /* put values in parmblk */
return self;
}
- addToPlot:aPlot
{
disp = [aPlot histDisplay];
if ( !disp ) return self;
NX_ZONEMALLOC( [aPlot zone], parmblk, double, nargs );
hfunc = h_addPlotFunc( disp, title, parmblk, nargs, SOLID);
h_setPlotFuncs( disp, YES);
if (fitType < 0 ) fitType = 0;
return self;
}
- removeFromPlot:(Plot *)aPlot
{
disp = [aPlot histDisplay];
h_deletePlotFunc( disp, hfunc );
NX_FREE( parmblk );
return self;
}
- setInitialValues
{
fitParm parm;
unsigned int i;
if ( !variedParms ) {
variedParms = [[Storage alloc] initCount:0
elementSize:sizeof(fitParm)
description:"[7d]*cc"];
}
for ( i = 0; i < nargs; i++ ) {
parm.value = 1.0;
parm.lower_limit = 0.0;
parm.upper_limit = 10.0;
parm.step_size = 0.1;
parm.name = NXCopyStringBuffer(names[i]);
parm.fixedValue = NO;
parm.fixedLimits = NO;
parm.error = 1.0;
[variedParms addElement:&parm];
}
/* user routine to override values */
[self initialValues];
[startParms free];
startParms = [variedParms copyFromZone:[self zone]];
[fittedParms free];
fittedParms = [variedParms copyFromZone:[self zone]];
return self;
}
- initialValues
{
return self;
}
- copyToVaried:(parm_t *)type
{
Storage *stor;
switch (*type) {
case INITIAL_VALUES:
stor = startParms;
break;
case FIT_VALUES:
stor = fittedParms;
break;
default:
stor = nil;
break;
}
if ( stor == nil ) return self;
[variedParms free];
variedParms = [stor copyFromZone:[self zone]];
return self;
}
- copyToFitted:(parm_t *)type
{
Storage *stor;
switch (*type) {
case INITIAL_VALUES:
stor = startParms;
break;
case PLAY_VALUES:
stor = variedParms;
break;
default:
stor = nil;
break;
}
if ( stor == nil ) return self;
[fittedParms free];
fittedParms = [stor copyFromZone:[self zone]];
return self;
}
- copyToInitial:(parm_t *)type
{
Storage *stor;
switch (*type) {
case PLAY_VALUES:
stor = variedParms;
break;
case FIT_VALUES:
stor = fittedParms;
break;
default:
stor = nil;
break;
}
if ( !stor ) return self;
[startParms free];
startParms = [stor copyFromZone:[self zone]];
return self;
}
- resetParms
{
[self updateFromType:¤tParms];
return self;
}
- updateFromType:(parm_t *)type
{
Storage *stor;
fitParm *parm;
int i;
stor = [self parmListOfType:*type];
i = [stor count];
while ( i-- ) {
parm = (fitParm *)[stor elementAt:i];
parmblk[i] = parm->value;
}
currentParms = *type;
return self;
}
- (parm_t) currentType
{
return currentParms;
}
- updateParm:(double) value at:(int) index
{
parmblk[index] = value;
return self;
}
- setFloatValue:(float) aValue at:(int) index
{
fitParm *parm;
if ( (index < 0) || (index >= nargs) ) return self;
parmblk[index] = aValue;
parm = [variedParms elementAt:index];
parm->value = aValue;
return self;
}
- (Storage *) parmListOfType:(parm_t) type
{
Storage *stor;
switch (type) {
case 0:
stor = startParms;
break;
case 1:
stor = fittedParms;
break;
case 2:
stor = variedParms;
break;
default:
stor = nil;
break;
}
return stor;
}
- (const char *)filename
{
return filename;
}
- readFile:(const char *)directory :(const char *)file
{
NXStream *input;
char path[MAXPATHLEN+1];
char *streambuf;
int len, maxlen;
sprintf( path, "%s/%s", directory, file );
input = NXMapFile( path, NX_READONLY );
codeStream = NXOpenMemory(NULL, 0, NX_READWRITE);
if ( input && codeStream ) {
NXGetMemoryBuffer( input, &streambuf, &len, &maxlen );
NXWrite( codeStream, streambuf, maxlen );
NXCloseMemory( input, NX_FREEBUFFER);
filename = NXCopyStringBufferFromZone( file, [self zone] );
}
return self;
}
- writeFile:(const char *)directory :(const char *) file
{
char path[MAXPATHLEN+1];
if ( codeStream ) {
sprintf( path, "%s/%s", directory, file );
NXSaveToFile( codeStream, path );
}
return self;
}
- write:(NXTypedStream *)stream
{
int i;
func_id func;
[super write:stream];
NXWriteTypes( stream, "*i", &title, &nargs );
for ( i = 0; i < nargs; i++ ) {
NXWriteType( stream, "*", &names[i] );
}
NXWriteTypes( stream, "i", ¤tParms );
if ( CURRENT_VERSION < STORAGE_VERSION ) {
/*
* Following doesn't work for NS3.1 pre-release
* thus we need to work around it.
*/
NXWriteObject( stream, fittedParms );
NXWriteObject( stream, startParms );
NXWriteObject( stream, variedParms );
} else {
writeParms( stream, fittedParms );
writeParms( stream, startParms );
writeParms( stream, variedParms );
}
NXWriteTypes( stream, "i", &fitType );
if ( CURRENT_VERSION >= EMPTYBIN_VERSION ) {
NXWriteTypes( stream, "i", &ebType );
}
/* figure out the index of the func_id block and write that */
hfunc_index = -1;
func = h_nextPlotFunc(disp, NULL);
for (i=0; func != NULL; i++ )
{
if (hfunc == func) hfunc_index = i;
func = h_nextPlotFunc(disp, func);
}
NXWriteTypes( stream, "i", &hfunc_index );
return self;
}
- read:(NXTypedStream *)stream
{
int i;
float f;
[super read:stream];
NXReadTypes( stream, "*i", &title, &nargs );
names =
(char **) NXZoneRealloc( [self zone], names, nargs*sizeof( char *) );
for ( i = 0; i < nargs; i++ ) {
NXReadType( stream, "*", &names[i] );
}
if ( NXTypedStreamClassVersion(stream, "PFunction") > BWG_VERSION )
NXReadTypes( stream, "i", ¤tParms );
else
NXReadTypes( stream, "if", ¤tParms, &f );
if ( NXTypedStreamClassVersion(stream, "PFunction") < STORAGE_VERSION ) {
/* The following was broke in NS3.1 pre-release */
fittedParms = NXReadObject( stream );
startParms = NXReadObject( stream );
variedParms = NXReadObject( stream );
} else {
fittedParms = readParms( stream );
startParms = readParms( stream );
variedParms = readParms( stream );
}
if (NXTypedStreamClassVersion(stream,"PFunction") >= ONETYPE_VERSION) {
NXReadTypes( stream, "i", &fitType);
}
else if (NXTypedStreamClassVersion(stream,"PFunction") == TYPES_VERSION) {
NXReadTypes( stream, "iii", &fitType, &i, &i );
} else {
fitType = 0;
}
if (NXTypedStreamClassVersion(stream,"PFunction") >= EMPTYBIN_VERSION) {
NXReadTypes( stream, "i", &ebType);
}
if (NXTypedStreamClassVersion(stream,"PFunction") >= LEAVEIN_VERSION) {
NXReadTypes( stream, "i", &hfunc_index );
}
else
hfunc_index = -1;
return self;
}
- free
{
[fittedParms free];
[startParms free];
[variedParms free];
if ( filename ) {
NXZoneFree( [self zone], filename );
/* do not free codeStream; another object might point to it */
}
return [super free];
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.