How do you reset an `ST` instance in `StringTemplate4`? - stringtemplate

StringTemplate instances in version 3 had a .reset() method.
I am generating inside a for/each loop and want to reset the instance to its default state at the end of each loop.
I have searched the JavaDoc and can not find out how to reset an instance of ST to reuse it.
How do you reset an ST instance in StringTemplate4?

This is here because this was a hard thing to find!
The .reset() method was removed and there is no direct documentation that hints to how to accomplish this in version 4.
By digging into the source code I discovered that .getInstanceOf()
delivers a cached uninitialized copy of the template there is no need
to call .reset() on the instances anymore, just get a fresh cached
instance.
Relevant code from STGroup.java as of the time of this answer:
/** The primary means of getting an instance of a template from this
* group. Names must be absolute, fully-qualified names like {#code /a/b}.
*/
public ST getInstanceOf(String name) {
if ( name==null ) return null;
if ( verbose ) System.out.println(getName()+".getInstanceOf("+name+")");
if ( name.charAt(0)!='/' ) name = "/"+name;
CompiledST c = lookupTemplate(name);
if ( c!=null ) {
return createStringTemplate(c);
}
return null;
}
/** Look up a fully-qualified name. */
public CompiledST lookupTemplate(String name) {
if ( name.charAt(0)!='/' ) name = "/"+name;
if ( verbose ) System.out.println(getName()+".lookupTemplate("+name+")");
CompiledST code = rawGetTemplate(name);
if ( code==NOT_FOUND_ST ) {
if ( verbose ) System.out.println(name+" previously seen as not found");
return null;
}
// try to load from disk and look up again
if ( code==null ) code = load(name);
if ( code==null ) code = lookupImportedTemplate(name);
if ( code==null ) {
if ( verbose ) System.out.println(name+" recorded not found");
templates.put(name, NOT_FOUND_ST);
}
if ( verbose ) if ( code!=null ) System.out.println(getName()+".lookupTemplate("+name+") found");
return code;
}

Related

How to pass a param for a binding in PostgreSQL - COPY (... ) TO STDOUT (FORMAT binary)?

I have some simple test table in postgres like below:
--DROP TABLE test_point
CREATE TABLE test_point
(
serie_id INT NOT NULL,
version_ts INT NOT NULL,
PRIMARY KEY (serie_id, version_ts)
);
I try to load a data from it by using COPY TO STDOUT and binary buffers. This is sql definition I use in a test case:
COPY (
SELECT version_ts
FROM test_point
WHERE
serie_id = $1::int
) TO STDOUT (FORMAT binary);
It works ok, if I don't provide any param to bind to in SQL. If I use simple select it recognizes params also as well.
I was trying to provide explicit info about param type during stmt preparation also, but results were similar (it doesn't recognize param).
This is a message I receive during the test case:
0x000001740a288ab0 "ERROR: bind message supplies 1 parameters, but prepared statement \"test1\" requires 0\n"
How to properly provide a param for COPY() statement?
I don't want to cut/concatenate strings for timestamp params and similar types.
Below is a test case showing the issue.
TEST(TSStorage, CopyParamTest)
{
auto sql = R"(
COPY (
SELECT version_ts
FROM test_point
WHERE
serie_id = $1::int
) TO STDOUT (FORMAT binary);
)";
auto connPtr = PQconnectdb("postgresql://postgres:pswd#localhost/some_db");
auto result = PQprepare(connPtr, "test1", sql, 0, nullptr);
// Lambda to test result status
auto testRes = [&](ExecStatusType status)
{
if (PQresultStatus(result) != status)
{
PQclear(result);
auto errorMsg = PQerrorMessage(connPtr);
PQfinish(connPtr);
throw std::runtime_error(errorMsg);
}
};
testRes(PGRES_COMMAND_OK);
PQclear(result);
int seriesIdParam = htonl(5);
const char *paramValues[] = {(const char *)&seriesIdParam};
const int paramLengths[] = {sizeof(seriesIdParam)};
const int paramFormats[] = {1}; // 1 means binary
// Execute prepared statement
result = PQexecPrepared(connPtr,
"test1",
1, //nParams,
paramValues,
paramLengths,
paramFormats,
1); // Output format - binary
// Ensure it's in COPY_OUT state
//testRes(PGRES_COPY_OUT);
if (PQresultStatus(result) != PGRES_COPY_OUT)
{
auto errorMsg = PQerrorMessage(connPtr);
int set_breakpoint_here = 0; // !!! !!! !!!
}
PQclear(result);
PQfinish(connPtr);
}

Restart numeration in multiple tables with docx4j

I need to create a .docx file using docx4j with many tables based on a template.
Tables must have rows with automatic numeration.
After copying table from template numeration continues in consecutive tables, like this:
table 1
List item
List item
table 2
List item
List item
How can I restart numeration for every table to obtain this:
table 1
List item
List item
table 2
List item
List item
I found that there exists NumberingDefinitionPart.restart() method that could be helpful but how can I apply it on each table?
Could you give example with java code?
For each table after the first, you need to create/add a list level override to the numbering definitions part, then use that in your numPr (ie in your "list item").
The method you mentioned does this:
/**
* For the given list numId, restart the numbering on the specified
* level at value val. This is done by creating a new list (ie <w:num>)
* which uses the existing w:abstractNum.
* #param numId
* #param ilvl
* #param val
* #return
*/
public long restart(long numId, long ilvl, long val)
throws InvalidOperationException {
// Find the abstractNumId
// (Ensure maps are initialised)
if (em == null ) {
getEmulator();
}
ListNumberingDefinition existingLnd = instanceListDefinitions.get( Long.toString(numId) );
if (existingLnd==null) {
throw new InvalidOperationException("List " + numId + " does not exist");
}
BigInteger abstractNumIdVal = existingLnd.getNumNode().getAbstractNumId().getVal();
// Generate the new <w:num
long newNumId = instanceListDefinitions.size() + 1;
org.docx4j.wml.ObjectFactory factory = Context.getWmlObjectFactory();
Num newNum = factory.createNumberingNum();
newNum.setNumId( BigInteger.valueOf(newNumId) );
AbstractNumId abstractNumId = factory.createNumberingNumAbstractNumId();
abstractNumId.setVal(abstractNumIdVal);
newNum.setAbstractNumId(abstractNumId);
LvlOverride lvlOverride = factory.createNumberingNumLvlOverride();
lvlOverride.setIlvl(BigInteger.valueOf(ilvl));
newNum.getLvlOverride().add(lvlOverride);
StartOverride start = factory.createNumberingNumLvlOverrideStartOverride();
start.setVal(BigInteger.valueOf(val));
lvlOverride.setStartOverride(start);
// Add it to the jaxb object and our hashmap
((Numbering)getJaxbElement()).getNum().add(newNum);
ListNumberingDefinition listDef
= new ListNumberingDefinition(newNum, abstractListDefinitions);
instanceListDefinitions.put(listDef.getListNumberId(), listDef);
// Return the new numId
return newNumId;
}
https://github.com/plutext/docx4j/blob/master/src/samples/docx4j/org/docx4j/samples/NumberingRestart.java is an example of using it.
In your numPr element in your w:p "list item":
<w:pPr>
<w:numPr>
<w:ilvl w:val="0"/>
<w:numId w:val="1"/>
</w:numPr>
</w:pPr>
set level (ilvl) to the level you used in the method; set numid to the value the method returns.
As noted in the sample, after the first paragraph using newNumId, it doesn't matter whether subsequent paragraphs use that or the original numId.

dynamically change a part of the variable path

I know this question has been asked a bunch of times, but none of the answers (or at least what i took away from them) was a help to my particiular problem.
I want to dynamically change a part of the variable path, so i don't have to repeat the same code x-times with just two characters changing.
Here's what i got:
In the beginning of my script, i'm setting the reference to PlayerData scripts, attached to the GameManager object like this:
var P1 : P1_Data;
var P2 : P2_Data;
function Start(){
P1 = GameObject.Find("GameManager").GetComponent.<P1_Data>();
P2 = GameObject.Find("GameManager").GetComponent.<P2_Data>();
}
Later, i want to access these scripts using the currentPlayer variable to dynamically adjust the path:
var currentPlayer : String = "P1"; //this actually happens along with some other stuff in the SwitchPlayers function, i just put it here for better understanding
if (currentPlayer.PlayerEnergy >= value){
// do stuff
}
As i was afraid, i got an error saying, that PlayerEnergy was not a part of UnityEngine.String.
So how do I get unity to read "currentPlayer" as part of the variable path?
Maybe some parse function I haven't found?
Or am I going down an entirely wrong road here?
Cheers
PS: I also tried putting the P1 and P2 variables into an array and access them like this:
if (PlayerData[CurrentPlayerInt].PlayerEnergy >= value){
// do stuff
}
to no success.
First of all,
var currentPlayer : String = "P1"
here P1 is just string, not the previous P1/P2 which are referenced to two scripts. So, if you want, you can change
currentPlayer.PlayerEnergy >= value
to
P1.PlayerEnergy >= value
or,
P2.PlayerEnergy >= value
But if you just want one function for them, like
currentPlayer.PlayerEnergy >= value
Then you have to first set currentPlayer to P1/P2 which I assume you are trying to do. You must have some codes that can verify which player is selected. Then, maybe this can help -
var playerSelected: int = 0;
var currentPlayerEnergy: int = 0;
.....
//Use your codes to verify which player is selected and then,
if (playerSelected == 1) {
currentPlayerEnergy = P1.PlayerEnergy;
} else if (playerSelected == 2) {
currentPlayerEnergy = P2.PlayerEnergy;
}
//Now use your favorite function
if (currentPlayerEnergy >= value) {
//Do stuff
}
As there was no reply providing the answer I needed, I'll share the solution that did the trick for me, provided by a fellow student.
Instead of having the PlayerData scripts pre-written, I generate them using a public class function in a Playermanager script. This generates the Playerdata as attached scripts, saved into an array.
I can then access them through Playermanager.Playerlist[Playernumber].targetvariable.
Which is what I wanted to do, only with the Playerdata being attached to a script instead of a gameobject. And it works great!
Here's the full code of my Playermanager Script:
//initialise max players
public var maxplayers : int = 2;
// Initialise Playerlist
static var Players = new List.<PlayerData>();
function Start () {
for (var i : int = 0; i < maxplayers; i++){
var Player = new PlayerData();
Players.Add(Player);
Players[i].PlayerName = "Player " + i;
}
DontDestroyOnLoad (transform.gameObject);
}
public class PlayerData {
public var PlayerName : String;
public var PlayerEnergy : int = 15;
public var Fleet : List.<GameObject> = new List.<GameObject>();
}
As you see, you can put any type of variable in this class.
I hope this helps some of you who have the same problem.
cheers,
Tux

lua:How to use value from table 'A', in table 'B', which nested in table 'A'

In real project, TEST_TABLE would contain much of TEST_TABLE_NESTED, each with its own testVariable and bunch of testScript. test function from testScript would be used in C++ code, and TEST_TABLE_NESTED tables would be added automatically from C++ code too.
TEST_TABLE =
{
TEST_TABLE_NESTED =
{
testVariable = 5,
testScript =
{
test = function()
print(testVariable, "hello") --How to access 'testVariable'?
end
}
}
}
EDIT :
This is the actual scenario of using this script:
GameObjectScriptTables =
{
GameObject_1 = --Container of scripts corresponding to some gameObject
{
gameObjectOwner = actual_object_passed_from_c++, --This is an actual object passed from c++
GameObjectScript_1 = --This is a script with update(dt) method which will be called somwhere in c++ code
{
update = function(dt)
--here I want to use some data from gameObjectOwner like position or velocity
end
}
}
GameObject_2 =
{
gameObjectOwner = actual_object_passed_from_c++,
GameObjectScript_1 =
{
update = function(dt)
--here I want to use some data from gameObjectOwner like position or velocity
end
},
GameObjectScript_2 =
{
update = function(dt)
--here I want to use some data from gameObjectOwner like position or velocity
end
}
}
--And so on
}
Idea is that exists some testVariable object (passed from C++), which data is used all over TEST_TABLE_NESTED. For me, above example looks natural for this task, but it prints nil instead of 5. So how to acces a testVariable from testScript without printing a full path like TEST_TABLE.TEST_TABLE_NESTED.testVariable?
You're asking for something like a "parent" pointer, which tells table B about table A, but that doesn't exist. Internally, the only association they have is that one of A's values happens to be B, but any number of tables could contain B as a value. Which is B's parent?
If you want B to know about A, you'll need to tell it. You can add an extra parameter to update which receives the game owner object, or update can be a closure which contains the game owner as a bound variable, so on and so forth.
I made it work by providing a gameObjectOwner instance for each GameObjectScript_N. However I don't know is it expensive solution or not.

Dapper.Net and the DataReader

I have a very strange error with dapper:
there is already an open DataReader associated with this Command
which must be closed first
But I don't use DataReader! I just call select query on my server application and take first result:
//How I run query:
public static T SelectVersion(IDbTransaction transaction = null)
{
return DbHelper.DataBase.Connection.Query<T>("SELECT * FROM [VersionLog] WHERE [Version] = (SELECT MAX([Version]) FROM [VersionLog])", null, transaction, commandTimeout: DbHelper.CommandTimeout).FirstOrDefault();
}
//And how I call this method:
public Response Upload(CommitRequest message) //It is calling on server from client
{
//Prepearing data from CommitRequest
using (var tr = DbHelper.DataBase.Connection.BeginTransaction(IsolationLevel.Serializable))
{
int v = SelectQueries<VersionLog>.SelectVersion(tr) != null ? SelectQueries<VersionLog>.SelectVersion(tr).Version : 0; //Call my query here
int newVersion = v + 1; //update version
//Saving changes from CommitRequest to db
//Updated version saving to base too, maybe it is problem?
return new Response
{
Message = String.Empty,
ServerBaseVersion = versionLog.Version,
};
}
}
}
And most sadly that this exception appearing in random time, I think what problem in concurrent access to server from two clients.
Please help.
This some times happens if the model and database schema are not matching and an exception is being raised inside Dapper.
If you really want to get into this, best way is to include dapper source in your project and debug.