Skip to content

Commit

Permalink
Alt/Obj,Batch: add more checks when creating objects; refactor to rem…
Browse files Browse the repository at this point in the history
…ove some redundancy.
  • Loading branch information
PMeira committed Mar 16, 2024
1 parent a858db9 commit 790268c
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 38 deletions.
4 changes: 4 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@

# Versions 0.14.x

## Version 0.14.4 (dev, next release)

- Alt/Obj,Batch: adjust checks for new elements. Refactored some other internal code to simplify this kind of check.

## Version 0.14.3 (2024-03-13)

- Header/Alt: fix `dss_obj_float64_int32_func_t` (returns `double`, not `int32_t`).
Expand Down
43 changes: 28 additions & 15 deletions src/CAPI/CAPI_Obj.pas
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,9 @@ function obj_NewFromClass(DSS: TDSSContext; Cls: TDSSClass; Name: String; Activa
Result := NIL;
if DSS = NIL then DSS := DSSPrime;
Obj := Cls.NewObject(Name, Activate);
if Obj = NIL then
Exit;

if BeginEdit then
Cls.BeginEdit(Obj, False);

Expand All @@ -240,25 +243,26 @@ function obj_NewFromClass(DSS: TDSSContext; Cls: TDSSClass; Name: String; Activa

function Obj_New(DSS: TDSSContext; ClsIdx: Integer; Name: PAnsiChar; Activate: TAltAPIBoolean; BeginEdit: TAltAPIBoolean): Pointer; CDECL;
var
Obj: TDSSObject;
Cls: TDSSClass;
checkDups: Boolean;
begin
Result := NIL;
if DSS = NIL then DSS := DSSPrime;
Cls := DSS.DSSClassList.At(ClsIdx);
if Cls = NIL then
if (Cls = NIL) or (Cls.RequiresCircuit and InvalidCircuit(DSS)) then
Exit;

Obj := Cls.NewObject(Name, Activate);
if BeginEdit then
Cls.BeginEdit(Obj, False);

if Cls.DSSClassType = DSS_OBJECT then
DSS.DSSObjs.Add(Obj)
else
DSS.ActiveCircuit.AddCktElement(TDSSCktElement(Obj));
checkDups := (cls.DSSClassType <> DSS_OBJECT) and (not DSS.ActiveCircuit.DuplicatesAllowed);

Result := Obj;
if checkDups then
begin
if cls.Find(Name, true) <> NIL then
begin
DoSimpleMsg(DSS, 'Warning: Duplicate new element definition: "%s.%s". Element being redefined.', [Cls.Name, Name], 266);
Exit;
end;
end;
Result := obj_NewFromClass(DSS, cls, name, Activate, BeginEdit);
end;

function Obj_GetHandleByName(DSS: TDSSContext; ClsIdx: Integer; Name: PAnsiChar): Pointer; CDECL;
Expand Down Expand Up @@ -858,18 +862,21 @@ procedure Batch_CreateFromNew(DSS: TDSSContext; var ResultPtr: TDSSObjectPtr; Re
Cls: TDSSClass;
outptr: TDSSObjectPtr;
i: Integer;
prefix: String;
Name, prefix: String;
checkDups: Boolean;
begin
if DSS = NIL then DSS := DSSPrime;
Cls := DSS.DSSClassList.At(ClsIdx);
if Cls = NIL then
if (Cls = NIL) or (Cls.RequiresCircuit and InvalidCircuit(DSS)) then
Exit;

checkDups := (cls.DSSClassType <> DSS_OBJECT) and (not DSS.ActiveCircuit.DuplicatesAllowed);
ensureBatchSize(Count, ResultPtr, ResultCount);
outptr := ResultPtr;

if Names = NIL then
begin
// Use a random batch prefix to avoid collisions
// Use a random batch prefix to avoid collisions; we won't check for existing objects here
prefix := Format('%09d_', [Random(1000000000)]);
for i := 1 to Count do
begin
Expand All @@ -886,7 +893,13 @@ procedure Batch_CreateFromNew(DSS: TDSSContext; var ResultPtr: TDSSObjectPtr; Re
begin
for i := 1 to Count do
begin
outptr^ := Cls.NewObject(Names^, False);
Name := Names^;
if checkDups and (cls.Find(Name, true) <> NIL) then
begin
DoSimpleMsg(DSS, 'Warning: Duplicate new element definition: "%s.%s". Element being redefined.', [Cls.Name, Name], 266);
Exit;
end;
outptr^ := Cls.NewObject(Name, False);
if Cls.DSSClassType = DSS_OBJECT then
DSS.DSSObjs.Add(outptr^)
else
Expand Down
1 change: 1 addition & 0 deletions src/Common/CktElementClass.pas
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ constructor TCktElementClass.Create(dssContext: TDSSContext; DSSClsType: Integer
end;

inherited Create(dssContext, DSSClsType, DSSClsName);
RequiresCircuit := true;
ClassParents.Add('CktElement');
end;

Expand Down
3 changes: 3 additions & 0 deletions src/Common/DSSClass.pas
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,7 @@ TDSSClass = class(TObject)
ElementNamesOutOfSynch: Boolean; // When device gets renamed

Saved: Boolean;
RequiresCircuit: Boolean;

constructor Create(dssContext: TDSSContext; DSSClsType: Integer; DSSClsName: String);
destructor Destroy; override;
Expand Down Expand Up @@ -1494,6 +1495,8 @@ constructor TDSSClass.Create(dssContext: TDSSContext; DSSClsType: Integer; DSSCl
ElementNameList := THashListType.Create(100);
ElementNamesOutOfSynch := FALSE;

RequiresCircuit := false;

DefineProperties();
end;

Expand Down
40 changes: 17 additions & 23 deletions src/Executive/ExecHelper.pas
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ TExecHelper = class helper for TExecutive
procedure GetObjClassAndName(var ObjClass, ObjName: String);

function AddObject(ObjType: String; const Name: String): Integer; overload;
function AddObject(ObjCls: TDSSClass; const Name: String): Integer; overload;
function AddObject(Cls: TDSSClass; const Name: String): Integer; overload;
function EditObject(const ObjType, name: String): Integer;

procedure SetActiveCircuit(const cktname: String);
Expand Down Expand Up @@ -1853,7 +1853,7 @@ function TExecHelper.AddObject(ObjType: String; const Name: String): Integer;
Result := AddObject(DSS.ActiveDSSClass, Name);
end;

function TExecHelper.AddObject(ObjCls: TDSSClass; const Name: String): Integer;
function TExecHelper.AddObject(Cls: TDSSClass; const Name: String): Integer;
var
Obj: TDSSObject = NIL;
begin
Expand All @@ -1873,7 +1873,7 @@ function TExecHelper.AddObject(ObjCls: TDSSClass; const Name: String): Integer;

// intrinsic and user Defined models
// Make a new circuit element
DSS.ActiveDSSClass := ObjCls;
DSS.ActiveDSSClass := Cls;

// Name must be supplied
if Length(Name) = 0 then
Expand All @@ -1882,53 +1882,47 @@ function TExecHelper.AddObject(ObjCls: TDSSClass; const Name: String): Integer;
Exit;
end;

// now let's make a new object or set an existing one active, whatever the case
if DSS.ActiveDSSClass.DSSClassType = DSS_OBJECT then
if Cls.RequiresCircuit and (DSS.ActiveCircuit = NIL) then
begin
if (DSS.ActiveCircuit = NIL) and ((DSS.ActiveDSSClass = DSS.LineCodeClass) or (DSS.ActiveDSSClass = DSS.LineGeometryClass)) then
begin
DoSimpleMsg(DSS, _('You Must Create a circuit first: "new circuit.yourcktname"'), 279);
Exit;
end;
DoSimpleMsg(DSS, _('You Must Create a circuit first: "new circuit.yourcktname"'), 265);
Exit;
end;

// now let's make a new object or set an existing one active, whatever the case
if Cls.DSSClassType = DSS_OBJECT then
begin
// These can be added WITHout having an active circuit
// Duplicates not allowed in general DSS objects;
if not DSS.ActiveDSSClass.SetActive(Name) then
if not Cls.SetActive(Name) then
begin
Obj := DSS.ActiveDSSClass.NewObject(Name, TRUE, Result);
Obj := Cls.NewObject(Name, TRUE, Result);
DSS.DSSObjs.Add(Obj); // Stick in pointer list to keep track of it
end;
end
else
begin
// These are circuit elements
if DSS.ActiveCircuit = NIL then
begin
DoSimpleMsg(DSS, _('You Must Create a circuit first: "new circuit.yourcktname"'), 265);
Exit;
end;

// IF Object already exists. Treat as an Edit IF dulicates not allowed
if DSS.ActiveCircuit.DuplicatesAllowed then
begin
Obj := DSS.ActiveDSSClass.NewObject(Name, TRUE, Result); // Returns index into this class
Obj := Cls.NewObject(Name, TRUE, Result); // Returns index into this class
DSS.ActiveCircuit.AddCktElement(TDSSCktElement(Obj)); // Adds active object to active circuit
end
else
begin // Check to see if we can set it active first
if not DSS.ActiveDSSClass.SetActive(Name) then
if not Cls.SetActive(Name) then
begin
Obj := DSS.ActiveDSSClass.NewObject(Name, TRUE, Result); // Returns index into this class
Obj := Cls.NewObject(Name, TRUE, Result); // Returns index into this class
DSS.ActiveCircuit.AddCktElement(TDSSCktElement(Obj)); // Adds active object to active circuit
end
else
begin
DoSimpleMsg(DSS, 'Warning: Duplicate new element definition: "%s.%s". Element being redefined.', [DSS.ActiveDSSClass.Name, Name], 266);
DoSimpleMsg(DSS, 'Warning: Duplicate new element definition: "%s.%s". Element being redefined.', [Cls.Name, Name], 266);
Exit;
end;
end;
end;
DSS.ActiveDSSClass.Edit(DSS.Parser); // Process remaining instructions on the command line
Cls.Edit(DSS.Parser); // Process remaining instructions on the command line
end;

function TExecHelper.EditObject(const ObjType, Name: String): Integer;
Expand Down
1 change: 1 addition & 0 deletions src/General/LineCode.pas
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ constructor TLineCode.Create(dssContext: TDSSContext);
end;

inherited Create(dssContext, DSS_OBJECT, 'LineCode');
RequiresCircuit := true;
end;

destructor TLineCode.Destroy;
Expand Down
1 change: 1 addition & 0 deletions src/General/LineGeometry.pas
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ constructor TLineGeometry.Create(dssContext: TDSSContext);
end;

inherited Create(dssContext, DSS_OBJECT, 'LineGeometry');
RequiresCircuit := true;
end;

destructor TLineGeometry.Destroy;
Expand Down

0 comments on commit 790268c

Please sign in to comment.